Reputation: 361
I am creating an app for downloading files to my phone. The app is working fine in devices less than 23 but getting crashed in SDK > 23 devices. I had successfully granted the permission on run-time. But still making the app crash during downloading files.
Permission.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
if (Build.VERSION.SDK_INT < 23) {
Toast.makeText(Permission.this,
"Build Version Less than 23", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, MainActivity.class));
}
else if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Toast.makeText(Permission.this,
"Permission Already Granted", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, MainActivity.class));
status = 1;
} else {
ActivityCompat.requestPermissions(this, new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"}, this.REQUEST_CODE);
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == this.REQUEST_CODE && grantResults.length == 1 && grantResults[0] == 0) {
Toast.makeText(Permission.this,
"Permission Granted Message", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, MainActivity.class));
}
else {
Toast.makeText(Permission.this,
"Permission Denied", Toast.LENGTH_LONG).show();
}
}
So the app is asking permission fine and I successfully granted it. But during downloading, I am getting this log.
--------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: Thread-153 Process: us.browserapp.manager, PID: 2898 java.lang.RuntimeException: java.io.IOException: open failed: ENOENT (No such file or directory) at us.browserapp.manager.get.DownloadManagerImpl$Initializer.run(DownloadManagerImpl.java:210) Caused by: java.io.IOException: open failed: ENOENT (No such file or directory) at java.io.File.createNewFile(File.java:939) at us.browserapp.manager.get.DownloadManagerImpl$Initializer.run(DownloadManagerImpl.java:202) Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) at libcore.io.Posix.open(Native Method) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) at java.io.File.createNewFile(File.java:932) at us.browserapp.manager.get.DownloadManagerImpl$Initializer.run(DownloadManagerImpl.java:202) E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae70c540 E/ActivityThread: Activity us.browserapp.manager.ui.main.MainActivity has leaked ServiceConnection us.browserapp.manager.ui.main.MainActivity$1@73e5314 that was originally bound here android.app.ServiceConnectionLeaked: Activity us.browserapp.manager.ui.main.MainActivity has leaked ServiceConnection us.browserapp.manager.ui.main.MainActivity$1@73e5314 that was originally bound here at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:1092) at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986) at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303) at android.app.ContextImpl.bindService(ContextImpl.java:1286) at android.content.ContextWrapper.bindService(ContextWrapper.java:604) at us.browserapp.manager.ui.main.MainActivity.onCreate(MainActivity.java:104) at android.app.Activity.performCreate(Activity.java:6237) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) E/ActivityThread: Activity us.browserapp.manager.ui.main.MainActivity has leaked ServiceConnection us.browserapp.manager.ui.fragment.MissionsFragment$1@961c89d that was originally bound here android.app.ServiceConnectionLeaked: Activity us.browserapp.manager.ui.main.MainActivity has leaked ServiceConnection us.browserapp.manager.ui.fragment.MissionsFragment$1@961c89d that was originally bound here at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:1092) at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986) at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303) at android.app.ContextImpl.bindService(ContextImpl.java:1286) at android.content.ContextWrapper.bindService(ContextWrapper.java:604) at us.browserapp.manager.ui.fragment.MissionsFragment.onCreateView(MissionsFragment.java:71) at android.app.Fragment.performCreateView(Fragment.java:2220) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148) at android.app.BackStackRecord.run(BackStackRecord.java:793) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535) at android.app.FragmentManagerImpl$1.run(FragmentManager.java:482) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) I/Process: Sending signal. PID: 2898 SIG: 9 Application terminated.
DownloadManagerImpl.java
public class DownloadManagerImpl implements DownloadManager
{
private static final String TAG = DownloadManagerImpl.class.getSimpleName();
private Context mContext;
private String mLocation;
protected ArrayList<DownloadMission> mMissions = new ArrayList<DownloadMission>();
public DownloadManagerImpl(Context context, String location) {
mContext = context;
mLocation = location;
loadMissions();
}
@Override
public int startMission(String url, String name, int threads) {
DownloadMission mission = new DownloadMission();
mission.url = url;
mission.name = name;
mission.location = mLocation;
mission.timestamp = System.currentTimeMillis();
mission.threadCount = threads;
new Initializer(mContext, mission).start();
return insertMission(mission);
}
@Override
public void resumeMission(int i) {
DownloadMission d = getMission(i);
if (!d.running && d.errCode == -1) {
d.start();
}
}
@Override
public void pauseMission(int i) {
DownloadMission d = getMission(i);
if (d.running) {
d.pause();
}
}
@Override
public void deleteMission(int i) {
getMission(i).delete();
mMissions.remove(i);
}
private void loadMissions() {
File f = new File(mLocation);
if (f.exists() && f.isDirectory()) {
File[] subs = f.listFiles();
for (File sub : subs) {
if (sub.isDirectory()) {
continue;
}
if (sub.getName().endsWith(".fdm")) {
String str = Utility.readFromFile(sub.getAbsolutePath());
if (str != null && !str.trim().equals("")) {
if (DEBUG) {
Log.d(TAG, "loading mission " + sub.getName());
Log.d(TAG, str);
}
DownloadMission mis = new Gson().fromJson(str, DownloadMission.class);
if (mis.finished) {
sub.delete();
continue;
}
mis.running = false;
mis.recovered = true;
insertMission(mis);
}
} else if (!sub.getName().startsWith(".") && !new File(sub.getPath() + ".fdm").exists()) {
// Add a dummy mission for downloaded files
DownloadMission mis = new DownloadMission();
mis.length = sub.length();
mis.done = mis.length;
mis.finished = true;
mis.running = false;
mis.name = sub.getName();
mis.location = mLocation;
mis.timestamp = sub.lastModified();
insertMission(mis);
}
}
}
}
@Override
public DownloadMission getMission(int i) {
return mMissions.get(i);
}
@Override
public int getCount() {
return mMissions.size();
}
private int insertMission(DownloadMission mission) {
int i = -1;
DownloadMission m = null;
if (mMissions.size() > 0) {
do {
m = mMissions.get(++i);
} while (m.timestamp > mission.timestamp && i < mMissions.size() - 1);
//if (i > 0) i--;
} else {
i = 0;
}
mMissions.add(i, mission);
return i;
}
@Override
public String getLocation() {
return mLocation;
}
private class Initializer extends Thread {
private Context context;
private DownloadMission mission;
public Initializer(Context context, DownloadMission mission) {
this.context = context;
this.mission = mission;
}
@Override
public void run() {
try {
URL url = new URL(mission.url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
mission.length = conn.getContentLength();
if (mission.length <= 0) {
mission.errCode = DownloadMission.ERROR_SERVER_UNSUPPORTED;
//mission.notifyError(DownloadMission.ERROR_SERVER_UNSUPPORTED);
return;
}
// Open again
conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Range", "bytes=" + (mission.length - 10) + "-" + mission.length);
if (conn.getResponseCode() != 206) {
// Fallback to single thread if no partial content support
mission.fallback = true;
if (DEBUG) {
Log.d(TAG, "falling back");
}
}
if (DEBUG) {
Log.d(TAG, "response = " + conn.getResponseCode());
}
mission.blocks = mission.length / BLOCK_SIZE;
if (mission.threadCount > mission.blocks) {
mission.threadCount = (int) mission.blocks;
}
if (mission.threadCount <= 0) {
mission.threadCount = 1;
}
if (mission.blocks * BLOCK_SIZE < mission.length) {
mission.blocks++;
}
new File(mission.location).mkdirs();
new File(mission.location + "/" + mission.name).createNewFile();
RandomAccessFile af = new RandomAccessFile(mission.location + "/" + mission.name, "rw");
af.setLength(mission.length);
af.close();
mission.start();
} catch (Exception e) {
// TODO Notify
throw new RuntimeException(e);
}
}
}
}
Any Idea about what is going on? I have lost nearly 3 days on this. NB: App is working superfine in Lollipop devices.
Upvotes: 1
Views: 163
Reputation: 3019
This could be due to the fact that you are trying to create a directory using an invalid path. For example, this can happen if you attempt to create a directory in a place you don't have permission to do so. If that is the case, the call to mkdirs
will fail and the subsequent call to createNewFile
will throw an exception since the directory was never actually created.
Upvotes: 0