gpt4 book ai didi

android - 如果在 Kiosk 模式 Activity 中启动,NFCAdpater.enableReaderMode(...) 无法始终如一地工作

转载 作者:行者123 更新时间:2023-12-04 23:50:00 28 4
gpt4 key购买 nike

我有一个以 Kiosk 模式启动的应用程序,应该读取 NFCTags 并使用react。它正在使用 enableReaderModeNFCAdapteronResume开始阅读它们。如果应用程序是例如,一切正常。 (重新)在开发过程中开始。但是,如果我重新启动设备(并且 Activity 自动启动), Activity 有时会进入正确模式,但通常只播放 NFC 系统声音和我的 handleTag不叫。

根据我的记录,我拥有的 NFCAdapter 设置代码在所有情况下都被正确调用

我试过enableForegroundDispatch也一样,但是效果是一样的。我还尝试定期记忆 enableReaderMode但它也有同样的效果。

有人知道发生了什么吗?

更新

当我尝试在失败的情况下设置阅读器模式时,我在日志中看到此错误消息

NfcService: setReaderMode: Caller is not in foreground and is not system process.

尽管该 Activity 在前景中清晰可见。

手机是 Google Pixel 3

该应用程序是设备所有者,通过
adb shell dpm set-device-owner ...

应用程序 list
<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"
android:testOnly="true">

<!-- snip DeviceAdminReceiver -->

<activity
android:name=".FullscreenActivity"
android:screenOrientation="reverseLandscape"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:theme="@style/FullscreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" />

应该处理 NFC 标签的 FullscreenActivity
public class FullscreenActivity extends AppCompatActivity {
NfcAdapter mAdapter;
private DevicePolicyManager mDevicePolicyManager;
private ComponentName mAdminComponentName;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mDevicePolicyManager = (DevicePolicyManager) getSystemService(
Context.DEVICE_POLICY_SERVICE);
if (mDevicePolicyManager.isDeviceOwnerApp(getPackageName())) {
mAdminComponentName = MyDeviceAdminReceiver.getComponentName(this);

IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
intentFilter.addCategory(Intent.CATEGORY_HOME);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
mDevicePolicyManager.addPersistentPreferredActivity(
mAdminComponentName, intentFilter,
new ComponentName(getPackageName(),
FullscreenActivity.class.getName()));

mDevicePolicyManager.setLockTaskPackages(mAdminComponentName,
new String[]{getPackageName()});

mDevicePolicyManager.setKeyguardDisabled(mAdminComponentName, true);

}
startLockTask();
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
setFullscreenFlags();
}
}

private void setFullscreenFlags() {
getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}

@Override
protected void onResume() {
super.onResume();
setFullscreenFlags();
mAdapter = NfcAdapter.getDefaultAdapter(this);
setupNfcAdapter();
}

private void setupNfcAdapter() {
if (mAdapter == null) return;

Bundle options = new Bundle();
// No sure this is needed
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 50000);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass())
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mAdapter.enableReaderMode(this, this::handleTag,
NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS |
NfcAdapter.FLAG_READER_NFC_A |
NfcAdapter.FLAG_READER_NFC_B |
NfcAdapter.FLAG_READER_NFC_F |
NfcAdapter.FLAG_READER_NFC_V, options);
}

@Override
protected void onPause() {
super.onPause();

if (mAdapter != null) {
mAdapter.disableReaderMode(this);
}
}

private void handleTag(Tag tag) {
Log.d("NFCADAPTER", "tag detected");
}

}

最佳答案

我找到了适合我的情况的解决方案(嗯,更多的解决方法)。

我认为发生的是 NfcService不知道 Activity 正在前台运行。 NfcService通过 ForegroundUtils 跟踪前台 Activity 它利用 IProcessObserver .

我认为正在发生的事情是,我的 Activity 有时会在设置此流程观察者之前成为前台 Activity ,因此 NfcService认为我的 Activity 没有在前台运行,从而阻止了对 read 方法的调用。

作为解决方法,我所做的是接收 NfcAdapter.STATE_ON通过在 NfcAdapter.ACTION_ADAPTER_STATE_CHANGED 上注册接收器进行更改在 Activity 中。如果收到此事件,则认为是上述情况,我会终止并重新启动应用程序(请参阅 [1])。 ForgroundUtils 现在观察到了这一点。我能够进入阅读器模式。

[1] How do I programmatically "restart" an Android app?

关于android - 如果在 Kiosk 模式 Activity 中启动,NFCAdpater.enableReaderMode(...) 无法始终如一地工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61142449/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com