我通过android模拟器的浏览器下载了一个名为test.npk的文件。它保存在/sdcard/Download/test.npk中:
$ adb -e shell ls /sdcard/Download/
test.npk
当我打开模拟器的“下载”应用程序并单击test.npk时,我得到一个Toast:“无法打开文件”
当我查看logcat时,我发现它尝试的意图是错误的:
01-14 15:49:36.262 1232-1690/system_process I/ActivityManager﹕ START u0 {act=android.intent.action.VIEW dat=content://downloads/all_downloads/2 typ=application/octet-stream flg=0x3} from uid 10005 on display 0
01-14 15:49:36.264 1337-1337/android.process.media W/DownloadManager﹕ Failed to start Intent { act=android.intent.action.VIEW dat=content://downloads/all_downloads/2 typ=application/octet-stream flg=0x3 }: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://downloads/all_downloads/2 typ=application/octet-stream flg=0x3 }
正如您所看到的意图数据是content:// downloads / all_downloads / 2。这是为什么?我该如何为这样的意图制作一个intent-filter?我期待像file://bla-bla/test.npk或至少某些东西://bla/bal/test.npk
这些是我的意图过滤器:
<activity android:name=".MyActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:parentActivityName="com.example.OtherActivity"
android:uiOptions="splitActionBarWhenNarrow"
>
<meta-data android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.OtherActivity" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:pathPattern=".*\\.npk" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:host="*" />
<data android:pathPattern=".*\\.npk" />
</intent-filter>
</activity>
解决方案:
按照@ CommonsWare的建议,我可以使用以下intent-filter打开我的活动:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content"
android:host="*"
android:mimeType="application/vnd.com.fletech.npk"
android:pathPattern=".*"/>
</intent-filter>
并打开“文件”我需要使用以下代码:
Intent intent = getIntent();
String action = intent.getAction();
if (null != action) {
final Uri uri = intent.getData();
if (null != uri) {
// this part is optional, if you want to get the filename to save it by the same name
String filename = null;
Long filesize = null;
Cursor cursor = null;
try {
cursor = this.getContentResolver().query(uri, new String[] {
OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null );
if (cursor != null && cursor.moveToFirst()) {
filename = cursor.getString(0);
filesize = cursor.getLong(1);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
// copy the "content://" into a cache / temporary / or permanent file
final File file = new File(getCacheDir(), filename);
InputStream is = null;
OutputStream os = null;
try {
is = getContentResolver().openInputStream(uri);
os = new FileOutputStream(file);
try {
try {
final byte[] buffer = new byte[1024];
int read;
while ((read = is.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
os.flush();
} finally {
os.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} finally {
if (null != is) {
is.close();
}
if (null != os) {
os.close();
}
}
// open the copied file
if (file.exists()) {
categoryPack = PackI18nCategory.fromFile(file);
}
}
}
答案 0 :(得分:1)
正如您所看到的意图数据是content:// downloads / all_downloads / 2。这是为什么?
因为这是由管理下载的ContentProvider
传递到下载应用程序的内容。由下载Uri
处理的流是ContentProvider
。
我该如何为这样的意图制作一个意图过滤器?
支持content
和MIME类型application/octet-stream
的方案。
我期待像file://bla-bla/test.npk或至少某些东西://bla/bal/test.npk
ContentProvider
不要求使用文件扩展名,而且整体而言并不常见。 Android通常对文件扩展名没有太大作用,更喜欢使用MIME类型。