0

Since Android SDK 30, packages does not have full visibility of other packages by default (https://developer.android.com/training/package-visibility).

Basically, starting with API level 30, if you're targeting that version or higher, your app cannot see, or directly interact with, most external packages without explicitly requesting allowance, either through a blanket QUERY_ALL_PACKAGES permission, or by including an appropriate element in your manifest.

(intent.resolveActivity returns null in API 30)

Even while adding the blanket QUERY_ALL_PACKAGES permission, you apparently still need to add specific queries

Even when permission QUERY_ALL_PACKAGES is added, you still need to add filter to your AndroidManifest.

(What does QUERY_ALL_PACKAGES permission do?)

How do you locate the specific query filter required for NFC actions? I have tried adding everything imaginable to AndroidManifest but without success. Currently my full AndroidManifest file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.operationBlipp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.NFC" />
    <permission android:name="android.permission.QUERY_ALL_PACKAGES" />


    <uses-feature android:name="android.hardware.nfc"
        android:required="true" />

    <application
        android:networkSecurityConfig="@xml/network_security_config"
        android:allowBackup="true"
        android:icon="@mipmap/logo_ob_round"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/logo_ob_light_round"
        android:supportsRtl="true"
        android:usesCleartextTraffic="true"
        android:theme="@style/Theme.NFCApplication">
        <activity
            android:name="com.example.operationBlipp.MainActivity"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.nfc.action.TECH_DISCOVERED"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
        </activity>
    </application>

    <queries>
        <package android:name="android.nfc" />
        <intent>
            <action android:name="android.intent.action.ACTION_TAG_DISCOVERED" />
        </intent>
        <intent>
            <action android:name="android.intent.action.*" />
        </intent>
    </queries>



</manifest>

And everything compiles but I still just get returned null from resolveIntent as seen here:

    @Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(intent, 0);
    setIntent(intent);
    resolveIntent(intent);
}

private void resolveIntent(Intent intent) {
    String action = intent.getAction();
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
            || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
            || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))
    {
        tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        assert tag != null;
        tagHeader = new NFCTagHeader(tag);
        Toast.makeText(this, "New card with UID " + tagHeader.getUID() + " detected", Toast.LENGTH_SHORT).show();
    }
    else if (action == null) {
        Log.e("NullAction", "Action is null!");
    }
}

I think there was some update for androidstudio which broke this recently because I reverted commits to ones not targeting SDK 30 and encountered the same issue. Maybe there's something else that causes this?

Edit:

Some clarification and added code. It has worked before and is (used to be) a fully functioning application, currently the NFC adapter is initialized in the main function with:

    nfcAdapter = nfcHandler.createAdapter(this);
    assert nfcAdapter != null;

with the called code basically being

NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);

which is then used in onResume to enable foreground dispatch:

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

    assert nfcAdapter != null;
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);

}

ResolveIntent() gets properly called every time you scan an NFC card but the intent.getAction(); now only returns null.

oskhen
  • 11
  • 2
  • I'm not sure why you are trying to resolve NFC intents, this is not the standard pattern for using NFC via Intents, You seem to be missing a lot of code in your example. Normally `onNewIntent` will only be called if you have `enableForegroundDispatch` which you don't seem to have done. At the moment it looks like you are only handling when your App is started by NFC and then you would call `resloveIntent` from `onCreate` with the value of `getIntent()` – Andrew Feb 02 '22 at 22:02
  • @Andrew I updated the post to clarify, enableForegroundDispatch is enabled in onResume and resolveIntent gets properly called but only returns null because of the new package visibility restrictions (as I've understood it). – oskhen Feb 03 '22 at 22:30
  • Thanks for the clarity. I don't have a 30 API phone to test with but I moved away from using `enableForegroundDispatch` some time ago to the better API of `enableReaderMode` as you have more control and less negative side effect and is more reliable (and has nothing to do with Intents so might not have the problem you currently seem to have). The only other comment I have is that `List resolveInfos = getPackageManager()...` seems redundant and so is `setIntent(intent);` but I don't think call these should cause a problem. – Andrew Feb 03 '22 at 22:48
  • Thank you for this. Using enableReaderMode solved the problem, probably by circumventing it entirely. Also those lines were in fact redundant and were just added during debugging. – oskhen Feb 08 '22 at 18:41

0 Answers0