16

I am developing an android app in which it is required to provide permission for Read and write external storage. My requirement is to select a picture from gallery and use it in my app. Everything is working fine except Marshmallow devices. I want to provide permission for Marshmallow. Can anyone help me with this?

Mangesh
  • 5,491
  • 5
  • 48
  • 71
tiger
  • 413
  • 1
  • 5
  • 18

6 Answers6

24

It can be achieved something as following...

public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{

  private static final int REQUEST_WRITE_PERMISSION = 786;

  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {            
        openFilePicker();
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    requestPermission();
  }

  private void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
    } else {
        openFilePicker();
    }
  }
}
User
  • 4,023
  • 4
  • 37
  • 63
  • Somebody down-voted this answer, May I know the reason? I will try to improve. – User Apr 10 '19 at 06:42
  • It is heavily suggested to also include android.Manifest.permission.READ_EXTERNAL_STORAGE in the checks and permission requests. There are certain rare scenarios where WRITE_EXTERNAL_STORAGE is granted but READ_EXTERNAL_STORAGE is denied. – Alex Mar 23 '21 at 17:19
2

Read through Runtime permissions - Android M and its reference project.

Permissions flow has changed requiring the permissions to be asked at runtime, preferably, as and when required. With the same.. permissions have also been categorised into Normal and Dangerous which will also lead to permission groups.

Pararth
  • 8,114
  • 4
  • 34
  • 51
1

For writing a file in storage, First,need to add write permission in manifest.xml,

Then, In Android 6, it contains a permission system for certain tasks. Each application can request the required permission on runtime. So let’s open Activity class add below code for requesting runtime permission.

check your application has a runtime write permission using,

override fun onRequestPermissionsResult(requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray) {

    when(requestCode)  {

        100 -> {
            if (grantResults.size > 0 && permissions[0] == Manifest.permission.WRITE_EXTERNAL_STORAGE) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                
                }
            }

        }
    }

}
1

Check AndroidManifest.xml!!

    <?xml version="1.0" encoding="utf-8"?>
<manifest 
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.yoganetwork">
<!-- Internet Permission -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission 
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission 
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.YogaNetwork">
    <activity android:name=".LoginActivity"></activity>
    <activity android:name=".DashboardActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" 
/>

            <category 
android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".RegisterActivity" />
    <activity android:name=".MainActivity" />
</application>

</manifest>
OneKe
  • 97
  • 8
0

In addition, if you want to ask for multiple permissions. You can do this.

private ArrayList<String> permisos;

private void someMethod()
{
      ..

      verificarPermisos(Manifest.permission.READ_EXTERNAL_STORAGE );
      verificarPermisos(Manifest.permission.ACCESS_FINE_LOCATION );
      verificarPermisos(Manifest.permission.ACCESS_COARSE_LOCATION );
      if (permisos.size()!=0)
      {
         solicitarPermisos(permisos.toArray(new String[permisos.size()]));
      }

      ..

 }


@TargetApi(23)
void verificarPermisos(String permiso){
    if (ContextCompat.checkSelfPermission(this,permiso)
            != PackageManager.PERMISSION_GRANTED) {
        permisos.add(permiso);
        // Should we show an explanation?
        if (shouldShowRequestPermissionRationale(permiso)) {

        }

    }
}

@TargetApi(23)
void solicitarPermisos(String[] permiso){

    requestPermissions(permiso, 1);

}

First, I check if the permission is already granted or not with "verificarPermisos()" method. If they are not granted, I add them to "permisos" arraylist. Finally, the ungranted permissions are resquested passing them in a String[] array format.

Note that you can only request permissions since MashMellow(API 23) or higher. So, if your app is also targetting android versions before MashMellow you could use the "@TargetApi()" annotation and the permission methods only be called when the target is API 23 or higher.
Hope to help, greetings.

Hanako
  • 1,637
  • 1
  • 13
  • 16
0

Checking every situation

if denied - showing Alert dialog to user why we need permission

public static final int STORAGE_PERMISSION_REQUEST_CODE= 1;


    private void askPermissions() {

    int permissionCheckStorage = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE); 

   // we already asked for permisson & Permission granted, call camera intent
    if (permissionCheckStorage == PackageManager.PERMISSION_GRANTED) {

        //do what you want

    } else {

           // if storage request is denied
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("You need to give permission to access storage in order to work this feature.");
            builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            });
            builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();

                    // Show permission request popup
                    ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            STORAGE_PERMISSION_REQUEST_CODE);
                }
            });
            builder.show();

        } //asking permission for first time 
          else {
             // Show permission request popup for the first time
                        ActivityCompat.requestPermissions(AddWorkImageActivity.this,
                                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                STORAGE_PERMISSION_REQUEST_CODE);

                    }

    }
}

Checking Permission Results

 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    switch (requestCode) {
        case STORAGE_PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                // check whether storage permission granted or not.
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //do what you want;
                }
            }
            break;
        default:
            break;
    }
}

you can just copy and paste this code, it works fine. change context(this) & permissions according to you.

Adarsh Vijayan P
  • 2,964
  • 2
  • 16
  • 27