托管小部件获取java.lang.SecurityException:Permission Denial错误

时间:2017-08-04 15:48:05

标签: java android widget runtime-error

我正在创建一个托管小部件的应用程序,除了我添加电子邮件小部件时它运行良好。当我这样做时,我得到一个java.lang.SecurityException:Permission Denial error:starting intent。

以下是错误日志:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=11, result=-1, data=Intent { (has extras) }} to activity {aheschl.screenscortcut/aheschl.screenscortcut.WidgetEdge}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.appwidget.action.APPWIDGET_CONFIGURE cmp=com.samsung.android.email.provider/com.samsung.android.email.widget.EmailWidgetConfig (has extras) } from ProcessRecord{af0a74c 10759:aheschl.screenscortcut/u0a319} (pid=10759, uid=10319) not exported from uid 10033
                                                                        at android.app.ActivityThread.deliverResults(ActivityThread.java:4926)
                                                                        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4969)
                                                                        at android.app.ActivityThread.access$1600(ActivityThread.java:222)
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1850)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                        at android.os.Looper.loop(Looper.java:158)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:7230)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                                                                     Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.appwidget.action.APPWIDGET_CONFIGURE cmp=com.samsung.android.email.provider/com.samsung.android.email.widget.EmailWidgetConfig (has extras) } from ProcessRecord{af0a74c 10759:aheschl.screenscortcut/u0a319} (pid=10759, uid=10319) not exported from uid 10033
                                                                        at android.os.Parcel.readException(Parcel.java:1620)
                                                                        at android.os.Parcel.readException(Parcel.java:1573)
                                                                        at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3131)
                                                                        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1541)
                                                                        at android.app.Activity.startActivityForResult(Activity.java:4284)
                                                                        at android.app.Activity.startActivityForResult(Activity.java:4231)
                                                                        at aheschl.screenscortcut.WidgetEdge.configureWidget(WidgetEdge.java:124)
                                                                        at aheschl.screenscortcut.WidgetEdge.onActivityResult(WidgetEdge.java:94)
                                                                        at android.app.Activity.dispatchActivityResult(Activity.java:7138)
                                                                        at android.app.ActivityThread.deliverResults(ActivityThread.java:4922)
                                                                        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4969) 
                                                                        at android.app.ActivityThread.access$1600(ActivityThread.java:222) 
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1850) 
                                                                        at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                        at android.os.Looper.loop(Looper.java:158) 
                                                                        at android.app.ActivityThread.main(ActivityThread.java:7230) 
                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

以下是日志中提到的configureWidget方法

private void configureWidget(Intent data) {
    Bundle extras = data.getExtras();
    int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
    AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
    if (appWidgetInfo.configure != null) {

        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
        intent.setComponent(appWidgetInfo.configure);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        startActivityForResult(intent, Constants.REQUEST_CREATE_APPWIDGET);

    } else {
        createWidget(data);
    }
}

这里是onActivityResult()

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) {
        if (requestCode == Constants.REQUEST_PICK_APPWIDGET) {
            configureWidget(data);
        } else if (requestCode == Constants.REQUEST_CREATE_APPWIDGET) {
            createWidget(data);
        } else if(requestCode == Constants.RESIZE_WIDGETS_CODE){
            //getParams
            int height = data.getIntExtra("height", 100);
            int width = data.getIntExtra("width", 100);
            receivedHeight = height;
            receivedWidth = width;
            waitingForResult = false;
        }
    } else if (resultCode == RESULT_CANCELED && data != null) {
        int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        if (appWidgetId != -1) {
            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
        }
    }
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

这是一个老问题,但我想我找到了解决方案。

我想知道带有exported = "false"标签的活动如何仍被某些启动器调用。 这些启动器使用的AppWidgetHost中有一种方法startAppWidgetConfigureActivityForResult

  

启动应用程序窗口小部件提供程序代表调用方配置结果的活动。如果提供者在另一个配置文件中,因为您不允许在另一个配置文件中启动活动,请使用此方法。您可以选择提供在Activity#onActivityResult(int,int,android.content.Intent)中返回的请求代码,以及将传递给已启动活动的选项包。   请注意,必须绑定提供的应用程序小部件才能使此方法起作用。

因此,该方法不仅可以在另一个配置文件中启动活动,而且还忽略了exported = "false"标签。对我来说听起来像是一个安全问题。