30

I'm trying to programmatically call to a number with following code:

 String number = ("tel:" + numTxt.getText());
 Intent intent = new Intent(Intent.ACTION_CALL);
 intent.setData(Uri.parse(number));
 startActivity(intent);

I've set the permission in the Manifest:

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

I'm working with real device for testing and debugging, it is Nexus 5 with Android M, my compileSdkVersion is 23. I'm getting the following Security Exception:

error: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxxxxxxxxx cmp=com.android.server.telecom/.components.UserCallActivity } from ProcessRecord{cbbd7c1 5228:com.dialerTest.DialerApp/u0a96} (pid=5228, uid=10096) with revoked permission android.permission.CALL_PHONE

I've searched the web and this community for similar Q/A and couldn't find the answer. Any help will be appreciated.

Evgeniy Mishustin
  • 3,343
  • 3
  • 42
  • 81

5 Answers5

28

Permission CALL_PHONE belong to dangerous permission group.
So if your apps target SDK is 23 or higher and your device is running on Android 6.0 or higher, you must request for CALL_PHONE permission while the app is running.

You can use the following code that I copied from http://web.archive.org/web/20160111030837/http://developer.android.com/training/permissions/requesting.html

String number = ("tel:" + numTxt.getText());
mIntent = new Intent(Intent.ACTION_CALL);
mIntent.setData(Uri.parse(number));
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.CALL_PHONE)
    != PackageManager.PERMISSION_GRANTED) {

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.CALL_PHONE},
            MY_PERMISSIONS_REQUEST_CALL_PHONE);

    // MY_PERMISSIONS_REQUEST_CALL_PHONE is an
    // app-defined int constant. The callback method gets the
    // result of the request.
} else {
    //You already have permission
     try {
        startActivity(mIntent); 
    } catch(SecurityException e) {
       e.printStackTrace();
   }
} When your app requests permissions, the system presents a dialog box to the user. When the user responds, the system invokes your app's

onRequestPermissionsResult() method, passing it the user response.

@Override
public void onRequestPermissionsResult(int requestCode,
    String permissions[], int[] grantResults) {
  switch (requestCode) {
    case MY_PERMISSIONS_REQUEST_CALL_PHONE: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            // permission was granted, yay! Do the phone call

        } 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
  }
}
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
18

In android 6.0 (Api lvl 23) we have something called "Runtime Permissions". You have to read about it.

You can find documentation here.

Artur Szymański
  • 1,639
  • 1
  • 19
  • 22
10

You code could works only if you make an ACTION_DIAL, not an ACTION_CALL where you need to request a permission, so if you want to make a call, please follow this example:

MANIFEST:

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

Code:

import static android.Manifest.permission.CALL_PHONE;

Intent i = new Intent(Intent.ACTION_CALL);
i.setData(Uri.parse("tel:0612312312"));
/*
Intent i = new Intent(Intent.ACTION_DIAL);
i.setData(Uri.parse("tel:0612312312"));
if (i.resolveActivity(getPackageManager()) != null) {
      startActivity(i);
}*/
if (ContextCompat.checkSelfPermission(getApplicationContext(), CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
      startActivity(i);
} else {
      requestPermissions(new String[]{CALL_PHONE}, 1);
}
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
-1

in fragment class

Step 1: import static android.Manifest.permission.CALL_PHONE;

step 2:Where your onclick button:

            Intent callIntent = new Intent(Intent.ACTION_CALL);
            callIntent.setData(Uri.parse("tel:" +driver_no ));

            if (ContextCompat.checkSelfPermission(getActivity(), CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
                startActivity(callIntent);
            } else {
                requestPermissions(new String[]{CALL_PHONE}, 1);
            }

[Or] you are using in activity class means change the getActivity to getApplicationContext()

VISALIG
  • 27
  • 4
-1

FYI: If you're targeting Android 11, you need to add an Intent Query element for Intent.ACTION_DIAL in your manifest.

https://developer.android.com/training/basics/intents/package-visibility#intent-signature

airowe
  • 794
  • 2
  • 9
  • 29