我的应用程序(Keepass2Android)有一个内部文件选择器,用于查找密码数据库,密钥文件等。(它主要集成用于浏览Dropbox,SkyDrive等云提供商。)
因此我添加了许可
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
android:protectionLevel="signature"
。
文件选择器活动标有android:permission="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing"
,因此如果其他应用使用ACTION_GET_CONTENT
,我的内部文件选择器就不会显示。 (这不是很糟糕,但它不是一个非常高级的文件选择器,当然不是我的应用程序提供文件的主要目的,所以我认为用户看到我的应用程序出现会相当令人惊讶。)
这在Android 4.3之前效果很好,但是在Android 4.4中它没有:我的应用程序仍然显示在Storage Access Framework的文件选择器的左侧。但是,如果用户点击它,则会产生SecurityException: Permission denied.
12-16 06:13:33.393 E/AndroidRuntime(16058): java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.GET_CONTENT cat=[android.intent.category.OPENABLE] typ=*/* cmp=keepass2android.keepass2android/group.pals.android.lib.ui.filechooser.FileChooserActivity } from ProcessRecord{42623050 16058:com.android.documentsui/u0a81} (pid=16058, uid=10081) requires keepass2android.keepass2android.permission.KP2aInternalFileBrowsing
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.os.Parcel.readException(Parcel.java:1465)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.os.Parcel.readException(Parcel.java:1419)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2096)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1419)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.app.Activity.startActivityForResult(Activity.java:3424)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.app.Activity.startActivityForResult(Activity.java:3385)
12-16 06:13:33.393 E/AndroidRuntime(16058): at com.android.documentsui.DocumentsActivity.onAppPicked(DocumentsActivity.java:926)
12-16 06:13:33.393 E/AndroidRuntime(16058): at com.android.documentsui.RootsFragment$2.onItemClick(RootsFragment.java:183)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.widget.AdapterView.performItemClick(AdapterView.java:299)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.widget.AbsListView$3.run(AbsListView.java:3638)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.os.Handler.handleCallback(Handler.java:733)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.os.Handler.dispatchMessage(Handler.java:95)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.os.Looper.loop(Looper.java:136)
12-16 06:13:33.393 E/AndroidRuntime(16058): at android.app.ActivityThread.main(ActivityThread.java:5017)
12-16 06:13:33.393 E/AndroidRuntime(16058): at java.lang.reflect.Method.invokeNative(Native Method)
12-16 06:13:33.393 E/AndroidRuntime(16058): at java.lang.reflect.Method.invoke(Method.java:515)
12-16 06:13:33.393 E/AndroidRuntime(16058): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
12-16 06:13:33.393 E/AndroidRuntime(16058): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
12-16 06:13:33.393 E/AndroidRuntime(16058): at dalvik.system.NativeStart.main(Native Method)
12-16 06:13:33.393 W/ActivityManager( 580): Force finishing activity com.android.documentsui/.DocumentsActivity
12-16 06:13:33.904 W/ActivityManager( 580): Activity pause timeout for ActivityRecord{42f84718 u0 com.android.documentsui/.DocumentsActivity t42 f}
我想这种情况正在发生,因为存储访问框架的UI在另一个没有我许可的进程中运行。
有没有办法保留预期的行为,或者我应该删除权限,以便适用于所有Android版本?
答案 0 :(得分:0)
如果它是仅供内部使用的活动,请删除intent过滤器。
理论上,避免外部应用程序了解您的组件的正确方法是将其导出的属性设置为从AndroidManifest.xml文件中的声明设置为false。
然而,由于commonsware已经解释here,不幸的是,Android选择器中存在一个错误,它会忽略&#34;导出的&#34;列出它们时的活动状态,如果用户单击它们则会崩溃(与您正在试验的类似的错误)。
据我所知,你可以做的最好的事情就是从你的活动声明中删除你的意图过滤器标签,而不是用明确的意图来调用它。