在项目中使用到nfc是,聊一聊NFC的试用范围
通过项目中遇到的各种坑,认识到使用nfc传输只能传输较小的内容
比如只能传输小于100k的内容
当nfc传输大于200k时,会出现文件过大异常
然后查询资料找到一般通过nfc传输文件都是通过Android Beam实现
在传输文件中NFC的功能是进行蓝牙或者wifi连接,然后使用蓝牙或者wifi进行传输文件
对于nfc传输,一般看的的都是传输一段字符串,进行校验
nfc传输速度较慢,一般为10k/s左右
项目中遇到只有nfc而无蓝牙的情况
做出了一个传输文件的nfcDemo
实现是将文件转为Byte[] 使用字节流传输文件
然后在接收端将流转为需要的文件的过程
代码写的很随意,请见谅!
项目代码
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends Activity {
private static final String TAG = "stickynotes";
private boolean mResumed = false;
private boolean mWriteMode = false;
NfcAdapter mNfcAdapter;
private static final int REQUESTCODE_PICK = 0x2;
// private static final int REQUESTCODE_CUTTING = 0x3;
PendingIntent mNfcPendingIntent;
IntentFilter[] mWriteTagFilters;
IntentFilter[] mNdefExchangeFilters;
private Button mNote;
private String urlpath;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
findViewById(R.id.write_tag).setOnClickListener(mTagWriter);
mNote = (Button) findViewById(R.id.note);
iv = (ImageView) findViewById(R.id.iv);
mNote.setOnClickListener(new onclick());
// Handle all of our received NFC intents in this activity.
mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// Intent filters for reading a note from a tag or exchanging over p2p.
IntentFilter ndefDetected = new IntentFilter(
NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndefDetected.addDataType("text/plain");
} catch (MalformedMimeTypeException e) {
}
mNdefExchangeFilters = new IntentFilter[] { ndefDetected };
// Intent filters for writing to a tag
IntentFilter tagDetected = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED);
mWriteTagFilters = new IntentFilter[] { tagDetected };
}
@Override
protected void onResume() {
super.onResume();
mResumed = true;
// Sticky notes received from Android
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
NdefMessage[] messages = getNdefMessages(getIntent());
byte[] payload = messages[0].getRecords()[0].getPayload();
setNoteBody(payload);
setIntent(new Intent()); // Consume this intent.
}
enableNdefExchangeMode();
}
@Override
protected void onPause() {
super.onPause();
mResumed = false;
if (mNfcAdapter != null) {
mNfcAdapter.disableForegroundNdefPush(this);
}
}
@Override
protected void onNewIntent(Intent intent) {
// NDEF exchange mode
if (!mWriteMode
&& NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage[] msgs = getNdefMessages(intent);
setNoteBody(msgs[0].getRecords()[0].getPayload());
}
// Tag writing mode
if (mWriteMode
&& NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
writeTag(getNoteAsNdef(), detectedTag);
}
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
ndef = Ndef.get(tag);
Log.e("fzq", "-----------size " + ndef.getMaxSize());
}
/**
* 选择图片
* @Description: TODO
* @param
* @return void
* @throws
* @author fzq
* @date 2017-12-23
*/
public void selePic() {
//
Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
"image/*");
startActivityForResult(pickIntent, REQUESTCODE_PICK);
if (mNfcAdapter == null) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
return;
}
mNfcAdapter
.enableForegroundNdefPush(MainActivity.this, getNoteAsNdef());
}
/**
* 文件转流
* @Description: TODO
* @param @return
* @return NdefMessage
* @throws
* @author fzq
* @date 2017-12-23
*/
private NdefMessage getNoteAsNdef() {
Bitmap bmp = null;
if (postBitmap != null) {
bmp = postBitmap;
} else {
Resources r = getResources();
InputStream is = r.openRawResource(R.drawable.ic_launcher);
BitmapDrawable bmpDraw = new BitmapDrawable(is);
bmp = bmpDraw.getBitmap();
}
// bmp = BitMapUtils.getZoomImage(bmp, 100 * 1024);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] textBytes = baos.toByteArray();
// byte[] textBytes = mNote.getText().toString().getBytes();
Log.e("fzq", "------------textBytessize " + textBytes.length);
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
"text/plain".getBytes(), new byte[] {}, textBytes);
return new NdefMessage(new NdefRecord[] { textRecord });
}
/**
* 得到的数据流显示
* @Description: TODO
* @param @param body
* @return void
* @throws
* @author fzq
* @date 2017-12-23
*/
private void setNoteBody(byte[] payload) {
Log.e("fzq", "---------------payloadsize " + payload.length);
Bitmap bitmap = BitmapFactory.decodeByteArray(payload, 0,
payload.length);
iv.setImageBitmap(bitmap);
//下列为保存到相册中
// 创建Media File
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
try {
ContentResolver cr = MainActivity.this.getContentResolver();
JImageUtils.insertImage(cr, bitmap, "qraved" + timeStamp,
"a photo from app", "我是filename没啥用");
} catch (Exception e) {
e.printStackTrace();
}
// 对某些不更新相册的应用程序强制刷新
Intent intent2 = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(new File("/sdcard/image.jpg"));// 固定写法
intent2.setData(uri);
MainActivity.this.sendBroadcast(intent2);
}
private class onclick implements OnClickListener {
@Override
public void onClick(View v) {
selePic();
}
}
private View.OnClickListener mTagWriter = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// Write to a tag for as long as the dialog is shown.
disableNdefExchangeMode();
enableTagWriteMode();
new AlertDialog.Builder(MainActivity.this)
.setTitle("Touch tag to write")
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
disableTagWriteMode();
enableNdefExchangeMode();
}
}).create().show();
}
};
private Bitmap postBitmap;
private Bitmap camorabitmap;
private Ndef ndef;
NdefMessage[] getNdefMessages(Intent intent) {
// Parse the intent
NdefMessage[] msgs = null;
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
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[] {};
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN,
empty, empty, empty);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
} else {
Log.d(TAG, "Unknown intent.");
finish();
}
return msgs;
}
private void enableNdefExchangeMode() {
if (mNfcAdapter == null) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
return;
}
mNfcAdapter
.enableForegroundNdefPush(MainActivity.this, getNoteAsNdef());
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
mNdefExchangeFilters, null);
}
private void disableNdefExchangeMode() {
mNfcAdapter.disableForegroundNdefPush(this);
mNfcAdapter.disableForegroundDispatch(this);
}
private void enableTagWriteMode() {
mWriteMode = true;
IntentFilter tagDetected = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED);
mWriteTagFilters = new IntentFilter[] { tagDetected };
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
mWriteTagFilters, null);
}
private void disableTagWriteMode() {
mWriteMode = false;
mNfcAdapter.disableForegroundDispatch(this);
}
boolean writeTag(NdefMessage message, Tag tag) {
int size = message.toByteArray().length;
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
toast("Tag is read-only.");
return false;
}
if (ndef.getMaxSize() < size) {
toast("Tag capacity is " + ndef.getMaxSize()
+ " bytes, message is " + size + " bytes.");
return false;
}
ndef.writeNdefMessage(message);
toast("Wrote message to pre-formatted tag.");
return true;
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
toast("Formatted tag and wrote message");
return true;
} catch (IOException e) {
toast("Failed to format tag.");
return false;
}
} else {
toast("Tag doesn't support NDEF.");
return false;
}
}
} catch (Exception e) {
toast("Failed to write tag");
}
return false;
}
private void toast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUESTCODE_PICK:
try {
setPicToView(data);
} catch (NullPointerException e) {
e.printStackTrace();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
private void setPicToView(Intent picdata) {
Uri uri = picdata.getData();
ContentResolver cr = this.getContentResolver();
try {
camorabitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
// 显示bitmap的最大效果
iv.setImageBitmap(camorabitmap);
postBitmap = camorabitmap;
getNoteAsNdef();
} catch (FileNotFoundException e) {
Log.e("Exception", e.getMessage(), e);
}
}
}