安卓学习日记——NFC

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块钱不到。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值