1. let Context = plus.android.importClass("android.content.Context");
    2. let NfcManager = plus.android.importClass("android.nfc.NfcManager");
    3. let NfcAdapter = plus.android.importClass("android.nfc.NfcAdapter");
    4. let Settings= plus.android.importClass("android.provider.Settings");
    5. let Intent = plus.android.importClass("android.content.Intent");
    6. let Parcelable = plus.android.importClass("android.os.Parcelable");
    7. let PendingIntent = plus.android.importClass('android.app.PendingIntent');
    8. let IntentFilter = plus.android.importClass('android.content.IntentFilter');
    9. let NdefRecord = plus.android.importClass("android.nfc.NdefRecord");
    10. let NdefMessage = plus.android.importClass("android.nfc.NdefMessage");
    11. let Tag = plus.android.importClass("android.nfc.Tag");
    12. let MifareClassic = plus.android.importClass("android.nfc.tech.MifareClassic");
    13. let invoke = plus.android.invoke;
    14. const Nfc={
    15. //所需要的数据
    16. data:{
    17. sector:1,//0号扇区
    18. keyVal:'737166323031',//扇区密码
    19. status:'read',//当前操作方式:是读卡 还是 写卡
    20. WriteData:'',//当status为write时生效。需要写入的数字。长度不能超过32位。只能为数字
    21. block:1,//当status为write时生效。需要写入0号扇区的几号块
    22. keyType:'A',//验证方式
    23. nfcAdapter:null,
    24. ICUID:'',//卡片ID
    25. main:null,
    26. intent:null,
    27. IntervalId:null,
    28. callback:null,//回调事件
    29. techListsArray:[
    30. ["android.nfc.tech.IsoDep"],
    31. ["android.nfc.tech.NfcA"],
    32. ["android.nfc.tech.NfcB"],
    33. ["android.nfc.tech.NfcF"],
    34. ["android.nfc.tech.NfcV"],
    35. ["android.nfc.tech.Ndef"],
    36. ["android.nfc.tech.NdefFormatable"],
    37. ["android.nfc.tech.MifareClassic"],
    38. ["android.nfc.tech.MifareUltralight"]
    39. ]
    40. },
    41. //初始化
    42. Into:function (){
    43. this.data.main=plus.android.runtimeMainActivity();
    44. var nfchManager = this.data.main.getSystemService(Context.NFC_SERVICE);
    45. var nfcAdapter = nfchManager.getDefaultAdapter();
    46. if(!nfcAdapter.isEnabled()){
    47. this.data.intent= new Intent(Settings.ACTION_NFC_SETTINGS);
    48. this.data.main.startActivity(this.data.intent);
    49. }
    50. var intent = new Intent(this.data.main, this.data.main.getClass());
    51. intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    52. var pendingIntent = PendingIntent.getActivity(this.data.main, 0, intent, 0);
    53. var ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
    54. ndef.addDataType("*/*");
    55. var intentFiltersArray = [ndef];
    56. nfcAdapter.enableForegroundDispatch(this.data.main, pendingIntent, intentFiltersArray, this.data.techListsArray);
    57. this.data.nfcAdapter=nfcAdapter;
    58. },
    59. //取消操作
    60. nfcclose:function(){
    61. if(this.data.nfcAdapter)
    62. this.data.nfcAdapter.disableForegroundDispatch(this.data.main);
    63. this.data.nfcAdapter=null;
    64. clearInterval(this.data.IntervalId);
    65. },
    66. //轮询获取当前NFC设备触发的事件
    67. handle_nfc_data:function(){
    68. console.log('等卡靠近。。。')
    69. var intent = this.data.main.getIntent();
    70. if(intent.getAction() == "android.nfc.action.TECH_DISCOVERED"){
    71. clearInterval(this.data.IntervalId);
    72. intent.setAction(null);
    73. if(this.data.status==='read')
    74. {
    75. console.log('开始读取信息')
    76. this._readData(intent);
    77. }
    78. else{
    79. console.log('开始写入数据')
    80. this._WriteData(intent);
    81. }
    82. }
    83. },
    84. //读取设备
    85. _readData:function(intent){
    86. uni.showLoading({
    87. title:"正在读取.请勿移开"
    88. });
    89. var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    90. var techList = tag.getTechList();
    91. var bisMfc=false;
    92. for(var i=0;i<techList.length;i++){
    93. if(techList[i].indexOf('MifareClassic')>=0){
    94. bisMfc=true;
    95. break;
    96. }
    97. }
    98. if(!bisMfc){
    99. uni.hideLoading();
    100. uni.showModal({
    101. content: "卡片类型错误",
    102. showCancel: false
    103. });
    104. return;
    105. }
    106. var mfc=MifareClassic.get(tag);
    107. if(!mfc){
    108. uni.hideLoading();
    109. uni.showModal({
    110. content: "卡片获取错误",
    111. showCancel: false
    112. });
    113. return;
    114. }
    115. mfc.setTimeout(3000);
    116. if(!mfc.isConnected()){
    117. try{
    118. invoke(mfc,'connect');
    119. }catch(e){
    120. uni.hideLoading();
    121. uni.showModal({
    122. content: "卡片连接错误",
    123. showCancel: false
    124. });
    125. return;
    126. }
    127. }
    128. try{
    129. this.data.ICUID=this.ByteArrayToHexString(tag.getId());
    130. var cmdBytes=this.HexStringToByteArray(this.data.keyVal);
    131. console.log(cmdBytes)
    132. var auth=false;
    133. if(this.data.keyType=="A"){
    134. auth=invoke(mfc,"authenticateSectorWithKeyA",parseInt(this.data.sector),cmdBytes);
    135. }else{
    136. auth=invoke(mfc,"authenticateSectorWithKeyB",parseInt(this.data.sector),cmdBytes);
    137. }
    138. console.log(auth)
    139. if(!auth){
    140. uni.hideLoading();
    141. uni.showModal({
    142. content: "请勿拿开",
    143. showCancel: false
    144. });
    145. return;
    146. }
    147. var bIndex = mfc.sectorToBlock(this.data.sector);
    148. var arr=[]
    149. for (var i = 0; i < 4; i++) {
    150. var data = mfc.readBlock(bIndex+i);
    151. console.log('当前'+i+"号块:读取的内容:"+this.ByteArrayToHexString(data))
    152. arr.push(this.ByteArrayToHexString(data))
    153. }
    154. mfc.close();
    155. uni.hideLoading();
    156. // uni.showModal({
    157. // content: "扇区读取成功",
    158. // showCancel: false
    159. // });
    160. //this.nfcclose();
    161. this.data.callback(arr)
    162. }catch(e){
    163. console.error(e);
    164. }finally{
    165. mfc.close();
    166. }
    167. },
    168. //写入数据
    169. _WriteData:function(intent){
    170. uni.hideLoading();
    171. uni.showLoading({
    172. title: '正在写入中.请勿移开'
    173. });
    174. var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    175. var techList = tag.getTechList();
    176. var bisMfc=false;
    177. for(var i=0;i<techList.length;i++){
    178. if(techList[i].indexOf('MifareClassic')>=0){
    179. bisMfc=true;
    180. break;
    181. }
    182. }
    183. if(!bisMfc){
    184. uni.hideLoading();
    185. uni.showModal({
    186. content: "卡片类型错误",
    187. showCancel: false
    188. });
    189. return;
    190. }
    191. var mfc=MifareClassic.get(tag);
    192. if(!mfc){
    193. uni.hideLoading();
    194. uni.showModal({
    195. content: "卡片获取错误",
    196. showCancel: false
    197. });
    198. return;
    199. }
    200. mfc.setTimeout(3000);
    201. if(!mfc.isConnected()){
    202. try{
    203. invoke(mfc,'connect');
    204. }catch(e){
    205. uni.hideLoading();
    206. uni.showModal({
    207. content: "卡片连接错误",
    208. showCancel: false
    209. });
    210. return;
    211. }
    212. }
    213. try{
    214. this.data.ICUID=this.ByteArrayToHexString(tag.getId());
    215. console.log(this.data.keyVal)
    216. var cmdBytes=this.HexStringToByteArray(this.data.keyVal);
    217. var auth=false;
    218. if(this.data.keyType=="A"){
    219. auth=invoke(mfc,"authenticateSectorWithKeyA",parseInt(this.data.sector),cmdBytes);
    220. }else{
    221. auth=invoke(mfc,"authenticateSectorWithKeyB",parseInt(this.data.sector),cmdBytes);
    222. }
    223. if(!auth){
    224. uni.hideLoading();
    225. uni.showModal({
    226. content: "请靠近一点",
    227. showCancel: false
    228. });
    229. return;
    230. }
    231. //开始写入指定块
    232. //mfc.writeBlock(this.data.block,this.HexStringToByteArray("11111111100000000000000000000000"));
    233. mfc.writeBlock(this.data.block,this.HexStringToByteArray(this.data.WriteData));
    234. //验证是否写入成功
    235. var data = mfc.readBlock(this.data.block);
    236. console.log(this.ByteArrayToHexString(data))
    237. console.log(this.data.WriteData)
    238. if(this.ByteArrayToHexString(data)===this.data.WriteData)
    239. {
    240. uni.hideLoading();
    241. mfc.close();
    242. uni.showModal({
    243. content: "写入完成",
    244. showCancel: false
    245. });
    246. this.data.callback({status:1,msg:'写入成功'})
    247. }else{
    248. console.log('写入失败')
    249. this.data.callback({status:0,msg:'写入失败'})
    250. }
    251. }catch(e){
    252. console.error(e);
    253. }finally{
    254. mfc.close();
    255. }
    256. },
    257. ByteArrayToHexString:function(inarray) {
    258. var i, j, inn;
    259. var hex = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
    260. var out = '';
    261. for(j = 0; j<inarray.length; ++j) {
    262. inn = inarray[j] & 0xff;
    263. i = (inn >>> 4) & 0x0f;
    264. out += hex[i];
    265. i = inn & 0x0f;
    266. out += hex[i];
    267. }
    268. return out;
    269. },
    270. HexStringToByteArray:function(instr) {
    271. var hexA = new Array();
    272. var pos = 0;
    273. var len = instr.length/2;
    274. for(var i=0; i<len; i++)
    275. {
    276. var s = instr.substr(pos, 2);
    277. var v = parseInt(s, 16);
    278. if(v>=128)
    279. v=v-256;
    280. hexA.push(v);
    281. pos += 2;
    282. }
    283. return hexA;
    284. },
    285. //对外开放的读取事件
    286. readData:function(){
    287. //输入请靠近设备
    288. uni.showLoading({
    289. title: '将卡靠近设备'
    290. });
    291. this.data.status="read"
    292. var that=this
    293. this.data.IntervalId = setInterval(function(){
    294. that.handle_nfc_data();
    295. },1000);
    296. },
    297. //对外开放的写入事件
    298. //传一个需要写入的数据
    299. writeData:function(value){
    300. //输入请靠近设备
    301. this.data.status="write"
    302. uni.showLoading({
    303. title: '请靠近设备'
    304. });
    305. if(value.length>32)
    306. {
    307. uni.showModal({
    308. content: "写入数据长度不能超过32位",
    309. showCancel: false
    310. });
    311. }
    312. for(var i=value.length;i<32;i++)
    313. {
    314. value+='0';
    315. }
    316. console.log(value);
    317. console.log(value.length)
    318. this.data.WriteData=value
    319. var that=this
    320. this.data.IntervalId = setInterval(function(){
    321. that.handle_nfc_data();
    322. },1000);
    323. }
    324. }
    325. export default Nfc