我已经彻底搜索了网络以找到答案,但没有结果。
我在我的 Android 应用程序中实现了一些“首选项”,包括将文件保存在您想要的任何位置的能力。
如果我在所谓的“集成 sdcard”上选择一条路径,则一切正常。但是我也有一个“真正的”外部 sdcard,它(在我的情况下)以符号链接的形式安装/storage/sdcard1
到/extSdCard
and /mnt/extSdCard
(而“内部”sdcard/storage/sdcard0
带有符号链接到/sdcard
and /mnt/sdcard
)。
在 ICS 上,我有外部/emmc
链接以及一些我不记得的链接。
问题是,如果我选择指向 this 的路径extSdCard
,应用程序会创建文件夹结构,但不会写入下载的文件,以“SecurityException”“目标必须在外部存储上”结尾。
但是这条路径在外部存储上!更多:如果写入权限有问题,为什么要创建文件夹?(android.permission.WRITE_EXTERNAL_STORAGE
存在于清单中)。
很可能我做错了什么;或者可能是一些错误?
日食日志:
11-30 11:58:29.143: D/ShareActivity(24752): doInBackground...
11-30 11:58:33.813: D/ShareActivity(24752): The response is: 200
11-30 11:58:50.283: D/ShareActivity(24752): location: Downloads
11-30 11:58:50.443: D/ShareActivity(24752): User defined folders created
11-30 11:58:50.443: D/ShareActivity(24752): path: /storage/sdcard1/temp
11-30 11:59:07.053: D/ShareActivity(24752): downloadUri: file:/storage/sdcard1/temp/test.3gpp
11-30 11:59:07.313: D/AndroidRuntime(24752): Shutting down VM
11-30 11:59:07.318: W/dalvikvm(24752): threadid=1: thread exiting with uncaught exception (group=0x41ce3300)
11-30 11:59:07.318: E/AndroidRuntime(24752): FATAL EXCEPTION: main
11-30 11:59:07.318: E/AndroidRuntime(24752): java.lang.SecurityException: Destination must be on external storage: file:/storage/sdcard1/temp/test.3gpp
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.os.Parcel.readException(Parcel.java:1425)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.content.ContentProviderProxy.insert(ContentProviderNative.java:420)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.content.ContentResolver.insert(ContentResolver.java:864)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.app.DownloadManager.enqueue(DownloadManager.java:904)
11-30 11:59:07.318: E/AndroidRuntime(24752): at dentex.youtube.downloader.ShareActivity$AsyncDownload$1$1.onClick(ShareActivity.java:269)
11-30 11:59:07.318: E/AndroidRuntime(24752): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.os.Handler.dispatchMessage(Handler.java:99)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.os.Looper.loop(Looper.java:137)
11-30 11:59:07.318: E/AndroidRuntime(24752): at android.app.ActivityThread.main(ActivityThread.java:4931)
11-30 11:59:07.318: E/AndroidRuntime(24752): at java.lang.reflect.Method.invokeNative(Native Method)
11-30 11:59:07.318: E/AndroidRuntime(24752): at java.lang.reflect.Method.invoke(Method.java:511)
11-30 11:59:07.318: E/AndroidRuntime(24752): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
11-30 11:59:07.318: E/AndroidRuntime(24752): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
11-30 11:59:07.318: E/AndroidRuntime(24752): at dalvik.system.NativeStart.main(Native Method)
11-30 11:59:09.248: I/Process(24752): Sending signal. PID: 24752 SIG: 9
相关代码:
lv.setOnItemClickListener(new OnItemClickListener() {
private File userFolder;
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String location = settings.getString("download_locations", "Downloads");
Log.d(DEBUG_TAG, "location: " + location);
boolean userLocationEnabled = settings.getBoolean("enable_user_location", false);
if (userLocationEnabled == false) {
if (location.equals("DCIM") == true) {
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
}
if (location.equals("Movies") == true) {
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
}
if (location.equals("Downloads") == true) {
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
}
Log.d(DEBUG_TAG, "path: " + path);
} else {
userFolder = new File(settings.getString("user_location", ""));
path = userFolder;
}
Log.d(DEBUG_TAG, "path: " + path.toString());
pos = position;
AlertDialog.Builder helpBuilder = new AlertDialog.Builder(ShareActivity.this);
helpBuilder.setIcon(android.R.drawable.ic_dialog_info);
helpBuilder.setTitle("Confirm Download for:");
helpBuilder.setMessage(" *** msg *** ");
helpBuilder.setPositiveButton("Download here", new DialogInterface.OnClickListener() {
@TargetApi(11)
public void onClick(DialogInterface dialog, int which) {
mLink = links[pos];
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Request request = new Request(Uri.parse(mLink));
uri = Uri.parse(path.toURI() + title + "." + mExt);
Log.d(DEBUG_TAG, "downloadUri: " + uri);
request.setDestinationUri(uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
if (isExternalStorageWritable() == true) {
enqueue = downloadManager.enqueue(request);
}
}
});
helpBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
//...
});
AlertDialog helpDialog = helpBuilder.create();
helpDialog.show();
}
});