java - 许可授予的应用程序在棉花糖中崩溃

标签 java android android-studio

我正在创建一个用于将文件下载到手机的应用程序。该应用程序在少于23个的设备上运行良好,但在SDK> 23个设备上崩溃。我已成功授予运行时权限。但是在下载文件期间仍然会使应用程序崩溃。

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();
        }
    }


因此,该应用要求获得许可,我已成功授予它。但是在下载过程中,我正在获取此日志。

---------崩溃开始
E / AndroidRuntime:致命例外:Thread-153
                  流程:us.browserapp.manager,PID:2898
                  java.lang.RuntimeException:java.io.IOException:打开失败:ENOENT(无此类文件或目录)
                      在我们这里.browserapp.manager.get.DownloadManagerImpl $ Initializer.run(DownloadManagerImpl.java:210)
                   由以下原因引起:java.io.IOException:打开失败:ENOENT(没有这样的文件或目录)
                      在java.io.File.createNewFile(File.java:939)
                      在我们这里.browserapp.manager.get.DownloadManagerImpl $ Initializer.run(DownloadManagerImpl.java:202)
                   引起原因:android.system.ErrnoException:打开失败:ENOENT(无此类文件或目录)
                      在libcore.io.Posix.open(本机方法)
                      在libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
                      在java.io.File.createNewFile(File.java:932)
                      在我们这里.browserapp.manager.get.DownloadManagerImpl $ Initializer.run(DownloadManagerImpl.java:202)
E /表面:getSlotFromBufferLocked:未知缓冲区:0xae70c540
E / ActivityThread:活动us.browserapp.manager.ui.main.MainActivity泄漏了ServiceConnection us.browserapp.manager.ui.main.MainActivity$1@73e5314,它最初绑定在此处
                  android.app.ServiceConnectionLeaked:活动us.browserapp.manager.ui.main.MainActivity泄漏了最初绑定在此处的ServiceConnection us.browserapp.manager.ui.main.MainActivity$1@73e5314
                      在android.app.LoadedApk $ ServiceDispatcher。(LoadedApk.java:1092)
                      在android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986)
                      在android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303)
                      在android.app.ContextImpl.bindService(ContextImpl.java:1286)
                      在android.content.ContextWrapper.bindService(ContextWrapper.java:604)
                      在我们.browserapp.manager.ui.main.MainActivity.onCreate(MainActivity.java:104)
                      在android.app.Activity.performCreate(Activity.java:6237)
                      在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                      在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                      在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                      在android.app.ActivityThread.-wrap11(ActivityThread.java)
                      在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1344)
                      在android.os.Handler.dispatchMessage(Handler.java:102)
                      在android.os.Looper.loop(Looper.java:148)
                      在android.app.ActivityThread.main(ActivityThread.java:5417)
                      在java.lang.reflect.Method.invoke(本机方法)
                      在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)
                      在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E / ActivityThread:活动us.browserapp.manager.ui.main.MainActivity已泄漏ServiceConnection us.browserapp.manager.ui.fragment.MissionsFragment$1@961c89d,该绑定最初绑定在此处
                  android.app.ServiceConnectionLeaked:活动us.browserapp.manager.ui.main.MainActivity泄漏了最初绑定在此处的ServiceConnection us.browserapp.manager.ui.fragment.MissionsFragment$1@961c89d
                      在android.app.LoadedApk $ ServiceDispatcher。(LoadedApk.java:1092)
                      在android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986)
                      在android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303)
                      在android.app.ContextImpl.bindService(ContextImpl.java:1286)
                      在android.content.ContextWrapper.bindService(ContextWrapper.java:604)
                      在我们这里.browserapp.manager.ui.fragment.MissionsFragment.onCreateView(MissionsFragment.java:71)
                      在android.app.Fragment.performCreateView(Fragment.java:2220)
                      在android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
                      在android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
                      在android.app.BackStackRecord.run(BackStackRecord.java:793)
                      在android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
                      在android.app.FragmentManagerImpl $ 1.run(FragmentManager.java:482)
                      在android.os.Handler.handleCallback(Handler.java:739)
                      在android.os.Handler.dispatchMessage(Handler.java:95)
                      在android.os.Looper.loop(Looper.java:148)
                      在android.app.ActivityThread.main(ActivityThread.java:5417)
                      在java.lang.reflect.Method.invoke(本机方法)
                      在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)
                      在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I / Process:正在发送信号。 PID:2898 SIG:9
申请已终止。

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);
            }
        }
    }
}


有什么想法吗?我为此损失了将近3天。注意:应用程序在Lollipop设备中的运行情况极好。

最佳答案

这可能是由于您试图使用无效路径创建目录这一事实。例如,如果您尝试在没有权限的位置创建目录,则会发生这种情况。在这种情况下,对mkdirs的调用将失败,并且随后对createNewFile的调用将引发异常,因为从未实际创建目录。

关于java - 许可授予的应用程序在棉花糖中崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40371993/

相关文章:

java - 如何将基于 Java 的 Cassandra 客户端连接到 Cassandra 集群,而不是特定节点?

Java从数组中拆分字符串

android - 向 ScrollView 添加页脚

java - 我收到有关 java.lang.String 无法转换为 JSONarray 的错误

java - 如何将图标从 JLabel 转换为 BufferedImage?

Java 套接字只接受 header

java - 写入文件时出现空指针异常 - Android Studio

java -> 无法隔离参数 com.android.build.gradle

android - Gradle 模块和 git 子模块

java - 使用 try-with-resources 包围扫描仪