Intent.ACTION_CALL fails on android 6+

3

MY CASE

  • I have this method to make direct call from android:

    public void Llamar(String Numero) {  
        Intent Llamada = new   Intent(Intent.ACTION_CALL).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
        Llamada.setData(Uri.parse("tel:" + Numero));  
        context.startActivity(Llamada);  
    }
    
  • The corresponding permission is activated.

    <uses-permission android:name="android.permission.CALL_PHONE" />  
    
  • THE PROBLEM In terminals with Android less than 6, it works correctly, in terminals with 6 or higher the application stops.

        
    asked by Jorny 14.03.2017 в 04:39
    source

    2 answers

    2

    For applications with OS Android prior to 6.0 it is sufficient to define the permission within your file AndroidManifest.xml :

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

    Require CALL_PHONE permissions on devices running Android 6.0 or later.

    This would be the appropriate way to require permissions to make phone calls in Android 6.0 :

     int permissionCheck = ContextCompat.checkSelfPermission(
                this, Manifest.permission.CALL_PHONE);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            Log.i("Mensaje", "No se tiene permiso para realizar llamadas telefónicas.");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 225);
        } else {
            Log.i("Mensaje", "Se tiene permiso para realizar llamadas!");
        }
    

    To validate the request by API, the following is done:

    final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
    
    ...
    
    
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
            // Se tiene permiso
        }else{
            ActivityCompat.requestPermissions(PrincipalActivity.this,new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CODE_ASK_PERMISSIONS);
            return;
        }
    }else{
        // No se necesita requerir permiso OS menos a 6.0.
    }
    

    In the same activity add the method onRequestPermissionsResult () which is a callback to obtain the result of the request:

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case REQUEST_CODE_ASK_PERMISSIONS:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    // El usuario acepto los permisos.
                     Toast.makeText(this, "Gracias, aceptaste los permisos requeridos para el correcto funcionamiento de esta aplicación.", Toast.LENGTH_SHORT).show();
                }else{
                    // Permiso denegado.
                    Toast.makeText(this, "No se aceptó permisos", Toast.LENGTH_SHORT).show();
                }
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
    
    
      [1]: https://developer.android.com/training/permissions/requesting.html
    
        
    answered by 14.03.2017 / 05:28
    source
    2

    As of Android 6.0 (API 23) there were several changes in this regard, among them, some permissions have been considered as risky , and precisely among them are attempts to telephone calls ( CALL_PHONE ).

    It says the Android documentation :

      

    As of Android 6.0 (API level 23), users grant   Allows apps to run while they are running, not when they install the app.   This approach simplifies the process of installing the app, since the   user does not need to grant permissions when installing or updating the   app It also gives the user more control over the functionality of   the app; for example, a user could choose to provide a   camera app access to this, but not to the location of the device.   The user can revoke the permissions at any time from the   app configuration screen.

         

    System permissions are divided into two categories, normal and risky:

         
    • Normal permissions do not compromise the user's privacy.   direct way If your app has a normal permission in its manifest, the   system grants permission automatically.
    •   
    • The risky permissions   can allow the app to access confidential information of the   user. If your app has a normal permission in its manifest, the   system grants permission automatically. If you have a permit   dangerous, the user must explicitly authorize your app.
    •   

    In all Android versions, your app must declare the permissions   normal and dangerous you need in your manifest, as described   in Declaration of permissions. However, the effect of that statement   is different depending on the system version and the target SDK level   of your app:

         
    • If the device has Android 5.1 or an earlier version, or the level   SDK destination of your app is 22 or lower: If you have a   dangerous permission in your manifest, the user must grant the   permission when installing the app; If you do not grant permission, the system does not   will install the app.
    •   
    • If the device has Android 6.0 or a version   later, and the target SDK level of your app is 23 or one   Subsequent: The permissions must be indicated in the manifest of the   app, and it must request every risky permit it needs while   the app is running. The user can grant or deny each   permission and the app can continue to run with capabilities   limited even when the user rejects a permission request.
    •   

    See list of risky or dangerous permits .

      

    Note : As of Android 6.0 (API level 23), users can revoke permissions from any app at any time,   even if the app is oriented to a lower API level. You must try   your app to verify that it behaves correctly when it does not count   with a necessary permission, regardless of the level of API to which   your app is oriented.

    Request or verify permissions

    Each time you perform an operation that requires a dangerous permit, you should check if the user has granted that permission. If you have not done so, you must request that it be granted.

    Android has documentation in Spanish that explains how to perform these tasks with code snippets.

    You can check it here: How to request permissions at runtime .

    Check for permissions

    // Assume thisActivity is the current activity
    int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.CALL_PHONE);
    

    Request the permissions that are needed

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                    Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
    
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
    
            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
    
        } else {
    
            // No explanation needed, we can request the permission.
    
            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.READ_CONTACTS},
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    
            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
    

    Control the response to the permission request

    @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
        }
    }
    
        
    answered by 14.03.2017 в 04:54