Droid Genie
Droid Genie

Reputation: 361

Permission Granted Still App crashes in Marshmllow

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

Answers (1)

cascal
cascal

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

Related Questions