安卓学习日记——NFC

    xiaoxiao2022-07-05  177

    NFC介绍 近场通信又称近距离无线通信,是一种短距离的高频无线通信技术,允许电子设备之间进行非接触式点对点数据传输,交换数据。这个技术由免接触式射频识别(RFID)演变而来,由飞利浦和索尼共同研制开发,其基础是RFID及互连技术。近场通信是一种短距高频的无线电技术,在13.56MHz频率运行于20厘米距离内。其传输速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三种。

    近场通信技术主要特征如下:

    (1)用于近距离(10cm以内)安全通信的无线通信技术。

    (2)射频频率:13.56MHz。

    (3)射频兼容:ISO 14443,ISO 15693,Felica标准。

    (4)数据传输速度:106kbit/s,212 kbit/s,424kbit/s。 代码区 AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.nfc"> <uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".PackageListActivity"></activity> <activity android:name=".MainActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

    MainActivity

    package com.example.nfc; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.content.Intent; import android.nfc.FormatException; 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.Parcel; import android.os.Parcelable; import android.provider.Settings; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Toast; import java.io.IOException; import java.nio.charset.Charset; public class MainActivity extends AppCompatActivity { private static final int REQUEST_CODE =0x1 ; private NfcAdapter nfcAdapter; private String packageName; private PendingIntent pi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nfcAdapter=NfcAdapter.getDefaultAdapter(this); // if (nfcAdapter==null){ Toast.makeText(MainActivity.this,"设备不支持NFC功能",Toast.LENGTH_SHORT).show(); finish(); } //判断设备是否打开NFC功能 if (!nfcAdapter.isEnabled()){ Intent intent=new Intent(Settings.ACTION_NFC_SETTINGS); startActivity(intent); } pi=PendingIntent.getActivity(this,0,new Intent(this,getClass()),0); } public void selectStartAppClick(View v){ Intent intent=new Intent(this,PackageListActivity.class); startActivityForResult(intent,REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==REQUEST_CODE && resultCode==RESULT_OK){ packageName=data.getStringExtra("packageName"); System.out.println(packageName); } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (isRead){ read(intent); }else { write(intent); } } /** * 读取NFC标签的数据进行解析 * @param intent */ private void read(Intent intent){ Tag tag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (tag==null){ return; } if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())){ Parcelable[] data=intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (data!=null){ NdefMessage[] ndefMessages=new NdefMessage[data.length]; for (int i=0;i<ndefMessages.length;i++){ ndefMessages[i]= (NdefMessage) data[i]; NdefRecord[] records=ndefMessages[i].getRecords(); String package_name=new String(records[0].getPayload()); String flag=new String(records[1].getPayload()); //打开蓝牙 if ("1".equals(flag)){ BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter(); bluetoothAdapter.enable(); } //根据包名运行程序 Intent startApp=this.getPackageManager().getLaunchIntentForPackage(package_name); startActivity(startApp); } } } } /** * 把数据写入NFC标签 * @param intent */ public void write(Intent intent){ Tag tag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (tag==null){ return; } //写入数据 //启动指定的应用程序 // NdefRecord[] recodes=new NdefRecord[]{NdefRecord.createApplicationRecord(packageName)}; //打开URI // NdefRecord[] recodes=new NdefRecord[]{NdefRecord.createUri("www.baidu.com")}; NdefRecord[] records=new NdefRecord[2]; records[0]=new NdefRecord(NdefRecord.TNF_WELL_KNOWN,NdefRecord.RTD_TEXT,new byte[]{0},packageName.getBytes(Charset.forName("gb2312"))); records[1]=new NdefRecord(NdefRecord.TNF_WELL_KNOWN,NdefRecord.RTD_TEXT,new byte[]{0},"1".getBytes(Charset.forName("gb2312"))); // NdefMessage ndefMessage=new NdefMessage(recodes); NdefMessage ndefMessage=new NdefMessage(records); Ndef ndef=Ndef.get(tag); if (ndef!=null){ try { ndef.connect(); if (ndef.isWritable()){ int size=ndefMessage.toByteArray().length; if (ndef.getMaxSize()>size){ ndef.writeNdefMessage(ndefMessage); } } } catch (IOException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); } }else { try { NdefFormatable ndefFormatable=NdefFormatable.get(tag); if (ndefFormatable!=null) { ndefFormatable.connect(); ndefFormatable.format(ndefMessage);//格式化并写入数据 } } catch (IOException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); } } Toast.makeText(MainActivity.this,"写入成功",Toast.LENGTH_SHORT).show(); } @Override protected void onResume() { super.onResume(); if (nfcAdapter!=null){ //设置当前程序为优先处理NFC的程序 nfcAdapter.enableForegroundDispatch(this,pi,null,null); } } @Override protected void onPause() { super.onPause(); if (nfcAdapter!=null){ //取消设置当前程序为优先处理NFC的程序 nfcAdapter.disableForegroundDispatch(this); } } private boolean isRead=true;//true为读取,false为写入 //写入状态 public void writeClick(View v){ isRead=false; Toast.makeText(MainActivity.this, "当前为写入状态", Toast.LENGTH_SHORT).show(); } public void readClick(View v){ isRead=true; Toast.makeText(MainActivity.this, "当前为读取状态", Toast.LENGTH_SHORT).show(); } }

    PackageListActivity

    package com.example.nfc; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import org.w3c.dom.Text; import java.util.ArrayList; import java.util.List; public class PackageListActivity extends Activity implements AdapterView.OnItemClickListener { private ListView packageList; private List<AppInfo> list=new ArrayList<>(); private MyAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_package_list); packageList=findViewById(R.id.listView); packageList.setOnItemClickListener(this); PackageManager pm=getPackageManager(); List<PackageInfo> packageInfos=pm.getInstalledPackages(PackageManager.GET_ACTIVITIES); for (PackageInfo p:packageInfos){ AppInfo appInfo=new AppInfo(); appInfo.appname=p.applicationInfo.loadLabel(pm).toString(); appInfo.packagename=p.packageName; appInfo.versionName=p.versionName; appInfo.versionCode=p.versionCode; appInfo.appicon=p.applicationInfo.loadIcon(getPackageManager()); list.add(appInfo); } myAdapter=new MyAdapter(); packageList.setAdapter(myAdapter); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { AppInfo appInfo=list.get(position); Intent data=new Intent(); data.putExtra("packageName",appInfo.packagename); setResult(RESULT_OK,data); finish(); } private class MyAdapter extends BaseAdapter{ @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh=null; if (convertView==null){ convertView=getLayoutInflater().inflate(R.layout.list_item_layout,null); vh=new ViewHolder(); vh.imageView_logo=convertView.findViewById(R.id.imageView2_logo); vh.textView_name=convertView.findViewById(R.id.textView_name); convertView.setTag(vh); }else { vh= (ViewHolder) convertView.getTag(); AppInfo info=list.get(position); vh.imageView_logo.setImageDrawable(info.appicon); vh.textView_name.setText(info.appname); } return convertView; } class ViewHolder{ ImageView imageView_logo; TextView textView_name; } } }

    AppInfo

    package com.example.nfc; import android.graphics.drawable.Drawable; public class AppInfo { int versionCode=0;//名称 String appname="";//包 String packagename=""; String versionName="";//图标 Drawable appicon=null; }

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/button_select_app" android:layout_width="170dp" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginStart="0dp" android:onClick="selectStartAppClick" android:layout_marginTop="0dp" android:text="选择要启动的程序" /> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/button_select_app" android:layout_alignParentStart="true" android:layout_marginStart="0dp" android:scaleType="centerCrop" app:srcCompat="@mipmap/nfc" /> <Button android:id="@+id/button_write" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:onClick="writeClick" android:layout_toEndOf="@+id/button_select_app" android:text="写入标签" /> <Button android:id="@+id/button3" android:layout_width="150dp" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_marginTop="0dp" android:onClick="readClick" android:layout_marginEnd="3dp" android:layout_toEndOf="@+id/button_write" android:text="Button" /> </RelativeLayout>

    activity_package_list.xml

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".PackageListActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_centerVertical="true" android:layout_centerHorizontal="true"> </ListView> </RelativeLayout>

    list_item_layout.xml

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <ImageView android:id="@+id/imageView2_logo" android:layout_width="19dp" android:layout_height="wrap_content" android:layout_weight="1" app:srcCompat="@mipmap/ic_launcher" /> <TextView android:id="@+id/textView_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" android:text="loading" /> </LinearLayout>

    由于测试需要准备好NFC标签之类的东西,某宝上就有,需要的可以考虑一下,还是挺便宜的。便宜的1块钱不到。

    最新回复(0)