1

我正在编写应用程序 A 和 B。我希望 A 能够向 B 发送任何给定 mime 类型的文件 URI。我找到了一个关于如何处理某人发出文件请求的解释,所以更像是一个拉动,因为我想将一个 URI 从 A 推送到 B,而不需要 B 请求。我还看到了关于如何在应用程序之间共享数据的更通用的描述,但它使用 ACTION_SEND,在这种情况下,用户将看到一个可供选择的应用程序列表。我只希望应用程序 B 专门接收文件 URI。此外,当有人出于不同目的执行 ACTION_SEND 时,我不希望应用 B 显示为选项。那么,如何将文件 URI 从一个特定应用程序发送到另一个特定应用程序?

编辑 1:向示例中添加一些代码片段。

在应用程序 A 中,我正在执行以下操作:

Intent testIntent = new Intent("com.example.appB.TEST");
testIntent.addCategory(Intent.CATEGORY_DEFAULT);
testIntent.setData(Uri.parse("file:///mnt/sdcard/test.txt"));
startActivityForResult(testIntent, TEST);

在应用程序 B 中,我在清单中有以下内容:

<activity
    android:name="com.example.appB.mainActivity"
    android:label="@string/app_name" 
    android:launchMode="singleTask" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.example.appB.TEST" />
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:scheme="file"/>
            <data android:mimeType="*/*"/>
    </intent-filter>
</activity>

我得到的错误是 ActivityNotFoundException。如果我去掉 setData 行,活动就会启动,但显然我没有 URI。

您可以阅读我在这里遇到的更多问题。

4

5 回答 5

2

呼吁startActivity()您在 B 中的活动,UriIntent. 假设您遵循通过 a 共享文件的方法FileProvider,您需要做的就是将FLAG_ACTIVITY_GRANT_READ_PERMISSION其作为标志包含在 上Intent,然后 B 将可以临时访问该文件。

这是一个示例项目,我通过 共享 PDF 文件FileProvider,然后让我的活动启动 PDF 查看器以查看该共享文件。在这种情况下,我的应用程序是 A,PDF 查看器应用程序是 B。

于 2014-08-15T16:55:19.990 回答
1

您可以执行以下操作:

1.使App B实现自定义广播接收器。

2.自定义广播只会被App A触发(广播)。

3.App B 将捕获(监听)广播消息,该消息也将包含文件 URI。

您可以为广播添加签名级别权​​限,以便其他应用程序可以拦截(监听)您的广播。请参阅文档

android:permission 广播者必须拥有向广播接收者发送消息的权限的名称。如果未设置此属性,则元素的权限属性设置的权限适用于广播接收器。如果两个属性都没有设置,则接收者不受权限保护。有关权限的更多信息,请参阅简介中的权限部分和单独的文档安全性和权限。

同样,您也可以为您的文件 Uri 添加权限,以使其更安全。

于 2014-08-15T17:09:21.647 回答
1

我将使用两个应用程序都知道的自定义 ACTION,这样它就不会使用其他应用程序知道使用的通用 ACTION_SEND。这解决了不希望它出现在 ACTION_SEND 中的问题。这也意味着只有注册您的自定义操作的应用程序才能接收它。不利的一面是,如果其他应用程序知道用于 ACTION 的字符串,则它们可能会收到该意图。

如果您想绝对确定只有 B 可以接收意图,那么您可以指定一个组件。请参阅:https://developer.android.com/reference/android/content/Intent.html#setComponent(android.content.ComponentName)如果这样做意味着 A 必须知道 B 内部的组件才能引导意图到,使 B 在更改该组件名称方面不太灵活。但这确实意味着来自 A 的意图只能到达 B。

请注意,您仍然不应该信任 B 中的意图。另一个应用程序可以指定操作字符串(反编译您的应用程序,或查看 logcat 以找到它)和 B 的组件并发送恶意意图。所以总是检查 B 中的输入。

于 2014-08-15T17:11:37.807 回答
0

抱歉回复旧帖。

我可以给出以下场景

1)两个应用程序应具有相同的 APPUSERID。

APP2的工作流程要从APP1读取数据

1)需要APP1的安装信息。(获取 PackageManager)

2)调用ApplicationInfo.getApplicationInfo(获取元数据)

脚步

1)将APP2中要访问的内容保存在APP1中的一个文件中。

这是在APP1

FileOutputStream fos = null
File file = null;
file = getFilesDir();
fos = openFileOutput("my.txt", Context.MODE_PRIVATE);
String text = "hello";
fos.write(text.getBytes());

在 APP2

String packageName = "your.package.name.of.app1";

2)然后加载APP1中保存的文件

PackageManager packageManager = getPackageManager();

ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);

String filePath = appInfo.dataDir + "/files/my.txt";

3)然后使用读取文件

FileInputStream fis = new FileInputStream (new File (filePath));
// Please write the further code to read the contents of the file 

4) APP1 和 APP2 中的用户 ID 相同,即packag="x.y.z"在两个应用程序中写入以下行后AndroidManifest.xml

android:sharedUserID = "a.b.c";// 确保在两个应用的清单文件中都包含这一行。这里 abc 和 xyz 是原始数据。

PS:我没有处理异常。

于 2015-04-24T07:17:45.873 回答
0

我认为提供的前三个答案都是完成这项工作的正确方法。目前,我正在对我的代码进行一些小的修改。我需要使用 setDataAndType 而不仅仅是 setData。即使应用程序 B 说它可以处理任何 mimeType,但未在应用程序 A 中指定 mimeType 会使这不起作用。

您可以阅读我在这里遇到的更多问题。

于 2014-08-15T18:43:44.267 回答