You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

335 lines
11 KiB
Java

1 year ago
package com.rehome.dywoa;
import static com.rehome.dywoa.utils.NfcUtil.stringsToBytes;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.rehome.dywoa.utils.NfcUtil;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.Objects;
/**
* Description:
* onNewIntentNFC
* launchModesingleTopsingelTaskActivity
* onNewIntentintentTag
* NFCNFC
*/
public class BaseNfcActivity extends AppCompatActivity {
private NfcAdapter nfcAdapter;
private String readResult = "";
private PendingIntent pendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;
private boolean isFirst = true;
private IntentFilter ndef;
Tag mTag;
Tag getTagHandle() {
return mTag;
}
/**
* ,NFC
*
* @return
*/
private Boolean ifNFCUse() {
if (nfcAdapter == null) {
Toast.makeText(this, "设备不支持NFC", Toast.LENGTH_SHORT).show();
return false;
}
if (!nfcAdapter.isEnabled()) {
Toast.makeText(this, "请在系统设置中先启用NFC功能", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
/**
*
*/
public void initNFC() {
//NFC适配器所有的关于NFC的操作从该适配器进行
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (!ifNFCUse()) {
return;
}
//将被调用的Intent用于重复被Intent触发后将要执行的跳转
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
} else {
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_UPDATE_CURRENT);
}
//设定要过滤的标签动作这里只接收ACTION_NDEF_DISCOVERED类型
ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
ndef.addCategory("*/*");
mFilters = new IntentFilter[]{ndef};// 过滤器
mTechLists = new String[][]{new String[]{NfcA.class.getName()},
new String[]{NfcF.class.getName()},
new String[]{NfcB.class.getName()},
new String[]{NfcV.class.getName()},
new String[]{MifareClassic.class.getName()},
new String[]{MifareUltralight.class.getName()},
new String[]{IsoDep.class.getName()}};// 允许扫描的标签类型
if (isFirst) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent()
.getAction())) {
ndef = new IntentFilter();
if (readFromTag(getIntent())) {
Toast.makeText(this, readResult, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "标签数据为空", Toast.LENGTH_SHORT).show();
}
}
isFirst = false;
}
}
private String ByteArrayToHexString(byte[] inarray) { //converts byte arrays to string
int i, j, in;
String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
String out = "";
for (j = 0; j < inarray.length; ++j) {
in = (int) inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
}
return out;
}
@Override
protected void onPause() {
super.onPause();
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(this);
}
}
/*
* onResumeNFC
*/
@Override
protected void onResume() {
super.onResume();
//设置强制竖屏
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// 前台分发系统,这里的作用在于第二次检测NFC标签时该应用有最高的捕获优先权.
if (nfcAdapter != null && pendingIntent != null && mFilters != null && mTechLists != null) {
nfcAdapter.enableForegroundDispatch(this, pendingIntent, mFilters,
mTechLists);
}
}
/*
* onNewIntent,
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||
NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
String id = ByteArrayToHexString(Objects.requireNonNull(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID)));
if (readFromTag(intent)) {
// Toast.makeText(this, readResult, Toast.LENGTH_SHORT).show();
handleNfc(readResult, null);
} else {
Toast.makeText(this, "ID:" + id + " 标签数据为空", Toast.LENGTH_SHORT).show();
}
}
}
private JSONObject ndef2Html(Ndef ndef, Parcelable[] messages) {
return buildNdefJSON(ndef, messages);
}
JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
JSONObject json = NfcUtil.ndefToJSON(ndef);
if (messages != null) {
try {
if (messages.length == 1) {
NdefMessage message = (NdefMessage) messages[0];
json.put("ndefMessage", NfcUtil.messageToJSON(message));
json.put("type", "NDEF");
}
} catch (JSONException e) {
Log.e("BaseNfcActivity", "Failed to convert ndefMessage into json", e);
}
}
return json;
}
public void getNdefMessage(Intent intent) {
synchronized (this) {
try {
String action = intent.getAction();
if (action != null) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (detectedTag != null) {
mTag = detectedTag;
}
}
Ndef ndef = Ndef.get(getTagHandle());
Parcelable[] message = new NdefMessage[] {ndef.getNdefMessage()};
handleNfc(String.valueOf(ndef2Html(ndef, message)), null);
} catch (Exception exception) {
Log.d("BaseNfcActivity", exception.toString());
handleNfc(null, exception.toString());
}
}
}
/**
* NFC
*/
private boolean readFromTag(Intent intent) {
String action = intent.getAction();
if (action == null) {
return false;
}
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag == null) {
return false;
}
mTag = tag;
Ndef ndef;
switch (action) {
case NfcAdapter.ACTION_NDEF_DISCOVERED -> {
ndef = Ndef.get(tag);
Parcelable[] message = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
readResult = String.valueOf(ndef2Html(ndef, message));
}
case NfcAdapter.ACTION_TECH_DISCOVERED -> {
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
ndef = Ndef.get(tag);
readResult = String.valueOf(ndef2Html(ndef, new NdefMessage[]{ndef.getCachedNdefMessage()}));
} else {
Log.i("app ACTION_TECH_DISCOVERED 2", String.valueOf(tag));
}
}
}
return readResult != null;
}
//处理NFC
public void handleNfc(String result, String errorMessage) {
//showToast(result);
//Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
public void showLog(String logText) {
if (BuildConfig.LOG_ERROR) {
if(TextUtils.isEmpty(logText)){
Log.i("app", "logText is null");
}else{
Log.i("app", logText);
}
}
}
/**
* toast
*
* @param text
*/
public void showToast(String text) {
if (text != null && !text.trim().equals("")) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
}
/**
*
*/
public void writeNFCTag(String command) throws FormatException, JSONException {
if (mTag == null) {
return;
}
NdefMessage ndefMessage = new NdefMessage(stringsToBytes(command));
//转换成字节获得大小
int size = ndefMessage.toByteArray().length;
try {
//2.判断NFC标签的数据类型通过Ndef.get方法
Ndef ndef = Ndef.get(getTagHandle());
//判断是否为NDEF标签
if (ndef != null) {
ndef.connect();
//判断是否支持可写
if (!ndef.isWritable()) {
return;
}
//判断标签的容量是否够用
if (ndef.getMaxSize() < size) {
return;
}
//3.写入数据
ndef.writeNdefMessage(ndefMessage);
Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
ndef.close();
ndef.connect();
} else { //当我们买回来的NFC标签是没有格式化的或者没有分区的执行此步
//Ndef格式类
NdefFormatable format = NdefFormatable.get(mTag);
//判断是否获得了NdefFormatable对象有一些标签是只读的或者不允许格式化的
if (format != null) {
//连接
format.connect();
//格式化并将信息写入标签
format.format(ndefMessage);
Toast.makeText(this, "写入成功",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
}
}
}