浅聊NFC

在项目中使用到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);
		}

	}

}


猜你喜欢

转载自blog.csdn.net/fengzhiqi1993/article/details/78893824
NFC