Android不允许使用SDK更新创建目录

Android不允许使用SDK更新创建目录,android,sdk,create-directory,Android,Sdk,Create Directory,奇怪的问题,但在一台设备上,Android不再允许应用程序创建目录(或任何目录)。这似乎是在我迁移到SDK 27之后发生的(我引入了一个需要升级的第三方库)。更奇怪的是,它可以在其他设备上工作。无法工作的设备是三星Galaxy Tab S3,运行Android 8(sdk 26) 以下是失败的代码: public static String mediaStorageDirectory() { return Environment.getExternalStorageDirectory()

奇怪的问题,但在一台设备上,Android不再允许应用程序创建目录(或任何目录)。这似乎是在我迁移到SDK 27之后发生的(我引入了一个需要升级的第三方库)。更奇怪的是,它可以在其他设备上工作。无法工作的设备是三星Galaxy Tab S3,运行Android 8(sdk 26)

以下是失败的代码:

public static String mediaStorageDirectory() {
    return Environment.getExternalStorageDirectory().toString() + File.separator + "myapp";
}

private DatabaseHelper(Context context) {
    super(context, DB_NAME, null, 1); 
    File dbPath = new File(Utilities.mediaStorageDirectory() + "/databases/");
    if (!dbPath.exists()) {
        if (dbPath.mkdirs()) {
            this.mContext = context;
            createDataBase();
        }
    }
}
代码创建一个目录,然后将中的app DB复制到该目录中。这段代码从时间的黎明就开始工作了……Android是否改变了文件创建的一些安全要求

如果您想知道,我已经设置了如下特权:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />


在创建目录结构之前,系统会成功提示用户输入这些权限。

因此,问题似乎与SDK 27有关。似乎他们现在要求(强制执行?)授予写入权限。以前只需要读取。我假设这与安全升级有关,但我找不到任何关于此更改的文档。也许其他所有人之前都做过这个。对于那些希望看到执行权限处理的代码的人,我在不久前从另一个堆栈溢出中提取了以下代码。我只是添加了以前缺少的WRITE_EXTERNAL_存储部分:

final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

public void checkPermissions() {
    List<String> permissionsNeeded = new ArrayList<String>();

    final List<String> permissionsList = new ArrayList<String>();
    if (!addPermission(permissionsList, Manifest.permission.CAMERA))
        permissionsNeeded.add("Camera");
    if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE))
        permissionsNeeded.add("Read External Storage");
    if (!addPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE))
        permissionsNeeded.add("Write External Storage");
    if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
        permissionsNeeded.add("GPS");
    if (!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO))
        permissionsNeeded.add("Record Audio");

    if (permissionsList.size() > 0) {
        if (permissionsNeeded.size() > 0) {
            // Need Rationale
            String message = "You need to grant access to " + permissionsNeeded.get(0);
            for (int i = 1; i < permissionsNeeded.size(); i++) {
                message = message + ", " + permissionsNeeded.get(i);
            }

            message = message + "." + " If you do not the application may not function correctly.";

            showMessageOKCancel(message, this,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                        }
                    });
        } else {
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
        }
    }
}

private static void showMessageOKCancel(String message, Activity activity, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(activity).setMessage(message).setPositiveButton("OK", okListener).create().show();
}

private boolean addPermission(List<String> permissionsList, String permission) {
    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
        permissionsList.add(permission);
        // Check for Rationale Option
        if (!shouldShowRequestPermissionRationale(permission))
            return false;
    }
    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
            Map<String, Integer> perms = new HashMap<String, Integer>();
            // Initial
            perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
            // Fill with results
            for (int i = 0; i < permissions.length; i++)
                perms.put(permissions[i], grantResults[i]);
            // Check for ACCESS_FINE_LOCATION
            if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                    && perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
                    && perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
                    && perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                    && perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                // All Permissions Granted
            }
            // Warn the user that the application will not run
            else if (perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                AlertDialog.Builder builder = new AlertDialog.Builder(StartActivity.this);
                builder.setTitle("File Read Permissions Not Granted");
                builder.setMessage("The Application cannot operate without READ access to files on your device. Do you want to grant this access?");
                builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(StartActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
                    }
                });
                builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                    }
                });
                if (!isFinishing())
                    builder.show();
            }
            // Warn the user that the application will not run
            else if (perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                AlertDialog.Builder builder = new AlertDialog.Builder(StartActivity.this);
                builder.setTitle("File Write Permissions Not Granted");
                builder.setMessage("The Application cannot operate without WRITE access to directories on your device. Do you want to grant this access?");
                builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(StartActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
                    }
                });
                builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                    }
                });
                if (!isFinishing())
                    builder.show();
            }else {
                // Permission Denied
                Toast.makeText(StartActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
                        .show();
            }
        }
        break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

目前尚不清楚您使用哪条路径。此外,您的代码很混乱,甚至在无法创建目录时尝试创建数据库。请编写更干净的代码作为开头。@greenapps我已经添加了生成媒体存储路径的代码。你假设我写了这段代码——我没有,在我继承它之前它已经存在很久了,因此引用“从时间的黎明开始工作”。我已经“清理”了它以供您审阅,减去try/catch处理,将其归结为代码有问题。thxYou不需要getExternalStorageDirectory()的任何权限。如果该路径/目录已存在,则不会创建数据库文件。这是故意的吗?是的。它只需要在应用程序首次运行时创建一次。从那里,我们不想重新创建它。
    // Check permissions for Android 6.0 devices
    if (Build.VERSION.SDK_INT >= 23) {
        // Marshmallow+
        checkPermissions();
    }