I got a report on the Play Store of an ANR on my app.
Here's the stacktrace:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.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$1.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$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more
Here's the code:
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;
The line getting the exception is this:
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Download sottotitoli")
.setDescription(fileName)
.setDestinationInExternalPublicDir(directory,
fileName + ".zip");
It seems that, on a phone with an external SD card, the app throws an exception. I told the user to try saving the file on the internal storage of the phone and the download was completed succesfully. Now, I couldn't manage to create an AVD emulating a phone with an SD card, so I'm here asking you this question.
On the Manifest there is this permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Do I need to give the app also the permission to read the external storage, or what?
The device is a LG Optimus L5 II (vee5nfc) running Android 4.1.
Thanks for the help, guys.
At the end I solved the issue. I think it was an OS version-related problem: the minimum version was 4.x, but I fixed the error putting it to 4.3.1.