托管小部件获取 java.lang.SecurityException:权限拒绝错误
Hosting widgets getting java.lang.SecurityException: Permission Denial 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.access00(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.access00(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"
标签的活动如何仍然被某些启动器调用。
这些启动器使用的 AppWidgetHost 中有一个方法 startAppWidgetConfigureActivityForResult
。
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.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.access00(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.access00(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"
标签的活动如何仍然被某些启动器调用。
这些启动器使用的 AppWidgetHost 中有一个方法 startAppWidgetConfigureActivityForResult
。
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"
标记。对我来说听起来像是一个安全问题。