Search code examples
androidandroid-widgetandroid-6.0-marshmallowsmartphone

Is there a listener for Android app widget permission changes?


I've been working on an app widget for Android 6 and how it works is that every time the Broadcast Receiver receives an onUpdate, it will check for permissions before updating the RemoteView with the appropriate contents such as a message saying, "permissions missing" or whatever it's supposed to have.

However, I notice that if I disable any of the permissions my app requires via System > App > Permissions the process gets marked as "dead" in Studio.

If I then test if the widget still works in the emulator by triggering an onUpdate, sure enough it's not working any more. As soon as I toggle the permissions back on, a new process ID is generated and the widget is alive and working again.

Now my question is, is there a way to capture that change in permissions? It's weird that the widget is still "alive" on the home screen when it's supposed to be "dead" according to Studio (with no errors thrown it seems...) due to a permissions change =/


Solution

  • Right, I think I've figured out the problem...

    When a user goes into a phone's setting > apps > app > permissions and then revokes permissions, it ends up killing the app's process - or it might actually be suspended somewhere because as soon as you grant a permission again, the same process (same PID) is alive again.

    As a result of this, the widget IDs are lost so onUpdate() isn't called when the broadcast is received and all the widgets that have been added to the home screen can't be updated.

    So, the workaround?

    Fetch a new instance of AppWidgetManager and manually put those widget IDs back into the Intent before super.onReceive() is called. Then you will be able to access all the widget instances again and update them accordingly.

    @Override
    public void onReceive(Context c, Intent i) {
    
        String action = i.getAction();
        if ( action.equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE) ) {
            ComponentName thiswidget = new ComponentName(c,     BroadcastHandler.class);
             AppWidgetManager am = AppWidgetManager.getInstance(c);
             int[] ids = am.getAppWidgetIds(thiswidget);
             i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
    
            // either handle the permission change at this point or in onUpdate()
        }
    
        super.onReceive(c,i);
    
    }
    

    I don't know why Google doesn't have a permissions revoked listener to be honest =/