androidpermissions

Android GrantPermissionsViewModel reports Package (mypackage) not found


I'm trying to ask for a permission (bluetooth, but I don't think the exact permission is relevant) in an Android app and the underlying GrantPermissionsViewModel is logging a "Package (my package name) not found" error. It's also not bringing up the permissions screen, but I think that's just a follow through issue so I want to solve this first. I'm suspecting that there is some magic XML file or Gradle file that needs something but I'm lost as to what it might be. Searching on SO and general searches with DuckDuckGo aren't giving me any useful hints.

This example is using ActivityCompat.requestPermissions, but I've tried the ActivityResultLauncher as well with the same (non) results.

The message seams to be coming from GrantPermissionsViewModel.kt at line 284 because packageInfoLiveData is null or empty. But why? It's clearly the correct package name. Is it somehow because this is a simple debug version and doesn't go though Play store?

I've reduced the problem to a simple app with a single button:

MainActivity.java

package com.blackholeofphotography.ble;

import static android.Manifest.permission.BLUETOOTH;

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity
{
   @Override
   protected void onCreate (Bundle savedInstanceState)
   {
      super.onCreate (savedInstanceState);
      Log.d ("ble", "onCreate");

      EdgeToEdge.enable (this);
      setContentView (R.layout.activity_main);
      ViewCompat.setOnApplyWindowInsetsListener (findViewById (R.id.main), (v, insets) ->
      {
         Insets systemBars = insets.getInsets (WindowInsetsCompat.Type.systemBars ());
         v.setPadding (systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
         return insets;
      });

      final Button button = findViewById (R.id.button);
      button.setOnClickListener (new View.OnClickListener ()
      {
         @Override
         public void onClick (View v)
         {
            Log.d ("ble", "onClick");
            if (ActivityCompat.checkSelfPermission (getApplicationContext (), BLUETOOTH) != PackageManager.PERMISSION_GRANTED)
            {
               Log.i ("ble", "requestPermissions");
               // https://android.googlesource.com/platform/packages/modules/Permission/+/ea7b26fe98c142d0a87d61c3a1c82335ea29c6d2/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
               // 
               ActivityCompat.requestPermissions (MainActivity.this, new String[] { BLUETOOTH }, 0);
            }
            else
            {
               Log.i ("ble", "Permission Granted");
            }
         }
      });
   }
}

AndroidManifest.xml

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

    <permission
        android:name="${applicationId}.SERVICE_PERMISSION"
        android:protectionLevel="signature" />

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


    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Ble"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/get_permission"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Logcat output

37ms; Flags=1, IntendedVsync=470552223679335, Vsync=470552690345983, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=470552703616344, AnimationStart=470552703624417, PerformTraversalsStart=470552703914678, DrawStart=470552864200058, SyncQueued=470552883176102, SyncStart=470552883646050, IssueDrawCommandsStart=470552883719435, SwapBuffers=470553059778359, FrameCompleted=470553061297526, DequeueBufferDuration=166302, QueueBufferDuration=502708, GpuCompleted=-486371034539139072, 
2025-04-01 18:44:52.613 10691-10691 ble                     com.blackholeofphotography.ble       D  onClick
2025-04-01 18:44:52.613 10691-10691 ble                     com.blackholeofphotography.ble       I  requestPermissions
2025-04-01 18:44:52.873 26063-26063 GrantPermi...sViewModel com....android.permissioncontroller  E  Package com.blackholeofphotography.ble not found

(It's days like this that make me look back fondly at programming with punch cards)


Solution

  • I found the real problem. The phone I use for debugging is Android 11. When I went to install the app, it complained about minimum SDK version. Without thinking, I changed that and didn't notice the newly appearing yellow warning marks on the permissions.

    Moving to a phone with Android 12 and building for that fixes everything.

    I do really need to target Android 11, so I'll have to set up the coding to support both, but I can do that now that I understand.