首页 > 解决方案 > 有意来电——避免给自己打电话

问题描述

工作正常:我正在开发的应用程序被调用以打开文本文件(字节数组)作为工作数据文件(纯旧文本文件(.se 和 .si,未注册的 MIME 文件类型,我的应用程序输入文件从不 .txt或 .csv)和 xml 文件)。如果内容正常,则会打开一个会话,将文件内容显示为列表报告。从 Filer 应用程序获取意图调用或附加到电子邮件。(这是应用程序的基本业务框架)。

这就是接收意图的方式以及我拒绝错误内容的方式(当被除我之外的任何其他应用程序调用时工作正常):

if (action.compareTo(Intent.ACTION_VIEW) == 0) {
    // Open data from other app with intent
    String scheme = intent.getScheme();
    ContentResolver resolver = getContentResolver();
    Uri uri = intent.getData();
    String sFileName = null;
    if (scheme.compareTo(ContentResolver.SCHEME_CONTENT) == 0)
        sFileName = Utils.getContentName(resolver, uri);
    else if (scheme.compareTo(ContentResolver.SCHEME_FILE) == 0)
        sFileName = uri.toString();
    int iRet = (-1);
    byte[] readData = Utils.ReadInputData(resolver, uri);
    if (readData == null) {
        // Open data by file name
        iRet = ... 
    } else {
        // Open data by byte array (file data from the other app)
        iRet = ... 
        }
    }
    if (iRet == 0) {
        // OK
        this.setResult(Activity.RESULT_OK, null);
    } else {
        // Failure
        this.setResult(Activity.RESULT_CANCELED, null);
        this.finish();
        return;
    }
} 

这一切都很好打开传入的正确文件。如果 Android 文件管理器、其他文件管理器应用程序或电子邮件尝试调用没有正确内容的文本文件,它也可以正常工作,答案是,拒绝,好的。

工作正常:该应用程序还调用其他应用程序来显示屏幕上显示的报告的文本文件、csv 文本 (.csv) 文件(MS Excel 等)和选项卡式文本 (.txt) 文件(MS Word 等)(对于在这些应用程序中进行更多分析和演示)。

Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(FilePathName);
String extension = file.getName().substring(file.getName().lastIndexOf(".") + 1);
Uri uri = Uri.parse(FilePathName);
// From Build.VERSION_CODES.N there is entire different file view intent business
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    uri = FileProvider.getUriForFile(activity.getApplication(),
            activity.getApplication().getPackageName(), file);
    // We have to ask around for permissions to display the file
    List<ResolveInfo> resInfoList = activity.getPackageManager().queryIntentActivities(
            intent, PackageManager.MATCH_DEFAULT_ONLY);
    if(resInfoList==null)
        return;
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        // An attempt to exlude oneself (don't work)
        if (!packageName.equals("com.my.app"))
            activity.grantUriPermission(
                    packageName, 
                    uri, 
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION 
                    | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
} else // Elder up to Android 6
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension));
try {
    activity.startActivity(intent);
} catch (ActivityNotFoundException e) {
    ...
}

当其他应用程序接收到意图调用时,这可以正常工作。

我的问题是:我的应用程序本身存在明显的风险(用户在我的应用程序的呼叫中选择我的应用程序,或者我的应用程序是唯一响应的纯文本应用程序)。如果不是我的应用程序崩溃拒绝它自己的文件(错误的内容),而不是其他应用程序的意图调用,那将不是问题。

实际上我有两个解决方案路径,我不能让它们中的任何一个工作?

  1. 过滤掉使用 resolveInfo 调用自己的 if (!packageName.equals("com.my.app"))
  2. 在意图调用中拒绝我自己的文件后解决崩溃

过滤掉用 resolveInfo 调用自己我没有在 List resInfoList 中获得我自己的应用程序,所以我不能跳过它???根据其他 Stackoverflow Q/A,它应该可以工作,但不适合我?但在此之后,应用程序被我自己的意图调用(HAXM 模拟器没有其他 csv 解释应用程序,因此它在没有应用程序选择的情况下发送意图调用)。

在拒绝我自己的文件后解决崩溃,我不知道是什么原因造成的。

是的,我可以拥有和处理工作文件的多个活动,一个由应用程序本身打开一个文件,不同于文件管理器和电子邮件应用程序的活动。它适用于 2,3 和 4 活动并且被拒绝的电话,它们都存活下来。我认为多活动功能是一个主要的应用程序功能。只有单一活动能力,这个问题仍然存在。

是的,当我打电话给自己时,我可能会通过 this.finish() 破坏我自己的活动。然后我需要(类似于)发送带有意图的活动 ID,如果它相同,只需删除它。但令人惊奇的是,它在拒绝时也没有调用 this.finish() 就崩溃了?事实上,如果我什么都不做,收到来自自己的意图调用,它也会在离开后崩溃,但不会因其他人的意图调用而崩溃。弄得我一头雾水,这样的想法,也行不通。

关于解决方案路径或解释为什么我失败的任何好的提示?

这是我的崩溃:

2019-02-21 05:39:27.482 6149-6149/com.me.myapp.Myapp D/AndroidRuntime: Shutting down VM
2019-02-21 05:39:27.484 6149-6149/com.me.myapp.Myapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.me.myapp.Myapp, PID: 6149
    java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 5, found: 0 Pager id: com.me.myapp.Myapp:id/pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.me.myapp.MainActivity$ViewPagerAdapter
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1135)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
        at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
        at android.view.View.measure(View.java:22002)
        at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1060)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:451)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:721)
        at android.view.View.measure(View.java:22002)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2410)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1498)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1751)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

当我从 Android 文件管理器进行意图调用时(没有其他应用程序对 CSV 文件做出响应,并且我如上所述拒绝它)我在转储中收到以下消息(但我的应用程序不会崩溃,但我猜它是我的调用应用程序活动崩溃):

2019-02-21 05:57:15.811 7746-7746/com.me.myapp.Myapp E/ActivityThread: Activity com.me.myapp.MainActivity has leaked IntentReceiver com.me.myapp.MainActivity$5@e1fa714 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.me.myapp.MainActivity has leaked IntentReceiver com.me.myapp.MainActivity$5@e1fa714 that was originally registered here. Are you missing a call to unregisterReceiver()?

标签: javaandroidandroid-intent

解决方案


推荐阅读