android nfc

NFC一次贴片终生读卡实现(普通应用版)

2019-03-15  本文已影响0人  军如令

之前写了一篇关于系统应用实现一次贴片多次读卡的文章,实际运用过程中发现了一些小问题,某些设备(android 8.0可以,android7.0不可以)在线程中反射调用系统api时有时会不成功,导致之后设备读得了卡,但是我的应用收不到,不走onNewIntent,尝试4.4以上的新方法enableReaderMode()也不返回NfcAdapter.ReaderCallback的onTagDiscovered回调。

莫得办法,又不能删库跑路,只能另寻他路,在摆弄着我的设备时,忽然发现了一个有趣的现象,当我熄屏再亮屏的时候,我的app居然又收到了标签信息。

实现思路:通过控制屏幕的亮灭来实现一次贴卡多次读卡

网上很多说用PowerManager和PowerManager.WakeLock来实现亮灭,根本就不行,还需要设备管理员权限才可以。

具体如下:

1.添加权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />

2.添加Receiver:

< android:name=".newfunction.nfc.receiver.ScreenOffAdminReceiver"

    android:label="@string/app_name"

    android:permission="android.permission.BIND_DEVICE_ADMIN">

        android:name="android.app.device_admin"

        android:resource="@xml/device_admin" />

        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />

</receiver>

3.Receiver的实现:

public class ScreenOffAdminReceiver extends DeviceAdminReceiver {

}

4.需要的xml包下device_admin.xml:

<?xml version="1.0" encoding="utf-8"?>

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">

<uses-policies>

<!-- 强行锁定 在里仅这个是需要的-->

<force-lock />

</uses-policies>

</device-admin>

5.activity中初始化参数

private DevicePolicyManager policyManager;

private ComponentName adminReceiver;

private PowerManager mPowerManager;

private PowerManager.WakeLock mWakeLock;

private void initParams() {

adminReceiver =new ComponentName(this, ScreenOffAdminReceiver.class);

    mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);

    policyManager = (DevicePolicyManager)this.getSystemService(Context.DEVICE_POLICY_SERVICE);

}

6.检测是否有权限的方法以及亮灭屏

/**

* @param view 亮屏

*/

public void checkScreenOn(View view) {

mWakeLock =mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");

    mWakeLock.acquire();

    mWakeLock.release();

}

/**

* @param view 熄屏

*/

public void checkScreenOff(View view) {

boolean admin =policyManager.isAdminActive(adminReceiver);

    if (admin) {

policyManager.lockNow();

    }else {

showToast("没有设备管理权限");

    }

}

/**

* @param view 检测并去激活设备管理器权限

*/

public void checkAndTurnOnDeviceManager(View view) {

Intent intent =new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);

    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminReceiver);

    intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "开启后就可以使用锁屏功能了...");//显示位置见图二

    startActivityForResult(intent, 0);

}

private boolean isOpen() {

if (policyManager.isAdminActive(adminReceiver)) {//判断超级管理员是否激活

        return true;

    }else {

return false;

    }

}

//用户激活设备管理权限的回调

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

    if (isOpen())

showToast("设备已被激活");

else

        showToast("设备没有被激活");

}

private void showToast(String Str) {

Toast.makeText(this, Str, Toast.LENGTH_SHORT).show();

}

7.使用

while (isNfcTestStart) {

checkScreenOn(null);//亮屏

//业务逻辑

checkScreenOff(null);//熄屏

}

这样就实现了一次读卡终生读取了,更好的实现目前还没找到,有知道的大佬评论区或者私信我,一起探讨探讨。

手打不易,点个赞呗。

亮灭屏参考文章:

https://blog.csdn.net/u011913612/article/details/77822280

上一篇下一篇

猜你喜欢

热点阅读