Android N 添加PowerControl Widget

  • Post author:
  • Post category:其他

问题

开启Power Control Widget,过开机向导报错,报错log如下:

12-23 19:19:46.050 E/AndroidRuntime(868): FATAL EXCEPTION: main
12-23 19:19:46.050 E/AndroidRuntime(868): Process: com.android.settings, PID: 868
12-23 19:19:46.050 E/AndroidRuntime(868): java.lang.RuntimeException: Unable to start receiver com.android.settings.widget.SettingsAppWidgetProvider: java.lang.IllegalStateException: User 0 must be unlocked for widgets to be available
12-23 19:19:46.050 E/AndroidRuntime(868): at android.app.ActivityThread.handleReceiver(ActivityThread.java:3047)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.app.ActivityThread.-wrap18(ActivityThread.java)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1561)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.os.Handler.dispatchMessage(Handler.java:102)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.os.Looper.loop(Looper.java:154)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.app.ActivityThread.main(ActivityThread.java:6119)
12-23 19:19:46.050 E/AndroidRuntime(868): at java.lang.reflect.Method.invoke(Native Method)
12-23 19:19:46.050 E/AndroidRuntime(868): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
12-23 19:19:46.050 E/AndroidRuntime(868): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
12-23 19:19:46.050 E/AndroidRuntime(868): Caused by: java.lang.IllegalStateException: User 0 must be unlocked for widgets to be available
12-23 19:19:46.050 E/AndroidRuntime(868): at android.os.Parcel.readException(Parcel.java:1692)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.os.Parcel.readException(Parcel.java:1637)
12-23 19:19:46.050 E/AndroidRuntime(868): at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.updateAppWidgetProvider(IAppWidgetService.java:745)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.appwidget.AppWidgetManager.updateAppWidget(AppWidgetManager.java:634)
12-23 19:19:46.050 E/AndroidRuntime(868): at com.android.settings.widget.SettingsAppWidgetProvider.updateWidget(SettingsAppWidgetProvider.java:720)
12-23 19:19:46.050 E/AndroidRuntime(868): at com.android.settings.widget.SettingsAppWidgetProvider.onReceive(SettingsAppWidgetProvider.java:839)
12-23 19:19:46.050 E/AndroidRuntime(868): at android.app.ActivityThread.handleReceiver(ActivityThread.java:3040)
12-23 19:19:46.050 E/AndroidRuntime(868): ... 8 more

分析

  1. 通过User 0 must be unlocked for widgets to be available可定位到AppWidgetServiceImpl.java
private void ensureGroupStateLoadedLocked(int userId, boolean             enforceUserUnlockingOrUnlocked) {
        if (enforceUserUnlockingOrUnlocked && !isUserRunningAndUnlocked(userId)) {
            throw new IllegalStateException(
                    "User " + userId + " must be unlocked for widgets to be available");
        }
        if (enforceUserUnlockingOrUnlocked && isProfileWithLockedParent(userId)) {
            throw new IllegalStateException(
                    "Profile " + userId + " must have unlocked parent");
        }
        final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId);
        ......
}

出现该错误是由于isUserRunningAndUnlocked()返回为false,进一步追踪

 private boolean isUserRunningAndUnlocked(@UserIdInt int userId) {
        return mUserManager.isUserRunning(userId) && StorageManager.isUserKeyUnlocked(userId);
}

通过打印LOG得知mUserManager.isUserRunning(userId)返回true,StorageManager.isUserKeyUnlocked(userId)返回为false。
2. 出现该错误是由于执行SettingsAppWidgetProvider中回调方法onReceive()->updateWidget()->

final AppWidgetManager gm = AppWidgetManager.getInstance(context);
gm.updateAppWidget(THIS_APPWIDGET, views);

解决

修改onReceive()方法updateWidget的逻辑

    final int userId = UserHandle.getCallingUserId();
        Log.i("wangyannan"," userid:"+userId);
    if(StorageManager.isUserKeyUnlocked(userId)){
         updateWidget(context);
    }else{
        Log.i("wangyannan","unlocked->userid:"+userId);
    }

备注

Android N平台增加了Directboot功能,在做某些访问时需要确定该用户是否解锁,如果解锁才允许访问。故该问题是由于刚进开机向导时间过早,用户还没有解锁,进而导致更新widget出错。


版权声明:本文为w1070216393原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。