Android M及以上存储权限问题

Android M and above storage permission issue

我的应用程序用于从用户那里获取文本(字符串)并将其保存在内部 and/or 外部存储中,从中读取,问题是从我尝试 [=31= 的大约两个日期开始的] 虚拟设备上的应用程序使用 OS android 7.0.1 "Nougat" 和应用程序 skip/ignoring 写入外部存储权限,即使我看到权限对话框正方形出现时我点击外部缓存按钮

my question is: Is this mean There's no needed to create permission method for android OS android marshmallow and above?


看到这个 GIF 相关

整个代码

    public class MainFragment extends android.app.Fragment {

    private View view;
    private EditText userName2;
    private Button internalButton, externalButton, showData;
    FileOutputStream fileOutputStream;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.fragment_main, container, false);
        userName2 = view.findViewById(R.id.editTextUserName);
        internalButton = view.findViewById(R.id.internalButton);
        externalButton = view.findViewById(R.id.externalButton);
        showData = view.findViewById(R.id.showData);

        internalButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                saveToInternalCache();
            }
        });

        externalButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                enableRunTimePermisstion();


            }
        });

        showData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getActivity(), DataActivity.class);
                startActivity(intent);
            }
        });

        return view;

    }


    @TargetApi(23)
    public void enableRunTimePermisstion() {
        if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) &&
                (getContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                        PackageManager.PERMISSION_GRANTED))
            if (getActivity().shouldShowRequestPermissionRationale
                (Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(getActivity(), "Write storage permission is need for app"
                    , Toast.LENGTH_LONG).show();
        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            Toast.makeText(getActivity(), "request permission"
                    , Toast.LENGTH_LONG).show();
        }
        saveToExternalCache();

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getActivity(), "Write external storage granted", Toast.LENGTH_LONG).show();
                saveToExternalCache();
            }
        } else {
            Toast.makeText(getActivity(), "Write external permission denied", Toast.LENGTH_SHORT).show();
            enableRunTimePermisstion();
        }
    }


    public void saveToInternalCache() {
        String userName = userName2.getText().toString();
        File path = getActivity().getCacheDir();
        File file = new File(path, "dataInternal.txt");
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(userName.getBytes());
            Toast.makeText(getActivity(), "Data stored successfully" + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            Log.e("IOException", e.toString());
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                Log.e("IOException", e.toString());
            }
        }


    }

    public void saveToExternalCache() {
        String userName = userName2.getText().toString();
        File path = getActivity().getExternalCacheDir();
        File file = new File(path, "dataExternal.txt");
        try {
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(userName.getBytes());
            Toast.makeText(getActivity(), "Data stored successfully"
                    + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            Log.e("IOException", e.toString());
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                Log.e("IOException", e.toString());
            }
        }

    }

}

简短的回答是,它取决于您正在编写的外部存储中的 位置 以及您如何获取路径。每个应用程序都可以访问自己的 "private" 外部存储和外部缓存区域,无需特殊许可。您分别通过 Context.getExternalFilesDir()Context.getExternalCacheDir() 访问路径。

另一方面,如果您想写入外部存储中的任何其他位置,例如通过调用 Environment.getExternalStorageDirectory() 获取的路径,则需要持有 WRITE_EXTERNAL_STORAGE 权限.尽管如此,当您开始使用辅助外部存储时,仍然存在一些奇怪的限制。