0

I have build sample app for user to write some text and save it on internal storage.

Format TXT or pdf. I have tried on android Kitkat sdk 19 and It's working fine but when I tried on the latest android 9 I got denied could not save the text in internal storage

Edit : I wonder If have to manually create My files folder

What I'm I missing ?

enter image description here

AndroidManifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

MainActivity

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

       mSaveTextBtn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            mText = mResultEt.getText().toString().trim();
            if(mText.isEmpty()){
                Toast.makeText(MainActivity.this, "write text First...", Toast.LENGTH_SHORT).show();
            }
            else{
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                    if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED){
                        String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
                        requestPermissions(permissions,WRITE_EXTERNAL_STORAGE_CODE);
                    }else {
                        saveToTxtFile(mText);
                    }
                }else {
                    saveToTxtFile(mText);
                }
            }

        }
    }); 

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case WRITE_EXTERNAL_STORAGE_CODE: {
            if (grantResults.length > 0 && grantResults[0]
                    == PackageManager.PERMISSION_GRANTED) {
                //permission granted save data
                saveToTxtFile(mText);
            } else {
                //permission denied
                Toast.makeText(this, "Storage Permission required to store", Toast.LENGTH_SHORT).show();
            }
        }
        break;
    }
}

private void saveToTxtFile(String mText){
    //get current time for file name
    String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(System.currentTimeMillis());
    try{
        //path tp storage
        File path = Environment.getExternalStorageDirectory();
        //create folder named "My file"
        File dir = new File( path + "/My Files/");
        dir.mkdirs();
        //file name
        String fileName = "MyFile_" + timestamp + ".txt";

        File file = new File (dir, fileName);

        //used to store characater in file
        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(mText);
        bw.close();

        //show file name and path where file saved
        Toast.makeText(this, fileName+"is saved to\n" +dir, Toast.LENGTH_SHORT).show();

    }catch (Exception e){
        //if anything goes wrong
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}
kashyap
  • 498
  • 1
  • 6
  • 21
Ishak Benaissa
  • 81
  • 1
  • 10
  • Refer to this StackOverflow [answer](https://stackoverflow.com/a/57116787/5180017). I hope you get some idea. – Shashanth Dec 30 '19 at 04:17
  • 1
    stacktrace? exception? – njzk2 Dec 30 '19 at 04:21
  • refere this link to get more idea. https://stackoverflow.com/questions/58379543/cant-create-directory-in-android-10 – kashyap Dec 30 '19 at 04:22
  • I'll try the answer provided it's a good approach and there isn't any error displaying for stacktrace – Ishak Benaissa Dec 30 '19 at 04:23
  • you can use the legacy storage by setting android:requestLegacyExternalStorage=”true” on the application tag inside of AndroidManifest.xml. However, you should implement Scoped Storage in your app as soon as possible becuase on Android 11 Google says it will be required for all apps regardless of targetSdkVersion. https://developer.android.com/about/versions/10/privacy/ – Chirag Rayani Dec 30 '19 at 04:39
  • @ChiragRayani thanks I'm looking for some example to practice with using this Scoped storage I'm not sure how to use it yet – Ishak Benaissa Dec 30 '19 at 04:43
  • @IshakBenaissa I think you are missing point to create file if it does not exist. Kindly first do check whether file exist using `file.exists()` if yes then continue with writing else create file first then write. – Shadow Droid Dec 30 '19 at 09:00
  • `dir.mkdirs();` Do not blindly call mkdirs(). Only call it when the directory does not exist yet. And if you call mkdirs() then check the return value. Do not continue if it returns false. In that case display a Toast() to the user saying so and return. Dont continue as it makes little sense trying to write a file in a non existing directory. – blackapps Dec 30 '19 at 11:04

2 Answers2

2

As suggested both Shashanth and kashyap answers.

This is just a workaround but it works.

I have added

android:requestLegacyExternalStorage="true"

to my <application> element in the AndroidManifest.xml file.

And changed the line

File path = Environment.getExternalStorageDirectory();

to

File path = new File(getExternalFilesDir(null).getAbsolutePath());
Shashanth
  • 4,995
  • 7
  • 41
  • 51
Ishak Benaissa
  • 81
  • 1
  • 10
  • 1
    `android:requestLegacyExternalStorage="true"` That makes only sense for Android 10. And only if you wish to continue using getExternalStorageDirectory(). Do not change two things at once as you will not know which one did it. The Answers you link to are for Android 10. – blackapps Dec 30 '19 at 11:06
1

In your MainActivity you should check if permission is granted or not, then use != operator.

if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        == PackageManager.PERMISSION_GRANTED) {}

this line should be-

if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED){}
Rasel
  • 5,488
  • 3
  • 30
  • 39