¿Permiso de solicitud de malvavisco de Android?

Actualmente estoy trabajando en una aplicación que requiere varios permisos “peligrosos”. Así que intenté agregar “pedir permiso” como se requiere en Android Marshmallow (Nivel API 23), pero no pude encontrar cómo hacerlo.

¿Cómo puedo solicitar permiso usando un nuevo modelo de permiso en mi aplicación?

Abra un cuadro de 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 de la siguiente manera:

 @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 usando para verificar si mi aplicación tiene permiso y luego solicitarla si no tiene permiso. Entonces, en mi código principal desde donde quiero verificar, escriba lo 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 anular 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 información: http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html

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

https://github.com/googlesamples/easypermissions

Función que trata de verificar 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 encoding 🙂

Comenzando en Android Marshmallow, necesitamos solicitar al usuario permisos específicos. También podemos verificar el código si el permiso ya está dado. Aquí hay una lista de permisos comúnmente necesarios:

  • 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.SENSORES

    • 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í hay un código de muestra para verificar los permisos:

 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); } } 

Mi clase para solicitar permisos de tiempo de ejecución

 public class RequestPermissionHandler { private Activity mActivity; private RequestPermissionListener mRequestPermissionListener; private int mRequestCode; public void requestPermission(Activity activity, @NonNull String[] permissions, int requestCode, RequestPermissionListener listener) { mActivity = activity; mRequestCode = requestCode; mRequestPermissionListener = listener; if (!needRequestRuntimePermissions()) { mRequestPermissionListener.onSuccess(); return; } requestUnGrantedPermissions(permissions, requestCode); } private boolean needRequestRuntimePermissions() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } private void requestUnGrantedPermissions(String[] permissions, int requestCode) { String[] unGrantedPermissions = findUnGrantedPermissions(permissions); if (unGrantedPermissions.length == 0) { mRequestPermissionListener.onSuccess(); return; } ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode); } private boolean isPermissionGranted(String permission) { return ActivityCompat.checkSelfPermission(mActivity, permission) == PackageManager.PERMISSION_GRANTED; } private String[] findUnGrantedPermissions(String[] permissions) { List unGrantedPermissionList = new ArrayList<>(); for (String permission : permissions) { if (!isPermissionGranted(permission)) { unGrantedPermissionList.add(permission); } } return unGrantedPermissionList.toArray(new String[0]); } public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == mRequestCode) { if (grantResults.length > 0) { for (int grantResult : grantResults) { if (grantResult != PackageManager.PERMISSION_GRANTED) { mRequestPermissionListener.onFailed(); return; } } mRequestPermissionListener.onSuccess(); } else { mRequestPermissionListener.onFailed(); } } } public interface RequestPermissionListener { void onSuccess(); void onFailed(); } } 

Usando en Activity como

 public class MainActivity extends AppCompatActivity { private RequestPermissionHandler mRequestPermissionHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRequestPermissionHandler = new RequestPermissionHandler(); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handleButtonClicked(); } }); } private void handleButtonClicked(){ mRequestPermissionHandler.requestPermission(this, new String[] { Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE }, 123, new RequestPermissionHandler.RequestPermissionListener() { @Override public void onSuccess() { Toast.makeText(MainActivity.this, "request permission success", Toast.LENGTH_SHORT).show(); } @Override public void onFailed() { Toast.makeText(MainActivity.this, "request permission failed", Toast.LENGTH_SHORT).show(); } }); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); mRequestPermissionHandler.onRequestPermissionsResult(requestCode, permissions, grantResults); } } 

enter image description here

Proyecto de demostración en Github

========

MÁS

He creado una base LIRARIA sobre esta idea, pero admite más funciones como mostrar justificación, manejar No preguntar de nuevo. Verifíquelo si es posible

Android-M ie, API 23 introdujo permisos de tiempo de ejecución para reducir fallas de seguridad en dispositivos 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 la aplicación, debe obtenerlo solicitando el diálogo de permiso que mencionaste en tu consulta.

Por lo tanto, compruebe antes de la acción, es decir, compruebe que tiene permiso para acceder al enlace del recurso y si su aplicación no tiene ese permiso en particular, puede solicitar el enlace de permiso y manejar la respuesta de solicitud de permisos como se muestra 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 pasar por cambios de comportamiento si planeas trabajar con nuevas versiones para evitar cerrar la fuerza 🙂

Mejores prácticas de permisos.

Puede acceder a la aplicación de muestra oficial aquí .

Desde Android Marshmallow (API 23) y superior, de forma predeterminada, todos los permisos peligrosos (según el documento oficial oficial del documento ) deshabilitados. Después de la instalación cuando la aplicación se abre por primera vez, debe otorgar el permiso en tiempo de ejecución.

Lo logré 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); } } } 

EN tu 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 de Fragmento base. Solo solicito permisos de un fragmento, pero podría refactorizarlo 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 debes usar:

  • hasPermissionOrWillAsk – Use esto para ver si un usuario que no quiere que se le vuelva a pedir permiso lo niega y niega. Esto es útil para deshabilitar la IU cuando el usuario ha dado su respuesta final sobre NO querer una función.

  • runNowOrAskForPermissionsFirst: use esto para ejecutar algún código que requiera permisos. Si el usuario ya ha otorgado permiso, el código se ejecutará inmediatamente. De lo contrario, el código se ejecutará más adelante si el usuario otorga el permiso. O no en absoluto. Es bueno porque especifica el código en un solo lugar.

Aquí hay 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 esté un poco simplificado, ya que también debe verificar si los Servicios de localización están habilitados en el dispositivo. (Eso es diferente de los permisos). Además, solo admite un permiso a la vez, pero sería fácil de modificar si lo necesita para admitir más de uno a la vez.

Puede ser una manera más limpia. Agregue todos sus permisos en una matriz 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 permiso, cree el método para cada permiso

 @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)); } 

Llamar a este método en onCreate

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

Ahora anula 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 gestionar el permiso de tiempo de ejecución, google ha proporcionado un proyecto de biblioteca. Puede consultar esto desde aquí https://github.com/googlesamples/easypermissions

EasyPermissions se instala agregando la siguiente dependencia a su 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 list) { // Some permissions have been granted // ... } @Override public void onPermissionsDenied(int requestCode, List list) { // Some permissions have been denied // ... } } 

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

Para permisos múltiples a la vez, puede usar esto. Este trabajo para mí … Tengo otra solución. si le das a tu targetSdkVersion abajo 22, me funciona. y su comportamiento es similar a obtener permiso de manifest.xml. Probado y funciona para mí.

 final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; private void insertDummyContactWrapper() { List permissionsNeeded = new ArrayList(); final List permissionsList = new ArrayList(); 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 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 perms = new HashMap(); // 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. Verifique 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 usar en caso de que se necesiten permisos cuando un servicio en segundo plano necesita permiso. Aunque una limitación de la biblioteca es que no se puede utilizar para determinar si los permisos se otorgan actualmente a la aplicación o no. Siempre le pregunta al usuario si la aplicación aún no los tiene.

Pruébalo ya que hace la vida más simple: Permisos de Android

Prueba esto

Esta es la forma más sencilla de pedir permiso en la versión de Marshmallow.

  if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED&&ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { //TO do here if permission is granted by user } else { //ask for permission if user didnot given if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION}, 0); } } 

Nota: – No se olvide de agregar este mismo permiso en el archivo de manifiesto también

    

Segundo método ¿ Se concede o no el código para verificar el permiso?

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

Y anula el método

 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case 1: { if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) { // grantResult[0] means it will check for the first postion permission which is READ_EXTERNAL_STORAGE // grantResult[1] means it will check for the Second postion permission which is CAMERA Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show(); } else Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show(); return; } } } 

Este código a continuación funciona perfectamente. Lo estoy explicando con la ayuda de un ejemplo.

En mi caso, puse los controles de permisos por separado en una clase de utilidad y pasé los permisos específicos que necesito verificar de las clases apropiadas. Esto permitió reutilizar el archivo de verificación de permiso de toda la aplicación.

La parte del código siguiente muestra la llamada a la función. En este caso, solicito el permiso android.Manifest.permission.READ_EXTERNAL_STORAGE .

 //the below call is from a fragment @OnClick(R.id.button)//butterknife implementation public void attachPressed() { if (PermissionUtils.hasThisPermission(getContext(), android.Manifest.permission.READ_EXTERNAL_STORAGE)) { onAttachPressed(); } else { PermissionUtils.isPermissionRequestNeeded(getActivity(), this, android.Manifest.permission.READ_EXTERNAL_STORAGE, PermissionUtils.REQUEST_GROUP_STORAGE); } } 

En el caso anterior, el permiso se verifica si está permitido el onAttachPressed(); la función se llama más, verificamos el permiso de solicitud.

El siguiente es el código presente en la clase util en mi caso PermissionUtils

 public final class PermissionUtils { public static final int REQUEST_GROUP_STORAGE = 1508; private PermissionUtils() { } public static boolean hasThisPermission(Context context, String permission) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED; } else { return true; } } public static boolean isPermissionRequestNeeded(Activity activity, Fragment fragment, String permission, int requestCode) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasThisPermission(activity, permission)) { final String[] permissions = new String[]{permission}; if (fragment == null) { activity.requestPermissions(permissions, requestCode); } else { fragment.requestPermissions(permissions, requestCode); } return true; } return false; } } 

Y después de la solicitud, si desea llamar a la función desde onRequestPermissionsResult o de lo contrario tendrá que presionar el botón nuevamente para la llamada a la función.

Así que solo llámalo desde onRequestPermissionsResult

 //the below call is from a fragment @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == PermissionUtils.REQUEST_GROUP_STORAGE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { onAttachPressed(); } else { Log.e("value", "Permission Denied, You cannot use local drive ."); } } 

Una forma simple de pedir permiso evitando escribir un montón de código,

https://github.com/sachinvarma/EasyPermission

Cómo agregar :

 repositories { maven { url "https://jitpack.io" } } implementation 'com.github.sachinvarma:EasyPermission:1.0.1' 

Cómo pedir permiso:

  List permission = new ArrayList<>(); permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE); permission.add(EasyPermissionList.ACCESS_FINE_LOCATION); new EasyPermissionInit(MainActivity.this, permission); 

Esperando que sea útil para alguien.

  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); } 

Puedes usar mi biblioteca – NoPermission (Es solo una clase)

compile 'ru.alexbykov:nopermission:1.1.1'

Muestra

 PermissionHelper permissionHelper = new PermissionHelper(this); //don't use getActivity in fragment! permissionHelper.check(Manifest.permission.READ_CONTACTS) .onSuccess(this::onSuccess) .onDenied(this::onDenied) .onNeverAskAgain(this::onNeverAskAgain) .run(); 

onRequestPermissionResult:

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

Creo que es más conveniente que EasyPermissions de Google.

Yo uso la biblioteca de la biblioteca RxPermission para pedir permiso. Porque es un código largo que tenemos que escribir para pedir permiso.

 RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance // Must be done during an initialization phase like onCreate rxPermissions .request(Manifest.permission.CAMERA) .subscribe(granted -> { if (granted) { // Always true pre-M // I can control the camera now } else { // Oups permission denied } }); 

Agregue estas dependencias en su build.gradle

 allprojects { repositories { ... maven { url 'https://jitpack.io' } } } dependencies { implementation 'com.github.tbruyelle:rxpermissions:0.10.1' implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' } 

Permiso de tiempo de ejecución en cualquier lugar de la aplicación Aquí hay un ejemplo

 use dependency maven { url 'https://jitpack.io' } dependencies { implementation 'com.github.irshadsparky:PermissionLib:master-SNAPSHOT' } 

y llame al código así:

 PermissionHelper.requestCamera(new PermissionHelper.OnPermissionGrantedListener() { @Override public void onPermissionGranted() { } }); 

puedes encontrar más Github