我从不同来源打开了 pdf 文件并得到了这个
Intents
:
文件管理器(Google 文件)-> 内部存储-> 下载:
Intent { act=android.intent.action.VIEW dat=content://com.google.android.apps.nbu.files.provider/1/file:///storage/emulated/0/Download/Untitled.pdf typ=application/pdf flg=0x13000001 cmp=team.sls.testapp/.ActivityMain }
文件管理器(Google 文件)-> 下载:
Intent { act=android.intent.action.VIEW dat=content://com.google.android.apps.nbu.files.provider/2/1863 typ=application/pdf flg=0x13000001 cmp=team.sls.testapp/.ActivityMain }
下载管理器(来自通知面板):
Intent { act=android.intent.action.VIEW dat=content://com.android.providers.downloads.documents/document/1508 typ=application/pdf flg=0x13000003 cmp=team.sls.testapp/.ActivityMain }
电报聊天:
Intent { act=android.intent.action.VIEW dat=content://org.telegram.messenger.provider/media/Telegram/Telegram Documents/2_5276292126848585208.pdf typ=application/pdf flg=0x13000001 cmp=team.sls.testapp/.ActivityMain }
什么是
content://com.google.android.apps.nbu.files.provider/2/1863
以及为什么同一文件的路径不同?
但更有趣的是 - 为什么情况 1 和 4 可以打开具有自定义扩展名的文件,但情况 2 和 3 却不能?
如果对情况1和2有误解,请查看这个问题
中的截图所有这四个 Uri 都遵循相同的模式
content://com.google.android.apps.nbu.files.provider/1/file:///storage/emulated/0/Download/Untitled.pdf
content://com.google.android.apps.nbu.files.provider/2/1863
content://com.android.providers.downloads.documents/document/1508
content://org.telegram.messenger.provider/media/Telegram/Telegram Documents/2_5276292126848585208.pdf
内容://
PACKAGE_NAME
.provider/CONTENT_DETAIL
PACKAGE_NAME
取决于应用。CONTENT_DETAIL
是可选的,可以是 file_id 或 full_path。如果您反编译所有这四个应用程序并查看它们的
AndroidManifest.xml
,您将看到相同的提供商标签,但有细微的差异。
查看 Google Files 的 AndroidManifest.xml
<application>
<provider
android:name="com.google.android.libraries.storage.storagelib.FileProvider"
android:exported="false"
android:authorities="com.google.android.apps.nbu.files.provider"
android:grantUriPermissions="true"/>
</application>
该提供商将生成如下所示的
HierarchicalUri
content://com.google.android.apps.nbu.files.provider/1651/2
使用下面的代码片段,您可以从所有这四个应用程序中读取文件/内容。
public final class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
InputStream is = getContentResolver().openInputStream(intent.getData());
String content = new String(Utils.unwrap(is));
Log.i("TAG", "content: " + content);
}
public static byte[] unwrap(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[4096];
while ((nRead = is.read(data, 0, data.length)) != -1) {
baos.write(data, 0, nRead);
}
baos.flush();
is.close();
baos.close();
return baos.toByteArray();
}
}
我希望我已经回答了你的问题。