Android Device phone call ability

if (((TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE)).getPhoneType()
    == TelephonyManager.PHONE_TYPE_NONE)
{
    // no phone
}

EDIT I'm surprised it comes back PHONE_TYPE_CDMA. Here's another possibility:

if (((TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number()
    == null)
{
    // no phone
}

This will require the READ_PHONE_STATE permission.


Devices do not necessarily need Context.TELEPHONY_SERVICE to make phone calls. Consider what happens if you install Skype:

  • Enter a phone number on the native Dialer/Phone app and press "Call".
  • A popup appears titled "Complete action using" and offering "Dialer" or "Skype" applications (it could list other applications too).

So, I believe Skype would work on a wifi-only device with no phone capabilities (according to Context.TELEPHONY_SERVICE).

I think you were correct with your original idea, but you need to check what applications are registered to handle Intent.ACTION_CALL instead of Intent.ACTION_DIAL, e.g.

Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:5551231234"));
List<ResolveInfo> callAppsList = 
  context.getPackageManager().queryIntentActivities(callIntent, 0);

However, I am not aware of any reliable, forward-proof ways of figuring out if those applications will be able to handle the phone call. Consider these cases:

1) A wifi-only Xoom with Skype installed. It needs a valid wifi connection, and the user must have configured Skype to use their account, otherwise the call won't succeed.

2) A telephony enabled device with no SIM card in, or a SIM card that is locked or has run out. The device thinks it can handle telephony, but the call results in a "Not registered on network" error.

3) A telephony enabled device with no wifi or mobile connection (or because it is in Airplane/Flight mode). The device thinks it can handle telephony, but the call will fail.

There are ways you could detect some of these scenarios (e.g. inspecting getSystemService(Context.TELEPHONY_SERVICE).getSimState()), but I think this would probably lead to fragile code that may break when things change in future. For example, could you always reliably detect which application in the list is the default Dialer/Phone app? What if Android changed the package name for it in a subsequent release.

Hopefully that gave you some useful information - I wanted to show this is more tricky that it might appear at a first glance!


I think a better approach would be to query the PackageManager to detect if Telephony features are even available on the device. A device should only have Telephony features if it has a phone. I tested this on a Nexus 7, which does not have a phone, and it works. I do not have a device with a phone to test the opposite case.

PackageManager pm = getPackageManager();

if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)){
    //has Telephony features.
}

Steve,

Check out TelephonyManager. It has the getPhoneType() function which will return PHONE_TYPE_NONE in your case.