我正在制作一个托管小部件的应用程序,它运行良好,除了我添加电子邮件小部件时。当我这样做时,我得到一个 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);
}
}
}
非常感谢任何帮助。
最佳答案
这是一个老问题,但我想我找到了解决方案。
我想知道带有 exported = "false"
标签的 Activity 如何仍然被某些启动器调用。
有一种方法startAppWidgetConfigureActivityForResult
在这些启动器使用的 AppWidgetHost 中。
Starts an app widget provider configure activity for result on behalf of the caller. Use this method if the provider is in another profile as you are not allowed to start an activity in another profile. You can optionally provide a request code that is returned in Activity#onActivityResult(int, int, android.content.Intent) and an options bundle to be passed to the started activity. Note that the provided app widget has to be bound for this method to work.
因此,此方法不仅可以在另一个配置文件中启动 Activity ,而且还会忽略 exported = "false"
标记。对我来说这听起来像是一个安全问题。
关于java - 托管小部件获取 java.lang.SecurityException : Permission Denial error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45510916/