Android marshmallow solicitud de permiso?

Actualmente estoy trabajando en una aplicación que requiere varios permisos "peligrosos". Así que traté de agregar "pedir permiso" como se requiere en Android Marshmallow (Nivel API 23), pero no pude encontrar la forma de hacerlo.

¿Cómo puedo pedir permiso usando el nuevo modelo de permiso en mi aplicación?

Abra un diálogo con el siguiente código:

ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1); 

Obtenga el resultado de la actividad como a continuación:

 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case 1: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show(); } return; } // other 'case' lines to check for other // permissions this app might request } } 

Más información: https://developer.android.com/training/permissions/requesting.html

Esta estructura que estoy utilizando para comprobar si mi aplicación tiene permiso y que solicitar si no tiene permiso. Así que en mi código principal de donde quiero comprobar escribir siguiente:

 int MyVersion = Build.VERSION.SDK_INT; if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { if (!checkIfAlreadyhavePermission()) { requestForSpecificPermission(); } } 

El módulo checkIfAlreadyhavePermission () se implementa como:

 private boolean checkIfAlreadyhavePermission() { int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS); if (result == PackageManager.PERMISSION_GRANTED) { return true; } else { return false; } } 

El módulo requestForSpecificPermission () se implementa como:

 private void requestForSpecificPermission() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101); } 

Y Anulación en Actividad:

 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case 101: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //granted } else { //not granted } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } 

Consulte este enlace para obtener más detalles: http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html

A partir de android marshmallow tenemos que solicitar al usuario permisos específicos, también podemos comprobar a través de código si el permiso ya se da. Echa un vistazo a la lista de permisos necesarios en la mayoría de los casos

Android.permission-group.CALENDAR android.permission.READ_CALENDAR android.permission.WRITE_CALENDAR

Android.permission-group.CAMERA android.permission.CAMERA

Android.permission-group.CONTACTS android.permission.READ_CONTACTS android.permission.WRITE_CONTACTS android.permission.GET_ACCOUNTS

Android.permission-group.LOCATION android.permission.ACCESS_FINE_LOCATION android.permission.ACCESS_COARSE_LOCATION

Android.permission-group.MICROPHONE android.permission.RECORD_AUDIO

Android.permission-group.PHONE android.permission.READ_PHONE_STATE android.permission.CALL_PHONE android.permission.READ_CALL_LOG android.permission.WRITE_CALL_LOG android.permission.ADD_VOICEMAIL android.permission.USE_SIP android.permission.PROCESS_OUTGOING_CALLS

Android.permission-group.SENSORS android.permission.BODY_SENSORS

Android.permission-group.SMS android.permission.SEND_SMS android.permission.RECEIVE_SMS android.permission.READ_SMS android.permission.RECEIVE_WAP_PUSH android.permission.RECEIVE_MMS android.permission.READ_CELL_BROADCASTS

Android.permission-group.STORAGE android.permission.READ_EXTERNAL_STORAGE android.permission.WRITE_EXTERNAL_STORAGE

Aquí es una muestra si necesitamos comprobar si hay algún permiso

 if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) { AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context); alertBuilder.setCancelable(true); alertBuilder.setMessage("Write calendar permission is necessary to write event!!!"); alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR); } }); } else { ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR); } } 

Android-M es decir, la API 23 introdujo permisos de tiempo de ejecución para reducir las fallas de seguridad en el dispositivo android, donde los usuarios ahora pueden administrar directamente los permisos de la aplicación en runtime.so si el usuario niega un permiso particular de su aplicación que tiene que obtener pidiendo el diálogo de permiso Que mencionaste en tu consulta.

Por lo tanto, compruebe antes de la acción, por ejemplo, compruebe que tiene permiso para acceder al enlace de recursos y si su aplicación no tiene ese permiso en particular, puede solicitar el enlace de permisos y manejar la respuesta de solicitud de permisos como a continuación.

 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } // other 'case' lines to check for other // permissions this app might request } } 

Así que finalmente, es una buena práctica para pasar por cambios de comportamiento si usted está planeando trabajar con nuevas versiones para evitar la fuerza se cierra 🙂

Permisos Mejores Prácticas.

Puede descargar la aplicación de muestra oficial aquí .

He utilizado este envoltorio (recomendado) escrito por los desarrolladores de google. Su súper fácil de usar.

https://github.com/googlesamples/easypermissions

Función que trata de la comprobación y pedir permiso si es necesario

 public void locationAndContactsTask() { String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS }; if (EasyPermissions.hasPermissions(this, perms)) { // Have permissions, do the thing! Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show(); } else { // Ask for both permissions EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts), RC_LOCATION_CONTACTS_PERM, perms); } } 

Feliz codificación

Desde Android Marshmallow (API 23) y por defecto, por defecto, todos los permisos peligrosos (según documento oficial doc ) están deshabilitados. Después de la instalación cuando la aplicación está abierta por primera vez, debe conceder permiso en Run Time.

He logrado esto de la siguiente manera:

 public class MarshMallowPermission { public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_GALLERY = 0; public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_CAMERA = 1; public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE = 2; public static final int CAMERA_PERMISSION_REQUEST_CODE = 3; public static final int LOCATION_PERMISSION_REQUEST_CODE = 4; Activity activity; Context mContext; public MarshMallowPermission(Activity activity) { this.activity = activity; this.mContext = activity; } public boolean checkPermissionForExternalStorage(){ int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (result == PackageManager.PERMISSION_GRANTED){ return true; } else { return false; } } public boolean checkPermissionForCamera(){ int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA); if (result == PackageManager.PERMISSION_GRANTED){ return true; } else { return false; } } public boolean checkLocationPermission(){ int result = ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION); if (result == PackageManager.PERMISSION_GRANTED){ return true; } else { return false; } } public void requestPermissionForExternalStorage(int requestCode){ if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){ Toast.makeText(mContext.getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); } else { ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode); } } public void requestPermissionForCamera(){ if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){ Toast.makeText(mContext.getApplicationContext(), "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); } else { ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE); } } public void requestPermissionForLocation(){ if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)){ Toast.makeText(mContext.getApplicationContext(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show(); } else { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } } } 

IN Su clase de actividad:

  public class MainActivity extends AppCompatActivity{ private MarshMallowPermission marshMallowPermission; @Override protected void onCreate(Bundle savedInstanceState) { Log.d("NavHome", "Oncreate_nav"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); marshMallowPermission = new MarshMallowPermission(MainActivity.this); if (!marshMallowPermission.checkPermissionForExternalStorage()) { marshMallowPermission.requestPermissionForExternalStorage(MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //permission granted successfully } else { //permission denied } break; } } } 

Estoy usando esto como una clase base de Fragmento. Sólo pido permisos de un fragmento, pero se puede refactorizar y hacer una versión de actividad similar.

 public class BaseFragment extends Fragment { private static final int PERMISSION_REQUEST_BLOCK_INTERNAL = 555; private static final String PERMISSION_SHARED_PREFERENCES = "permissions"; @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_REQUEST_BLOCK_INTERNAL) { boolean allPermissionsGranted = true; for (int iGranting : grantResults) { if (iGranting != PermissionChecker.PERMISSION_GRANTED) { allPermissionsGranted = false; break; } } if (allPermissionsGranted && permissionBlock != null) { permissionBlock.run(); } permissionBlock = null; } } public void runNowOrAskForPermissionsFirst(String permission, Runnable block) { if (hasPermission(permission)) { block.run(); } else if (!hasPermissionOrWillAsk(permission)) { permissionBlock = block; askForPermission(permission, PERMISSION_REQUEST_BLOCK_INTERNAL); } } public boolean hasPermissionOrWillAsk(String permission) { boolean hasPermission = hasPermission(permission); boolean hasAsked = hasPreviouslyAskedForPermission(permission); boolean shouldExplain = shouldShowRequestPermissionRationale(permission); return hasPermission || (hasAsked && !shouldExplain); } private boolean hasPermission(String permission) { return (ContextCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED); } private boolean hasPreviouslyAskedForPermission(String permission) { SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE); return prefs.getBoolean(permission, false); } private void askForPermission(String permission, int requestCode) { SharedPreferences.Editor editor = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit(); editor.putBoolean(permission, true); editor.apply(); requestPermissions(new String[] { permission }, requestCode); } } 

Hay dos métodos clave que debe usar:

  • HasPermissionOrWillAsk – Use esto para ver si un permiso ha sido solicitado y lo niega por un usuario que no quiere que se le pregunte de nuevo. Esto es útil para deshabilitar la interfaz de usuario cuando el usuario ha dado su respuesta final sobre NO querer una característica.

  • RunNowOrAskForPermissionsFirst – Usa esto para ejecutar algún código que requiera permisos. Si el usuario ya ha concedido permiso, el código se ejecutará inmediatamente. De lo contrario, el código se ejecutará más tarde si el usuario concede permiso. O no en absoluto. Es bueno porque especificas el código en un solo lugar.

He aquí un ejemplo:

 mFragment.runNowOrAskForPermissionsFirst(Manifest.permission.ACCESS_FINE_LOCATION, new Runnable() { @Override public void run() { ...do something if we have permission... } }); 

Feliz de recibir comentarios sobre esto. No es que este ejemplo específico sea un poco simplificado, ya que también debe comprobar si los Servicios de ubicación están habilitados en el dispositivo. (Es diferente de los permisos.) Además, sólo admite un permiso a la vez, pero sería sencillo modificarlo si lo necesita para admitir más de uno a la vez.

Puede ser una manera más limpia. Agrega todos tus permisos en un array como

 private static final String[] INITIAL_PERMS={ android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION }; private static final int INITIAL_REQUEST=1337; 

Cualquiera que sea su permision es crear un método para cada permision

 @RequiresApi(api = Build.VERSION_CODES.M) private boolean canAccessFineLocation() { return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)); } @RequiresApi(api = Build.VERSION_CODES.M) private boolean canAccessCoarseLocation() { return(hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION)); } @RequiresApi(api = Build.VERSION_CODES.M) private boolean hasPermission(String perm) { return(PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm)); } 

Llame a este método en onCreate

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

Ahora reemplace onRequestPermissionsResult

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if(requestCode == INITIAL_REQUEST){ if (canAccessFineLocation() && canAccessCoarseLocation()) { //call your method } else { //show Toast or alert that this permissions is neccessary } } } 

Para obtener permiso múltiple a la vez, puede utilizarlo. Este trabajo para mí .. Tengo otra solución. Si usted da su targetSdkVersion abajo 22 que trabaja para mí. Y su comportamiento es como obtener permiso de manifest.xml. Probado y funciona para mí.

 final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; private void insertDummyContactWrapper() { List<String> permissionsNeeded = new ArrayList<String>(); final List<String> permissionsList = new ArrayList<String>(); if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) permissionsNeeded.add("GPS"); if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS)) permissionsNeeded.add("Read Contacts"); if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS)) permissionsNeeded.add("Write Contacts"); if (permissionsList.size() > 0) { if (permissionsNeeded.size() > 0) { // Need Rationale String message = "You need to grant access to " + permissionsNeeded.get(0); for (int i = 1; i < permissionsNeeded.size(); i++) message = message + ", " + permissionsNeeded.get(i); showMessageOKCancel(message, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); } }); return; } requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); return; } insertDummyContact(); } private boolean addPermission(List<String> permissionsList, String permission) { if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { permissionsList.add(permission); // Check for Rationale Option if (!shouldShowRequestPermissionRationale(permission)) return false; } return true; } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: { Map<String, Integer> perms = new HashMap<String, Integer>(); // Initial perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED); // Fill with results for (int i = 0; i < permissions.length; i++) perms.put(permissions[i], grantResults[i]); // Check for ACCESS_FINE_LOCATION if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) { // All Permissions Granted insertDummyContact(); } else { // Permission Denied Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT) .show(); } } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } 

Para más detalles. Revise el enlace abajo

https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

Hay una buena biblioteca que se puede utilizar en caso de que los permisos se deben preguntar cuando el permiso es necesario por un servicio de fondo. Aunque una limitación de la biblioteca es que no se puede utilizar para determinar si los permisos se dan actualmente a la aplicación o no. Siempre pregunta al usuario si la aplicación ya no los tiene.

Déle una oportunidad, ya que hace la vida más simple: Permisos de Android

Para manejar el permiso de tiempo de ejecución, google ha proporcionado un proyecto de biblioteca. Puedes consultar esto desde aquí https://github.com/googlesamples/easypermissions

EasyPermissions se instala agregando la siguiente dependencia al archivo build.gradle:

 dependencies { compile 'pub.devrel:easypermissions:0.3.0' } 

Para comenzar a usar EasyPermissions, haga que su Actividad (o Fragmento) anule el método onRequestPermissionsResult:

 public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } @Override public void onPermissionsGranted(int requestCode, List<String> list) { // Some permissions have been granted // ... } @Override public void onPermissionsDenied(int requestCode, List<String> list) { // Some permissions have been denied // ... } } 

Aquí obtendrá un ejemplo práctico de cómo funciona esta biblioteca https://github.com/milon87/EasyPermission

  if (CommonMethod.isNetworkAvailable(MainActivity.this)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.CAMERA); if (permissionCheck == PackageManager.PERMISSION_GRANTED) { //showing dialog to select image callFacebook(); Log.e("permission", "granted MarshMallow"); } else { ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}, 1); } } else { Log.e("permission", "Not Required Less than MarshMallow Version"); callFacebook(); } } else { CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this); } 
  • ¿Por qué se agregan automáticamente los permisos a mi AndroidManifest cuando incluye la biblioteca de Google Play Services?
  • Grant Uri permiso para otra actividad
  • Los teléfonos de Redmi no piden permisos de SMS y por lo tanto no leen sms
  • ¿Por qué el proveedor de contenido sin permisos y exportado = true es accesible para cualquier aplicación?
  • Apagado del dispositivo Android - quiere "ShutdownThread-> shutdown ()" no "su reboot -p"
  • Android - "El receptor exportado no requiere permiso" en receptores destinados a recibir de los servicios del sistema
  • Reproductor de música preguntando para escribir permiso de almacenamiento externo?
  • Intención FLAG_GRANT_READ_URI_PERMISSION Uso de FileProvider en Gingerbread
  • ¿Qué pasará con aplicaciones que no se actualizan y que ejecutan código que requiere un permiso que el usuario desautorizado en Android 6.0 Marshmallow
  • La aplicación de Android se bloquea en 6.0 mientras busca permisos con ActivityCompat.requestPermissions
  • Modelo de permiso de Android Marshmallow en OS 4.0 READ_EXTERNAL_STORAGE permiso no siempre concedido
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.