Descripción del método de permiso de Android 6

Estoy intentando tomar una imagen de la galería y fijarla a una visión de la imagen pero en androide 6 hay algunos problemas del permiso. A continuación se muestra el método para solicitar el permiso. ¿Debería pedir almacenamiento externo de lectura o escribir almacenamiento externo?

Esto es lo que he hecho hasta ahora:

private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1; public void getPermissionToReadExternalStorage() { if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (shouldShowRequestPermissionRationale( Manifest.permission.READ_EXTERNAL_STORAGE)) { requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_CONTACTS_PERMISSIONS_REQUEST); }}} @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults){ // Make sure it's our original READ_CONTACTS request if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(getActivity(), "Read Contacts permission granted", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getActivity(), "Read Contacts permission denied", Toast.LENGTH_SHORT).show(); } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } 

Ahora mi en el oyente del tecleo para escoger datos de la galería:

  pro.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); if (android.os.Build.VERSION.SDK_INT >= 23) { getPermissionToReadExternalStorage(); if (getPermissionToReadExternalStorage () this???? <==) startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0); } else { startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0); }} }); return v; } 

Ahora quiero obtener el resultado del método getPermissionToReadExternalStorage() para que pueda iniciar la Actividad para la galería de picking para Android 6. ¿Cómo puedo obtener el resultado de la clase void? Y otra cosa es que tengo que escribir el método de cada permiso de mi aplicación pide?

Así que he reescrito completamente el código para solicitar permisos. Ahora admite solicitar varios permisos y ejecutar código con el resultado adecuado. También funciona con dispositivos preMarshmallow, por lo que no tiene que comprobar y copiar el código en ese caso.

En primer lugar, cree una clase de actividad con este código (puede ampliar cualquier rey de actividad que necesite, por ejemplo, AppCompatActivity):

 public abstract class PermissionActivity extends AppCompatActivity { private final ArrayList<PermissionListener> permissionListeners = new ArrayList<>(); @SuppressWarnings("unused") public void requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) { requestPermissions(requestCode, requestPermissions, null, permissionListener); } @SuppressWarnings("unused") public void requestPermissions(final int requestCode, String[] requestPermissions, String message, final PermissionListener permissionListener) { final int[] grantResults = new int[requestPermissions.length]; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ArrayList<String> list_notGranted = new ArrayList<>(); for (String requestPermission : requestPermissions) if (ContextCompat.checkSelfPermission(this, requestPermission) != PackageManager.PERMISSION_GRANTED) list_notGranted.add(requestPermission); if (list_notGranted.size() > 0) { permissionListeners.add(permissionListener); requestPermissions = list_notGranted.toArray(new String[list_notGranted.size()]); if (message != null) { boolean shouldShowRequestPermissionRationale = false; for (String permission : requestPermissions) if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { shouldShowRequestPermissionRationale = true; break; } if (shouldShowRequestPermissionRationale) { final String[] f_requestPermissions = requestPermissions; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(message); DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { @TargetApi(Build.VERSION_CODES.M) @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_POSITIVE: PermissionActivity.super.requestPermissions(f_requestPermissions, requestCode); break; default: for (int i = 0; i < grantResults.length; i++) grantResults[i] = PackageManager.PERMISSION_DENIED; if (permissionListener != null) permissionListener.onResult(requestCode, f_requestPermissions, grantResults); break; } } }; builder.setPositiveButton("OK", onClickListener); builder.setNegativeButton("Cancel", onClickListener); builder.show(); } else { super.requestPermissions(requestPermissions, requestCode); } } else { super.requestPermissions(requestPermissions, requestCode); } } else { for (int i = 0; i < grantResults.length; i++) grantResults[i] = PackageManager.PERMISSION_GRANTED; if (permissionListener != null) permissionListener.onResult(requestCode, requestPermissions, grantResults); } } else { if (permissionListener != null) { for (int i = 0; i < grantResults.length; i++) grantResults[i] = PackageManager.PERMISSION_GRANTED; permissionListener.onResult(requestCode, requestPermissions, grantResults); } } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { for (Iterator<PermissionListener> it = permissionListeners.iterator(); it.hasNext(); ) { PermissionListener permissionListener = it.next(); if (permissionListener.onResult(requestCode, permissions, grantResults)) { it.remove(); } } } public interface PermissionListener { boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults); } } 

Si desea solicitar permisos de Fragmentos, agregue esta clase:

 public class PermissionFragment extends Fragment { @SuppressWarnings("unused") public void requestPermissions(int requestCode, String[] requestPermissions, PermissionActivity.PermissionListener permissionListener) { requestPermissions(requestCode, requestPermissions, null, permissionListener); } @SuppressWarnings("unused") public void requestPermissions(final int requestCode, String[] requestPermissions, String message, PermissionActivity.PermissionListener permissionListener) { ((PermissionActivity) getActivity()).requestPermissions(requestCode, requestPermissions, message, permissionListener); } } 

Sus actividades y fragmentos deben extender estas clases en lugar de las estándar.

Ahora está listo para solicitar los permisos llamando a un método:

 requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) 

Si se requiere el permiso para que la aplicación funcione, debe llamar a este método y especificar el mensaje diciendo por qué se requiere el permiso.

 requestPermissions(int requestCode, String[] requestPermissions, String message, PermissionListener permissionListener) 

NO MISSCALL EL MÉTODO DEFAULT, QUE ES

 // DON'T USE THIS ONE! requestPermissions(String[] requestPermissions, int requestCode) // DON'T USE THIS ONE! 

Aquí está el ejemplo de los contactos que solicitan:

 private void requestAndLoadContacts() { String[] permissions = new String[]{Manifest.permission.READ_CONTACTS}; requestPermissions(REQUEST_PERMISSIONS_CONTACTS, permissions, "Read contacts permission is required for the app to work!", new PermissionListener() { @Override public boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults) { // Check if the requestCode is ours if (requestCode == REQUEST_PERMISSIONS_CONTACTS) { // Check if the permission is correct and is granted if (requestPermissions[0].equals(Manifest.permission.READ_CONTACTS) && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted // Calling a method to actually load the contacts loadContacts(); } else { // Permission not granted Toast.makeText(MainActivity.this, "Access denied!", Toast.LENGTH_SHORT).show(); } return true; } return false; } }); } 

Nota: cuando implementa el PermissionListener, no olvide devolver true cuando el requestCode es el correcto , de lo contrario el PermissionListener no se eliminará de la ArrayList y lo más probable es obtener una pequeña pérdida de memoria.

EDITAR

He reescrito el código y publicado en otra respuesta.

Respuesta antigua:

Sí, usted tiene que comprobar y pedir permiso cada vez.

Normalmente escribo el código de esta manera:

 private int requestPermissionCode; private Runnable requestPermissionRunnable; private void runPermissionCode(String requestPermission, int requestCode, Runnable codeToRun) { if (android.os.Build.VERSION.SDK_INT >= 23) { if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { requestPermissionCode = requestCode; requestPermissionRunnable = codeToRun; requestPermissions(new String[]{requestPermission}, requestCode); } } else { codeToRun.run(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { if (requestCode == requestPermissionCode) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestPermissionRunnable != null) requestPermissionRunnable.run(); } else { Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show(); } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } 

Y ejecutarlo de esta manera:

  runPermissionCode(Manifest.permission.READ_EXTERNAL_STORAGE, READ_CONTACTS_PERMISSIONS_REQUEST, new Runnable() { @Override public void run() { // your code here } }); 

Estoy seguro de que no es la mejor manera, pero al menos da la posibilidad de pedir permiso y hacer las acciones más fáciles.

Inicialice su permiso

 private static final int INITIAL_REQUEST = 1337; private static final int GET_ACCOUNTS = INITIAL_REQUEST+2; private static final int LOCATION_REQUEST =INITIAL_REQUEST+3; private static final String[] INITIAL_PERMS = { Manifest.permission.GET_ACCOUNTS, Manifest.permission.INTERNET, Manifest.permission.ACCESS_FINE_LOCATION }; 

Buscar dispositivo y solicitar permisos

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!canAccessAccounts()|| !canAccessLocation() ||!canAccessInternet()) { requestPermissions(INITIAL_PERMS, INITIAL_REQUEST); } } 

El permiso de verificación se otorga o no

 private boolean canAccessAccounts() { return (hasPermission(Manifest.permission.GET_ACCOUNTS)); } private boolean canAccessLocation() { return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)); } private boolean canAccessInternet() { return (hasPermission(Manifest.permission.INTERNET)); } private boolean hasPermission(String perm) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm)); } return (true); } 

Permisos de actualización y método Check para los permisos onRequestPermissionsResult

  void UpdatePermissions(){ canAccessInternet(); canAccessLocation(); canAccessInternet(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { UpdatePermissions(); switch(requestCode) { case GET_ACCOUNTS: if (canAccessAccounts()) { } else { } break; case LOCATION_REQUEST: if (canAccessLocation()) { } else { } break; case INITIAL_REQUEST: if(canAccessInternet()){ }else { } break; } } 
  • ¿Cómo implemento permisos de tiempo de ejecución de Android 6.0 en una aplicación existente?
  • Permiso de tiempo de ejecución al inicio
  • ¿Cómo comprobar el permiso múltiple en una sola solicitud en Android M?
  • Espresso - haga clic en el botón del diálogo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.