使用 DownloadManager 时,SD 在 phone 上出现 IllegalStateException
IllegalStateException on phone with SD while using DownloadManager
我在 Play 商店收到关于我的应用出现 ANR 的报告。
这是堆栈跟踪:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.IllegalStateException: Unable to create directory: /storage/sdcard0/storage/external_SD/Video
at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:496)
at com.pipodi.italiansubsmobileclient.connections.ConnectionForSubtitle.doInBackground(ConnectionForSubtitle.java:61)
at com.pipodi.italiansubsmobileclient.connections.ConnectionForSubtitle.doInBackground(ConnectionForSubtitle.java:21)
at android.os.AsyncTask.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more
代码如下:
SharedPreferences preferences = MainActivity.context.getSharedPreferences(Constants.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
String path = preferences.getString("DOWNLOADDIR", null);
this.directory = "";
try {
directory = path.replace(Environment.getExternalStorageDirectory().getCanonicalPath(), "");
} catch (IOException e) {
e.printStackTrace();
}
File direct = new File(path);
if (!direct.exists()) {
direct.mkdirs();
}
DownloadManager mgr = (DownloadManager) MainActivity.context
.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri
.parse("https://api.italiansubs.net/api/rest/subtitles/download?subtitle_id="
+ this.id
+ "&authcode="
+ somecodehere
+ "&apikey="
+ Constants.APIKey);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
List<Cookie> loginCookies = LoginVariables.loginCookies;
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Download sottotitoli")
.setDescription(fileName)
.setDestinationInExternalPublicDir(directory,
fileName + ".zip");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String cookieString = "";
for (Cookie cookie : loginCookies) {
cookieString += cookie.getName() + "=" + cookie.getValue() + "; path=" + cookie.getPath()
+ "; domain=" + cookie.getDomain() + "; expiry=" + cookie.getExpiryDate() + "; ";
}
request.addRequestHeader("Cookie", cookieString);
mgr.enqueue(request);
return null;
出现异常的行是这样的:
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Download sottotitoli")
.setDescription(fileName)
.setDestinationInExternalPublicDir(directory,
fileName + ".zip");
看来,在带有外部 SD 卡的 phone 上,应用会抛出异常。我告诉用户尝试将文件保存在 phone 的内部存储器上,下载成功完成。现在,我无法创建一个用 SD 卡模拟 phone 的 AVD,所以我在这里问你这个问题。
在清单上有这个权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
我是否还需要授予该应用读取外部存储的权限,或者什么?
该设备是 LG Optimus L5 II (vee5nfc) 运行 Android 4.1.
谢谢大家的帮助。
我的直觉告诉我外部存储无法写入。它可能丢失、只读或安装到计算机上。我会检查它是否可以使用从开发者网站获取的以下代码片段写入。
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
我添加了这个:
@Override
protected void onPreExecute() {
super.onPreExecute();
if (isExternalStorageWritable()) {
Toast.makeText(MainActivity.context, "Writable", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.context, "Unwritable", Toast.LENGTH_LONG).show();
}
}
下载前显示"Writable",但随后抛出异常。没有人将他们的 phone 安装在 PC 上。
最后我解决了这个问题。我认为这是一个 OS 版本相关的问题:最低版本是 4.x,但我修复了将其设置为 4.3.1 的错误。
我在 Play 商店收到关于我的应用出现 ANR 的报告。
这是堆栈跟踪:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.IllegalStateException: Unable to create directory: /storage/sdcard0/storage/external_SD/Video
at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:496)
at com.pipodi.italiansubsmobileclient.connections.ConnectionForSubtitle.doInBackground(ConnectionForSubtitle.java:61)
at com.pipodi.italiansubsmobileclient.connections.ConnectionForSubtitle.doInBackground(ConnectionForSubtitle.java:21)
at android.os.AsyncTask.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more
代码如下:
SharedPreferences preferences = MainActivity.context.getSharedPreferences(Constants.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
String path = preferences.getString("DOWNLOADDIR", null);
this.directory = "";
try {
directory = path.replace(Environment.getExternalStorageDirectory().getCanonicalPath(), "");
} catch (IOException e) {
e.printStackTrace();
}
File direct = new File(path);
if (!direct.exists()) {
direct.mkdirs();
}
DownloadManager mgr = (DownloadManager) MainActivity.context
.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri
.parse("https://api.italiansubs.net/api/rest/subtitles/download?subtitle_id="
+ this.id
+ "&authcode="
+ somecodehere
+ "&apikey="
+ Constants.APIKey);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
List<Cookie> loginCookies = LoginVariables.loginCookies;
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Download sottotitoli")
.setDescription(fileName)
.setDestinationInExternalPublicDir(directory,
fileName + ".zip");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String cookieString = "";
for (Cookie cookie : loginCookies) {
cookieString += cookie.getName() + "=" + cookie.getValue() + "; path=" + cookie.getPath()
+ "; domain=" + cookie.getDomain() + "; expiry=" + cookie.getExpiryDate() + "; ";
}
request.addRequestHeader("Cookie", cookieString);
mgr.enqueue(request);
return null;
出现异常的行是这样的:
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Download sottotitoli")
.setDescription(fileName)
.setDestinationInExternalPublicDir(directory,
fileName + ".zip");
看来,在带有外部 SD 卡的 phone 上,应用会抛出异常。我告诉用户尝试将文件保存在 phone 的内部存储器上,下载成功完成。现在,我无法创建一个用 SD 卡模拟 phone 的 AVD,所以我在这里问你这个问题。
在清单上有这个权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
我是否还需要授予该应用读取外部存储的权限,或者什么?
该设备是 LG Optimus L5 II (vee5nfc) 运行 Android 4.1.
谢谢大家的帮助。
我的直觉告诉我外部存储无法写入。它可能丢失、只读或安装到计算机上。我会检查它是否可以使用从开发者网站获取的以下代码片段写入。
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
我添加了这个:
@Override
protected void onPreExecute() {
super.onPreExecute();
if (isExternalStorageWritable()) {
Toast.makeText(MainActivity.context, "Writable", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.context, "Unwritable", Toast.LENGTH_LONG).show();
}
}
下载前显示"Writable",但随后抛出异常。没有人将他们的 phone 安装在 PC 上。
最后我解决了这个问题。我认为这是一个 OS 版本相关的问题:最低版本是 4.x,但我修复了将其设置为 4.3.1 的错误。