Android app can't read external storage files

后端 未结 5 557
遇见更好的自我
遇见更好的自我 2020-12-19 18:52

I\'m creating an app for a private use only... it\'s not so important then, respect your time :P

What I want to make is an app that reads from a database and plays s

相关标签:
5条回答
  • 2020-12-19 19:13

    Here is the code @Nisarg, had to clean it a bit:

    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.media.MediaPlayer;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    import java.io.File;
    
    public class MainActivity extends AppCompatActivity implements OnClickListener {
    
    Button readExcelButton;
    static String TAG = "ExelLog";
    MediaPlayer mpintro;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
            Toast.makeText(this, "Permission checking", Toast.LENGTH_SHORT).show();
            checkPermission();
        }
    
        readExcelButton = (Button) findViewById(R.id.readExcel);
        readExcelButton.setOnClickListener(this);
    
    }
    
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.readExcel:
                String filePath = getExternalFilesDir(null) + "/p0000.mp3";
                File file = new File(filePath);
                file.setReadable(true);
                file.setWritable(true);
    
                if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
                    Toast.makeText(this, "Ext storage not available or read only", Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(this, "Ext storage available", Toast.LENGTH_SHORT).show();
                }
    
                if (file.exists()){
                    Toast.makeText(this, "File found", Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(this, getExternalFilesDir(null) + "/p0000.mp3 - File not found", Toast.LENGTH_LONG).show();
                }
    
                break;
        }
    }
    
    private void checkPermission() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {//Can add more as per requirement
    
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},
                    123);
    
        } else {
    
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 123: {
    
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED)     {
                    //Peform your task here if any
                } else {
    
                    checkPermission();
                }
                return;
            }
        }
    }
    
    public static boolean isExternalStorageReadOnly() {
        String extStorageState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
            return true;
        }
        return false;
    }
    
    public static boolean isExternalStorageAvailable() {
        String extStorageState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
            return true;
        }
        return false;
    }
    

    }

    0 讨论(0)
  • 2020-12-19 19:17

    if your targetSdk is 23 than you have to check permissions like this for marshmallow and above devices

    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
        checkPermission();
    }
    else {
    }
    
    
    private void checkPermission() {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {//Can add more as per requirement
    
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},
                        123);
    
            } else {
    
            }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults)   
       {
        switch (requestCode) {
            case 123: {
    
    
     if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED)     {
       //Peform your task here if any
        } else {
    
            checkPermission();
        }
            return;
        }
    }
    }
    
    0 讨论(0)
  • 2020-12-19 19:19

    Android 9 (API level 28) started to restrict which apps could make the files in their data directories on internal storage world-accessible to other apps. Apps that target Android 9 or higher cannot make the files in their data directories world-accessible. For further info you can check this link.

    Incase you're targeting the API level 28 or higher, to solve your problem you can simply add some tags inside your AndroidManifest.xml. So it should have at least those ones:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
       xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       package="com.your.application">
    
       <!-- These three tags -->
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
       <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
    
       <!-- Add the tag android:requestLegacyExternalStorage="true" in application -->
       <!-- Other tags has been omitted -->
       <application
          android:requestLegacyExternalStorage="true">
       </application>
    
    </manifest>
    

    Now you can check if you are able to read and write:

    File root = new File(Environment.getExternalStorageDirectory() + "/My app folder");
    
    Log.d("Storage: can write", String.valueOf(root.canWrite()));
    Log.d("Storage: can read", String.valueOf(root.canRead()));
    

    The result of both logs should be TRUE.

    0 讨论(0)
  • 2020-12-19 19:30
     MyMediaPlayer=MediaPlayer.create(this,Uri.parse(String.valueOf(Uri.fromFile(f))));
    

    in this MyMediaPlayer is object of MediaPlayer,||ly f is object of file in this we convert to uri first and then uri to string and finally string to uri.

    I have done this because when we take the path of our choise it take /// 3times / but it is needed only 2 times thats why I have done this conversion which help me to take the desired file path.

    try this my friend.

    0 讨论(0)
  • 2020-12-19 19:36

    You also have to have the permission READ_EXTERNAL_STORAGE; Either write or read is not enough when it comes to external storage, as you have to use both

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

    You can also read more about external data writing in the declaration

    The reason you cannot read is because you didn't add that permission. A good rule is if you only need to read, only use read permission. But if you need to write you need the write and the read permission

    EDIT:

    When loading the directory, try this:

    file.setReadable(true);
    file.setWritable(true);
    

    Note: the value 'file' here is for the directory, not each separate file(all though that works fine too)

    From the declaration:

    This permission is enforced starting in API level 19. Before API level 19, this permission is not enforced and all apps still have access to read from external storage.

    If I am correct that means the permission has to be there from API 19 and up, but not before API 19

    0 讨论(0)
提交回复
热议问题