編輯:關於android開發
先說說NFC開發總結,看了幾天NFC開發資料,搜集了不少關於這方面的資料、demo、以及他人的總結。以下有部分是摘錄總結的。因為要是現在總結也是那些,最後附送代碼。關於demo我也有,有需要在評論去發郵箱給我。
第一:屏幕沒有鎖住 。 第二:NFC功能已經在設置中打開
當系統檢測到一個NFC標簽的時候,他會自動去尋找最合適的activity去處理這個intent.
NFC發出的這個Intent將會有三種action:
ACTION_NDEF_DISCOVERED:當系統檢測到tag中含有NDEF格式的數據時,且系統中有activity聲明可以接受包含NDEF數據的Intent的時候,系統會優先發出這個action的intent。
ACTION_TECH_DISCOVERED:當沒有任何一個activity聲明自己可以響應ACTION_NDEF_DISCOVERED時,系統會嘗試發出TECH的intent.即便你的tag中所包含的數據是NDEF的,但是如果這個數據的MIMEtype或URI不能和任何一個activity所聲明的想吻合,系統也一樣會嘗試發出tech格式的intent,而不是NDEF.
ACTION_TAG_DISCOVERED:當系統發現前兩個intent在系統中無人會接受的時候,就只好發這個默認的TAG類型的
首先是權限:
然後是sdk級別限制:我個人建議API11開始比較合適:
如果是API8,在代碼中,nfc功能設置的代碼會出錯,要拋出
例如:
NfcAdapter mAdapter = NfcAdapter.getDefaultAdapter(this);
mAdapter.isEnabled()
接著是特殊功能限制:
這個生命可以讓你的應用在googleplay上被聲明使用者必須擁有nfc功能。
在activity的intent過濾xml聲明中,你可以同時聲明過濾這三種action.但是由之前所說,你應該知道系統在發送intent的時候是有優先級的,所以你最好清楚自己最想處理哪個。
這個最簡單,也是最後一個被嘗試接受intent的選項。
其中最重要的應該算是data的mimeType類型了,這個定義的越准確,intent指向你這個activity的成功率就越高,否則系統可能不會發出你想要的NDEF intent了。下面在講如何使用NDEF寫入NFC標簽的時候會多舉幾個類型的例子。
你首先需要在你的
一個nfc_tech_filter.xml中可以定義多個
android.nfc.tech.IsoDep android.nfc.tech.NfcA android.nfc.tech.NfcB android.nfc.tech.NfcF android.nfc.tech.NfcV android.nfc.tech.Ndef android.nfc.tech.NdefFormatable android.nfc.tech.MifareClassic android.nfc.tech.MifareUltralight
在androidManifest文件中聲明xml過濾的舉例如下:
package org.reno.Beam; import java.io.ByteArrayOutputStream; import java.nio.charset.Charset; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import org.nfc.read.ParsedNdefRecord; import android.app.Activity; import android.app.AlertDialog; import android.app.PendingIntent; import android.content.DialogInterface; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.MifareClassic; import android.nfc.tech.MifareUltralight; import android.os.Bundle; import android.os.Parcelable; import android.provider.Settings; import android.widget.TextView; public class MainActivity extends Activity { private static final DateFormat TIME_FORMAT = SimpleDateFormat .getDateTimeInstance(); private NfcAdapter mAdapter; private PendingIntent mPendingIntent; private NdefMessage mNdefPushMessage; private TextView promt; private AlertDialog mDialog; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); promt = (TextView) findViewById(R.id.promt); resolveIntent(getIntent()); mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null) .create(); // 獲取默認的NFC控制器 mAdapter = NfcAdapter.getDefaultAdapter(this); //攔截系統級的NFC掃描,例如掃描藍牙 mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord("", Locale.ENGLISH, true) }); } @Override protected void onResume() { super.onResume(); if (mAdapter == null) { if (!mAdapter.isEnabled()) { showWirelessSettingsDialog(); } showMessage(R.string.error, R.string.no_nfc); promt.setText("設備不支持NFC!"); return; } if (!mAdapter.isEnabled()) { promt.setText("請在系統設置中先啟用NFC功能!"); return; } if (mAdapter != null) { //隱式啟動 mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); mAdapter.enableForegroundNdefPush(this, mNdefPushMessage); } } @Override protected void onPause() { super.onPause(); if (mAdapter != null) { //隱式啟動 mAdapter.disableForegroundDispatch(this); mAdapter.disableForegroundNdefPush(this); } } //16進制字符串轉換為String private String hexString = "0123456789ABCDEF"; public String decode(String bytes) { if (bytes.length() != 30) { return null; } ByteArrayOutputStream baos = new ByteArrayOutputStream( bytes.length() / 2); // 將每2位16進制整數組裝成一個字節 for (int i = 0; i < bytes.length(); i += 2) baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString .indexOf(bytes.charAt(i + 1)))); return new String(baos.toByteArray()); } // 字符序列轉換為16進制字符串 private static String bytesToHexString(byte[] src, boolean isPrefix) { StringBuilder stringBuilder = new StringBuilder(); if (isPrefix == true) { stringBuilder.append("0x"); } if (src == null || src.length <= 0) { return null; } char[] buffer = new char[2]; for (int i = 0; i < src.length; i++) { buffer[0] = Character.toUpperCase(Character.forDigit( (src[i] >>> 4) & 0x0F, 16)); buffer[1] = Character.toUpperCase(Character.forDigit(src[i] & 0x0F, 16)); System.out.println(buffer); stringBuilder.append(buffer); } return stringBuilder.toString(); } private void showMessage(int title, int message) { mDialog.setTitle(title); mDialog.setMessage(getText(message)); mDialog.show(); } private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes( Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset .forName("UTF-16"); byte[] textBytes = text.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); } private void showWirelessSettingsDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.nfc_disabled); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialogInterface, int i) { Intent intent = new Intent( Settings.ACTION_WIRELESS_SETTINGS); startActivity(intent); } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialogInterface, int i) { finish(); } }); builder.create().show(); return; } //初步判斷是什麼類型NFC卡 private void resolveIntent(Intent intent) { String action = intent.getAction(); if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { Parcelable[] rawMsgs = intent .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); NdefMessage[] msgs; if (rawMsgs != null) { msgs = new NdefMessage[rawMsgs.length]; for (int i = 0; i < rawMsgs.length; i++) { msgs[i] = (NdefMessage) rawMsgs[i]; } } else { // Unknown tag type byte[] empty = new byte[0]; byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID); Parcelable tag = intent .getParcelableExtra(NfcAdapter.EXTRA_TAG); byte[] payload = dumpTagData(tag).getBytes(); NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload); NdefMessage msg = new NdefMessage(new NdefRecord[] { record }); msgs = new NdefMessage[] { msg }; } // Setup the views buildTagViews(msgs); } } //一般公家卡,掃描的信息 private String dumpTagData(Parcelable p) { StringBuilder sb = new StringBuilder(); Tag tag = (Tag) p; byte[] id = tag.getId(); sb.append("Tag ID (hex): ").append(getHex(id)).append("\n"); sb.append("Tag ID (dec): ").append(getDec(id)).append("\n"); sb.append("ID (reversed): ").append(getReversed(id)).append("\n"); String prefix = "android.nfc.tech."; sb.append("Technologies: "); for (String tech : tag.getTechList()) { sb.append(tech.substring(prefix.length())); sb.append(", "); } sb.delete(sb.length() - 2, sb.length()); for (String tech : tag.getTechList()) { if (tech.equals(MifareClassic.class.getName())) { sb.append('\n'); MifareClassic mifareTag = MifareClassic.get(tag); String type = "Unknown"; switch (mifareTag.getType()) { case MifareClassic.TYPE_CLASSIC: type = "Classic"; break; case MifareClassic.TYPE_PLUS: type = "Plus"; break; case MifareClassic.TYPE_PRO: type = "Pro"; break; } sb.append("Mifare Classic type: "); sb.append(type); sb.append('\n'); sb.append("Mifare size: "); sb.append(mifareTag.getSize() + " bytes"); sb.append('\n'); sb.append("Mifare sectors: "); sb.append(mifareTag.getSectorCount()); sb.append('\n'); sb.append("Mifare blocks: "); sb.append(mifareTag.getBlockCount()); } if (tech.equals(MifareUltralight.class.getName())) { sb.append('\n'); MifareUltralight mifareUlTag = MifareUltralight.get(tag); String type = "Unknown"; switch (mifareUlTag.getType()) { case MifareUltralight.TYPE_ULTRALIGHT: type = "Ultralight"; break; case MifareUltralight.TYPE_ULTRALIGHT_C: type = "Ultralight C"; break; } sb.append("Mifare Ultralight type: "); sb.append(type); } } return sb.toString(); } private String getHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = bytes.length - 1; i >= 0; --i) { int b = bytes[i] & 0xff; if (b < 0x10) sb.append('0'); sb.append(Integer.toHexString(b)); if (i > 0) { sb.append(" "); } } return sb.toString(); } private long getDec(byte[] bytes) { long result = 0; long factor = 1; for (int i = 0; i < bytes.length; ++i) { long value = bytes[i] & 0xffl; result += value * factor; factor *= 256l; } return result; } private long getReversed(byte[] bytes) { long result = 0; long factor = 1; for (int i = bytes.length - 1; i >= 0; --i) { long value = bytes[i] & 0xffl; result += value * factor; factor *= 256l; } return result; } //顯示NFC掃描的數據 private void buildTagViews(NdefMessage[] msgs) { if (msgs == null || msgs.length == 0) { return; } // Parse the first message in the list // Build views for all of the sub records Date now = new Date(); Listrecords = NdefMessageParser.parse(msgs[0]); final int size = records.size(); for (int i = 0; i < size; i++) { TextView timeView = new TextView(this); timeView.setText(TIME_FORMAT.format(now)); ParsedNdefRecord record = records.get(i); promt.append(record.getViewText()); } } //獲取系統隱式啟動的 @Override public void onNewIntent(Intent intent) { setIntent(intent); resolveIntent(intent); } }
Android WindowManager實現懸浮窗效果 (一)——與當前Activity綁定,windowmanager懸浮窗 最近有學生做畢業設計,想使用懸浮窗這種
Android合並兩個APP的具體做法(掌握) 有時候因公司需求,要求合並兩個APP 使用裡面的功能。 平台:Studio 小白鼠:二維碼掃描 和自己項目
Android-繪制愛心,android-繪制自學android的圖形繪制,簡單的會用了Canvas和Paint,了解了他們的使用方法,便做了幾個愛心。這裡我記錄下我的幾
【騰訊Bugly干貨分享】微信熱補丁Tinker的實踐演進之路,buglytinker本文來自於騰訊bugly開發者社區,非經作者同意,請勿轉載,原文地址:http://