1.使用目的:正常开发是针对NDEF格式数据进行开发,但实际情况并非如此,以厦门公交卡为例,厦门公交卡保存的是非NDEF格式数据。其类型是IsoDep类型。

2.非标准的NDEF格式数据流程:当厦门公交卡放到NFC上时,手机会捕获该厦门公交卡标签信息,自动获得该tag能支持的技术支持,其中标签的数据将封装到Intent中,并启动相关的Activity处理该标签信息,判断该标签类型为IsoDep类型后,使用该IsoDep类对标签进行操作。

You can use the getTechList() method to determine the technologies supported by the tag and create the corresponding TagTechnology object with one of classes provided by android.nfc.tech

你可以使用getTechList()方法来确定该tag能支持的技术,创建由android.nfc.tech包中提供的能与之匹配的的TagTechnology对象类。

NFC针对非标准的NDEF格式数据使用步骤:

1.获取NFC权限/添加Intent过滤器

2.获取NFC适配器

3.捕获NFC Intent

4.处理该Intent(获取信息Tag)--> 判断标签类型为IsoDep类型,并执行相关操作

5.IsoDep类的核心函数: transceive(byte[]) 函数。通过该函数发送相关指令,得到返回值。-- 需要了解底层的指令

例如:

底层的指令:

通过NFC读取公交卡的余额和交易记录

读取分四个步骤:
1.select PSF (1PAY.SYS.DDF01)
选择支付系统文件,它的名字是1PAY.SYS.DDF01。

byte[] DFN_PSE = { (byte) '1', (byte) 'P',
(byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y',
(byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F',
(byte) '0', (byte) '1', };

2.选择公交卡应用的名字或者ID

长安通:
byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98,
(byte) 0x07, (byte) 0x01, };

3.读取余额 
发送命令读取电子钱包的余额:

final byte[] cmd = { (byte) 0x80, // CLA Class 
(byte) 0x5C, // INS Instruction 
(byte) 0x00, // P1 Parameter 1 
(byte) 0x02, // P2 Parameter 2 
(byte) 0x04, // Le 
};

获取到的余额数据是byte[] data, 前4字节合并成int,再除以100(两个小数点),得到的结果就是余额。

4.读取交易记录

一次性读取命令,在不知道有多少条记录的时候,用这个命令:

byte[] cmd = { (byte) 0x00, // CLA Class

(byte) 0xB2, // INS Instruction

(byte) 0x01, // P1 Parameter 1

(byte) 0xC5, // P2 Parameter 2

(byte) 0x00, // Le

};

返回所有的记录byte[] data,每23个字节代表一条记录

也可以一条一条的读取:

cmd = { (byte) 0x00, // CLA Class

(byte) 0xB2, // INS Instruction

(byte) index, // P1 Parameter 1

(byte) 0xC4, // P2 Parameter 2

(byte) 0x00, // Le

};

一条记录是23个字节byte[] data,对其解码如下

data[0]-data[1]:index

data[2]-data[4]:over,金额溢出?

data[5]-data[8]:交易金额

data[9]:如果等于0x06或者0x09,表示刷卡;否则是充值

data[10]-data[15]:刷卡机或充值机编号

data[16]-data[22]:日期String.format("%02X%02X.%02X.%02X %02X:%02X:%02X",data[16], data[17], data[18], data[19], data[20], data[21], data[22]);

实例解析:

1.获取NFC权限

  1. <uses-permission android:name="android.permission.NFC" />

添加Intent过滤器

  1. <activity
  2. android:name=".MainActivity"
  3. android:label="@string/app_name" >
  4. <intent-filter>
  5. <action android:name="android.intent.action.MAIN" />
  6. <category android:name="android.intent.category.LAUNCHER" />
  7. </intent-filter>
  8. <intent-filter>
  9. <action android:name="android.nfc.action.TECH_DISCOVERED" />
  10. </intent-filter>
  11. <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
  12. android:resource="@xml/nfc_tech_filter" />
  13. <intent-filter>
  14. <action android:name="android.nfc.action.TAG_DISCOVERED" />
  15. <category android:name="android.intent.category.DEFAULT" />
  16. </intent-filter>
  17. </activity>

nfc_tech_filter.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
  3.  
  4. <tech-list>
  5. <tech>android.nfc.tech.IsoDep</tech>
  6. </tech-list>
  7. <!-- 以下只是显示怎么添加多个nfc支持类 -->
  8. <tech-list>
  9. <tech>android.nfc.tech.NfcV</tech>
  10. </tech-list>
  11. <tech-list>
  12. <tech>android.nfc.tech.NfcF</tech>
  13. </tech-list>
  14.  
  15. </resources>

2.获取NFC适配器

  1. private NfcAdapter nfcAdapter; // NFC适配器
  2. ...
  3. ......
  4. // 获取默认的NFC控制器,并进行判断
  5. nfcAdapter = NfcAdapter.getDefaultAdapter(this);
  6. if (nfcAdapter == null) {
  7. Log.d("h_bl", "设备不支持NFC!");
  8. return;
  9. }
  10. if (!nfcAdapter.isEnabled()) {
  11. Toast.makeText(getApplicationContext(), "请在系统设置中先启用NFC功能!", Toast.LENGTH_SHORT).show();
  12. Log.d("h_bl", "请在系统设置中先启用NFC功能!");
  13. return;
  14. }

3.捕获NFC Intent

  1. Intent intent = this.getIntent(); // 捕获NFC Intent
  2. String nfcAction = intent.getAction(); // 解析该Intent的Action

4.处理该Intent(获取信息Tag) -- 厦门公交卡为IsoDep类,详见IsoDep类的使用。

  1. if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(nfcAction)) {
  2. Log.d("h_bl", "ACTION_TECH_DISCOVERED");
  3. Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 获取Tag标签,既可以处理相关信息
  4. for (String tech : tag.getTechList()) {
  5. Log.d("h_bl", "tech=" + tech);
  6. }
  7. IsoDep isoDep = IsoDep.get(tag);
  8. String str = "";
  9. try {
  10. isoDep.connect(); // 连接
  11. if (isoDep.isConnected()) {
  12. Log.d("h_bl", "isoDep.isConnected"); // 判断是否连接上
  13. // 1.select PSF (1PAY.SYS.DDF01)
  14. // 选择支付系统文件,它的名字是1PAY.SYS.DDF01。
  15. byte[] DFN_PSE = { (byte) '1', (byte) 'P', (byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y', (byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F', (byte) '0', (byte) '1', };
  16. isoDep.transceive(getSelectCommand(DFN_PSE));
  17. // 2.选择公交卡应用的名称
  18. byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98, (byte) 0x07, (byte) 0x01, };
  19. isoDep.transceive(getSelectCommand(DFN_SRV));
  20. // 3.读取余额
  21. byte[] ReadMoney = { (byte) 0x80, // CLA Class
  22. (byte) 0x5C, // INS Instruction
  23. (byte) 0x00, // P1 Parameter 1
  24. (byte) 0x02, // P2 Parameter 2
  25. (byte) 0x04, // Le
  26. };
  27. byte[] Money = isoDep.transceive(ReadMoney);
  28. if (Money != null && Money.length > 4) {
  29. int cash = byteToInt(Money, 4);
  30. float ba = cash / 100.0f;
  31. show_msg.setText("余额:" + ba);
  32. }
  33. // 4.读取所有交易记录
  34. byte[] ReadRecord = { (byte) 0x00, // CLA Class
  35. (byte) 0xB2, // INS Instruction
  36. (byte) 0x01, // P1 Parameter 1
  37. (byte) 0xC5, // P2 Parameter 2
  38. (byte) 0x00, // Le
  39. };
  40. byte[] Records = isoDep.transceive(ReadRecord);
  41. // 处理Record
  42. Log.d("h_bl", "总消费记录" + Records);
  43. ArrayList<byte[]> ret = parseRecords(Records);
  44. List<String> retList = parseRecordsToStrings(ret);
  45. show_msg.append("\n" + "消费记录如下:");
  46. for (String string : retList) {
  47. Log.d("h_bl", "消费记录" + string);
  48. show_msg.append("\n" + string);
  49. }
  50.  
  51. }
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. } finally {
  55. if (isoDep != null) {
  56. try {
  57. isoDep.close();
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. }
  63. }

完整代码:

  1. package com.example.nfcdemo;
  2.  
  3. import java.io.IOException;
  4. import java.nio.ByteBuffer;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7.  
  8. import android.support.v7.app.ActionBarActivity;
  9. import android.app.PendingIntent;
  10. import android.content.Intent;
  11. import android.content.IntentFilter;
  12. import android.content.IntentFilter.MalformedMimeTypeException;
  13. import android.nfc.NfcAdapter;
  14. import android.nfc.Tag;
  15. import android.nfc.tech.IsoDep;
  16. import android.nfc.tech.NfcF;
  17. import android.nfc.tech.NfcV;
  18. import android.os.Bundle;
  19. import android.util.Log;
  20. import android.widget.TextView;
  21. import android.widget.Toast;
  22. import com.example.nfcdemo2.R;
  23.  
  24. public class MainActivity extends ActionBarActivity {
  25.  
  26. private NfcAdapter nfcAdapter; // NFC适配器
  27. // NFC前台调度系统
  28. private PendingIntent pendingIntent = null;
  29. private TextView show_msg; // 显示数据
  30. protected final static byte TRANS_CSU = 6; // 如果等于0x06或者0x09,表示刷卡;否则是充值
  31. protected final static byte TRANS_CSU_CPX = 9; // 如果等于0x06或者0x09,表示刷卡;否则是充值
  32. public String[][] tenchlists;
  33. public IntentFilter[] filters;
  34.  
  35. @SuppressWarnings("unchecked")
  36. @Override
  37. protected void onCreate(Bundle savedInstanceState) {
  38. super.onCreate(savedInstanceState);
  39. setContentView(R.layout.activity_main);
  40. show_msg = (TextView) findViewById(R.id.show_msg);
  41. tenchlists = new String[][] { { IsoDep.class.getName() }, { NfcV.class.getName() }, { NfcF.class.getName() }, };
  42.  
  43. try {
  44. filters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") };
  45. } catch (MalformedMimeTypeException e1) {
  46. e1.printStackTrace();
  47. }
  48. // 初始化PendingIntent,当有NFC设备连接上的时候,就交给当前Activity处理
  49. pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
  50. // 获取默认的NFC控制器,并进行判断
  51. nfcAdapter = NfcAdapter.getDefaultAdapter(this);
  52. if (nfcAdapter == null) {
  53. Log.d("h_bl", "设备不支持NFC!");
  54. finish();
  55. return;
  56. }
  57. if (!nfcAdapter.isEnabled()) {
  58. Toast.makeText(getApplicationContext(), "请在系统设置中先启用NFC功能!", Toast.LENGTH_SHORT).show();
  59. Log.d("h_bl", "请在系统设置中先启用NFC功能!");
  60. return;
  61. }
  62. Intent intent = this.getIntent(); // 捕获NFC Intent
  63. praseIntent(intent);
  64. }
  65.  
  66. private void praseIntent(Intent intent) {
  67.  
  68. String nfcAction = intent.getAction(); // 解析该Intent的Action
  69. if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(nfcAction)) {
  70. Log.d("h_bl", "ACTION_TECH_DISCOVERED");
  71. Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 获取Tag标签,既可以处理相关信息
  72. for (String tech : tag.getTechList()) {
  73. Log.d("h_bl", "tech=" + tech);
  74. }
  75. IsoDep isoDep = IsoDep.get(tag);
  76. String str = "";
  77. try {
  78. isoDep.connect(); // 连接
  79. if (isoDep.isConnected()) {
  80. Log.d("h_bl", "isoDep.isConnected"); // 判断是否连接上
  81. // 1.select PSF (1PAY.SYS.DDF01)
  82. // 选择支付系统文件,它的名字是1PAY.SYS.DDF01。
  83. byte[] DFN_PSE = { (byte) '1', (byte) 'P', (byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y', (byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F', (byte) '0', (byte) '1', };
  84. isoDep.transceive(getSelectCommand(DFN_PSE));
  85. // 2.选择公交卡应用的名称
  86. byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98, (byte) 0x07, (byte) 0x01, };
  87. isoDep.transceive(getSelectCommand(DFN_SRV));
  88. // 3.读取余额
  89. byte[] ReadMoney = { (byte) 0x80, // CLA Class
  90. (byte) 0x5C, // INS Instruction
  91. (byte) 0x00, // P1 Parameter 1
  92. (byte) 0x02, // P2 Parameter 2
  93. (byte) 0x04, // Le
  94. };
  95. byte[] Money = isoDep.transceive(ReadMoney);
  96. if (Money != null && Money.length > 4) {
  97. int cash = byteToInt(Money, 4);
  98. float ba = cash / 100.0f;
  99. show_msg.setText("余额:" + ba);
  100. }
  101. // 4.读取所有交易记录
  102. byte[] ReadRecord = { (byte) 0x00, // CLA Class
  103. (byte) 0xB2, // INS Instruction
  104. (byte) 0x01, // P1 Parameter 1
  105. (byte) 0xC5, // P2 Parameter 2
  106. (byte) 0x00, // Le
  107. };
  108. byte[] Records = isoDep.transceive(ReadRecord);
  109. // 处理Record
  110. Log.d("h_bl", "总消费记录" + Records);
  111. ArrayList<byte[]> ret = parseRecords(Records);
  112. List<String> retList = parseRecordsToStrings(ret);
  113. show_msg.append("\n" + "消费记录如下:");
  114. for (String string : retList) {
  115. Log.d("h_bl", "消费记录" + string);
  116. show_msg.append("\n" + string);
  117. }
  118.  
  119. }
  120. } catch (IOException e) {
  121. e.printStackTrace();
  122. } finally {
  123. if (isoDep != null) {
  124. try {
  125. isoDep.close();
  126. } catch (IOException e) {
  127. e.printStackTrace();
  128. }
  129. }
  130. }
  131. }
  132. }
  133.  
  134. @Override
  135. protected void onPause() {
  136. if (nfcAdapter != null)
  137. nfcAdapter.disableForegroundDispatch(this);
  138. super.onPause();
  139. }
  140.  
  141. @Override
  142. protected void onResume() {
  143. super.onResume();
  144. nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, tenchlists);
  145. }
  146.  
  147. @Override
  148. protected void onNewIntent(Intent intent) {
  149. super.onNewIntent(intent);
  150. // 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来
  151. // 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法
  152. if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
  153. Log.d("h_bl", "onNewIntent");
  154. praseIntent(intent);
  155. }
  156.  
  157. }
  158.  
  159. public static byte byteToHex(byte arg) {
  160. byte hex = 0;
  161. if (arg >= 48 && arg <= 57) {
  162. hex = (byte) (arg - 48);
  163. } else if (arg >= 65 && arg <= 70) {
  164. hex = (byte) (arg - 55);
  165. } else if (arg >= 97 && arg <= 102) {
  166. hex = (byte) (arg - 87);
  167. }
  168. return hex;
  169. }
  170.  
  171. private byte[] getSelectCommand(byte[] aid) {
  172. final ByteBuffer cmd_pse = ByteBuffer.allocate(aid.length + 6);
  173. cmd_pse.put((byte) 0x00) // CLA Class
  174. .put((byte) 0xA4) // INS Instruction
  175. .put((byte) 0x04) // P1 Parameter 1
  176. .put((byte) 0x00) // P2 Parameter 2
  177. .put((byte) aid.length) // Lc
  178. .put(aid).put((byte) 0x00); // Le
  179. return cmd_pse.array();
  180. }
  181.  
  182. /**
  183. * 整条Records解析成ArrayList<byte[]>
  184. *
  185. * @param Records
  186. * @return
  187. */
  188. private ArrayList<byte[]> parseRecords(byte[] Records) {
  189. int max = Records.length / 23;
  190. Log.d("h_bl", "消费记录有" + max + "条");
  191. ArrayList<byte[]> ret = new ArrayList<byte[]>();
  192. for (int i = 0; i < max; i++) {
  193. byte[] aRecord = new byte[23];
  194. for (int j = 23 * i, k = 0; j < 23 * (i + 1); j++, k++) {
  195. aRecord[k] = Records[j];
  196. }
  197. ret.add(aRecord);
  198. }
  199. for (byte[] bs : ret) {
  200. Log.d("h_bl", "消费记录有byte[]" + bs); // 有数据。解析正确。
  201. }
  202. return ret;
  203. }
  204.  
  205. /**
  206. * ArrayList<byte[]>记录分析List<String> 一条记录是23个字节byte[] data,对其解码如下
  207. * data[0]-data[1]:index data[2]-data[4]:over,金额溢出??? data[5]-data[8]:交易金额
  208. * ??代码应该是(5,4) data[9]:如果等于0x06或者0x09,表示刷卡;否则是充值
  209. * data[10]-data[15]:刷卡机或充值机编号
  210. * data[16]-data[22]:日期String.format("%02X%02X.%02X.%02X %02X:%02X:%02X"
  211. * ,data[16], data[17], data[18], data[19], data[20], data[21], data[22]);
  212. *
  213. * @param logs
  214. * @return
  215. */
  216. private List<String> parseRecordsToStrings(ArrayList<byte[]>... Records) {
  217. List<String> recordsList = new ArrayList<String>();
  218. for (ArrayList<byte[]> record : Records) {
  219. if (record == null)
  220. continue;
  221. for (byte[] v : record) {
  222. StringBuilder r = new StringBuilder();
  223. int cash = Util.toInt(v, 5, 4);
  224. char t = (v[9] == TRANS_CSU || v[9] == TRANS_CSU_CPX) ? '-' : '+';
  225. r.append(String.format("%02X%02X.%02X.%02X %02X:%02X ", v[16], v[17], v[18], v[19], v[20], v[21], v[22]));
  226. r.append(" " + t).append(Util.toAmountString(cash / 100.0f));
  227. String aLog = r.toString();
  228. recordsList.add(aLog);
  229. }
  230. }
  231. return recordsList;
  232. }
  233.  
  234. // byteArray转化为int
  235. private int byteToInt(byte[] b, int n) {
  236. int ret = 0;
  237. for (int i = 0; i < n; i++) {
  238. ret = ret << 8;
  239. ret |= b[i] & 0x00FF;
  240. }
  241. if (ret > 100000 || ret < -100000)
  242. ret -= 0x80000000;
  243. return ret;
  244. }
  245.  
  246. }

Util:

  1. public final class Util {
  2. private final static char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  3.  
  4. private Util() {
  5. }
  6.  
  7. public static byte[] toBytes(int a) {
  8. return new byte[] { (byte) (0x000000ff & (a >>> 24)), (byte) (0x000000ff & (a >>> 16)), (byte) (0x000000ff & (a >>> 8)), (byte) (0x000000ff & (a)) };
  9. }
  10.  
  11. public static int toInt(byte[] b, int s, int n) {
  12. int ret = 0;
  13.  
  14. final int e = s + n;
  15. for (int i = s; i < e; ++i) {
  16. ret <<= 8;
  17. ret |= b[i] & 0xFF;
  18. }
  19. return ret;
  20. }
  21.  
  22. public static int toIntR(byte[] b, int s, int n) {
  23. int ret = 0;
  24.  
  25. for (int i = s; (i >= 0 && n > 0); --i, --n) {
  26. ret <<= 8;
  27. ret |= b[i] & 0xFF;
  28. }
  29. return ret;
  30. }
  31.  
  32. public static int toInt(byte... b) {
  33. int ret = 0;
  34. for (final byte a : b) {
  35. ret <<= 8;
  36. ret |= a & 0xFF;
  37. }
  38. return ret;
  39. }
  40.  
  41. public static String toHexString(byte[] d, int s, int n) {
  42. final char[] ret = new char[n * 2];
  43. final int e = s + n;
  44.  
  45. int x = 0;
  46. for (int i = s; i < e; ++i) {
  47. final byte v = d[i];
  48. ret[x++] = HEX[0x0F & (v >> 4)];
  49. ret[x++] = HEX[0x0F & v];
  50. }
  51. return new String(ret);
  52. }
  53.  
  54. public static String toHexStringR(byte[] d, int s, int n) {
  55. final char[] ret = new char[n * 2];
  56.  
  57. int x = 0;
  58. for (int i = s + n - 1; i >= s; --i) {
  59. final byte v = d[i];
  60. ret[x++] = HEX[0x0F & (v >> 4)];
  61. ret[x++] = HEX[0x0F & v];
  62. }
  63. return new String(ret);
  64. }
  65.  
  66. public static int parseInt(String txt, int radix, int def) {
  67. int ret;
  68. try {
  69. ret = Integer.valueOf(txt, radix);
  70. } catch (Exception e) {
  71. ret = def;
  72. }
  73.  
  74. return ret;
  75. }
  76.  
  77. public static String toAmountString(float value) {
  78. return String.format("%.2f", value);
  79. }
  80. }

3.非标准的NDEF格式数据解析--IsoDep的更多相关文章

  1. Android之JSON格式数据解析

    查看原文:http://blog.csdn.net/hantangsongming/article/details/42234293 JSON:JavaScript 对象表示法(JavaScript ...

  2. (5)微信二次开发 之 XML格式数据解析

    1.首先理解一下html html的全名是:HyperText Transfer markup language 超级文本标记语言,html本质上是一门标记(符合)语言,在html里,这些标记是事先定 ...

  3. html中通过js获取接口JSON格式数据解析以及跨域问题

    前言:本人自学前端开发,一直想研究下js获取接口数据在html的实现,顺利地找到了获取数据的方法,但是有部分接口在调用中出现无法展示数据.经查,发现时跨域的问题,花费了一通时间,随笔记录下过程,以方便 ...

  4. 让SNIPER-MXNet从标准的COCO格式数据集中直接使用file_name作为图片路径

    告别项目中“依index生成路径”的方法,直接使用我们在生成.json标签时就已经写入的图片路径(这里我写入的是绝对路径 full path)来获取图片. 需要做的,用以下代码替换SNIPER/lib ...

  5. ini格式数据生成与解析具体解释

    ini格式数据生成与解析具体解释 1.ini格式数据长啥样? watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/ ...

  6. android nfc中Ndef格式的读写

    1. 在onCreate()中获取NfcAdapter对象: NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); 2.在onNewI ...

  7. Wireshark分析非标准端口号流量

    Wireshark分析非标准端口号流量 2.2.2  分析非标准端口号流量Wireshark分析非标准端口号流量 应用程序运行使用非标准端口号总是网络分析专家最关注的.关注该应用程序是否有意涉及使用非 ...

  8. 13、NFC技术:读写非NDEF格式的数据

    MifareUltralight数据格式 将NFC标签的存储区域分为16个页,每一个页可以存储4个字节,一个可存储64个字节(512位).页码从0开始(0至15).前4页(0至3)存储了NFC标签相关 ...

  9. Python解析非标准JSON(Key值非字符串)

    采集数据的时候经常碰到一些JSON数据的Key值不是字符串,这些数据在JavaScript的上下文中是可以解析的,但在Python中,没有该部分数据的上下文,无法采用json.loads(JSON)的 ...

随机推荐

  1. ZOJ 3606 Lazy Salesgirl ( 线段树 + 思路 )

    卖切糕的小女孩 http://www.cnblogs.com/wuyiqi/archive/2012/04/28/2474672.html #include <cstdio> #inclu ...

  2. hexo从零开始到搭建完整 转

    http://visugar.com/2017/05/04/20170504SetUpHexoBlog/ https://liuchi.coding.me/   look me 交流群 有相关问题的可 ...

  3. 【Python】- pytharm 中import时无法识别自己写的程序

    右键点击自己的工作空间,找下面的Mark Directory as(将目录标记为) 选择Source Root,就可以解决上面的问题了,如图

  4. Linux命令 -文件操作类

    声明:本文所涉及到的Linux命令均为最常见的用法,未列举之参数,自行查阅man 1.ls    查看文件与目录 -a 打印全部的文件,包括隐藏文件 -l 列表打印,数据项包括文件属性,大小和权限等 ...

  5. BZOJ3244 [Noi2013]树的计数 【数学期望 + 树遍历】

    题目链接 BZOJ3244 题解 不会做orz 我们要挖掘出\(bfs\)序和\(dfs\)序的性质 ①容易知道\(bfs\)序一定是一层一层的,如果我们能确定在\(bfs\)序中各层的断点,就能确定 ...

  6. JavaScript—获取本地时间以12小时制显示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. JavaScript中继承机制的模仿实现

    首先,我们用一个经典例子来简单阐述一下ECMAScript中的继承机制. 在几何学上,实质上几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形. ...

  8. 百度之星初赛(A)——T6

    度度熊的01世界 Problem Description 度度熊是一个喜欢计算机的孩子,在计算机的世界中,所有事物实际上都只由0和1组成. 现在给你一个n*m的图像,你需要分辨他究竟是0,还是1,或者 ...

  9. 结构型设计模式之桥接模式(Bridge)

    结构 意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系.例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换. ...

  10. new Date在ios下的兼容bug

    今天发现在ios下new Date("2019-03-06").getTime()返回NaN 原因是ios下不支持“-”必须用"/" 记录备忘 var d = ...