How to detect if device is capable of calling and messaging
Asked Answered
S

6

18

Some devices ie. Galaxy Tablet 10.1 can only send SMS, but cannot call. Some other devices like Asus Transformer don't even have SIM card.

How can I detect if device can makes calls? And how can I detect if device can send SMS?

Syrian answered 15/9, 2011 at 11:0 Comment(0)
O
6

Maybe you can query the PackageManager whether the system contains any component that can respond to ACTION_CALL and ACTION_SENDTO intents? You might need to add the "tel:" and "smsto:" scheme in the URI.

Olden answered 14/11, 2011 at 23:11 Comment(2)
I was thinking about it no longer than 2 days ago, but I haven't had time to try it, test it. Certainly this is the way to do it.Syrian
Tablets do seem to react to ACTION_DIAL and the likes, though. They show a little dialog that gives you the option to add the number to your contacts. So I doubt that this will work.Vortex
Q
28

Using this technic you can test all sorts of things too e.g. compass, is location available

    PackageManager pm = getBaseContext().getPackageManager();
    pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
Quattlebaum answered 15/9, 2011 at 11:7 Comment(4)
It doesn't help with SMS, does it?Syrian
Unfortunately this gives false negatives on some phone devices and emulators.Lengthways
I know this question is quite old but I want to make a clarification about this code in case someone find this answer in the future: this piece of code shows if the device has the ability to use telephony features, but it doesn't mean it can make calls or send SMS right now. For example, if you run this code in a phone without a SIM Card (obviously a device that can't make calls or send SMS) it will return true, despite lack of a SIM Card.Karyokinesis
This won't work on some tablets that are in fact capable of making phone calls.Danieldaniela
O
6

Maybe you can query the PackageManager whether the system contains any component that can respond to ACTION_CALL and ACTION_SENDTO intents? You might need to add the "tel:" and "smsto:" scheme in the URI.

Olden answered 14/11, 2011 at 23:11 Comment(2)
I was thinking about it no longer than 2 days ago, but I haven't had time to try it, test it. Certainly this is the way to do it.Syrian
Tablets do seem to react to ACTION_DIAL and the likes, though. They show a little dialog that gives you the option to add the number to your contacts. So I doubt that this will work.Vortex
P
5

That should do it:

 PackageManager pm = this.getPackageManager();

 if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
     System.out.println("horray");
 } else {
     System.out.println("nope");
 }
Primer answered 15/9, 2011 at 11:12 Comment(4)
It doesn't help with SMS, does it?Syrian
it should actually because SMS does not use a data connection but 2G like telephony as wellPrimer
Yeah, but as I said. Galaxy Tab 10.1 can send sms, but cannot call. So how can I separate those two things?Syrian
This has problems for detecting SMS capability, though. If a device has Google Voice installed, even if it has no telephony capability whatsoever, it can still send SMS. So this approach could give you false negatives. Unless something better exists, it seems to me that the best approach is to just prepare the SMS intent normally, pass it to startActivity(), and catch ActivityNotFoundException. That way if it fails, at least it will fail gracefully and you can display an error message showing why it failed.Baryram
C
2

You can use the below method to check if sms feature is supported or not:

private void sendSms(String theNumber, String theMsg) {
        // TODO Auto-generated method stub
        String SENT = "Message Sent";
        String DELIVERED = "Message Delivered";

        PendingIntent sentPI = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(SENT), 0);
        PendingIntent deliveredPI = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(DELIVERED), 0);

        registerReceiver(new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                // TODO Auto-generated method stub
                switch(getResultCode()){
                case Activity.RESULT_OK:   Toast.makeText(getApplicationContext(), "Message Sent", Toast.LENGTH_SHORT).show();
                                            break;
                case Activity.RESULT_CANCELED: Toast.makeText(getApplicationContext(), "Message Not Sent", Toast.LENGTH_SHORT).show();
                                                break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:  Toast.makeText(getApplicationContext(), "No Service Available", Toast.LENGTH_SHORT).show();
                                                           break;
                }
            }
        }, new IntentFilter(SENT));

        registerReceiver(new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                // TODO Auto-generated method stub
                switch(getResultCode()){
                case Activity.RESULT_OK:   Toast.makeText(getApplicationContext(), "Message Delivered", Toast.LENGTH_SHORT).show();
                                            break;
                case Activity.RESULT_CANCELED: Toast.makeText(getApplicationContext(), "Message Not Delivered", Toast.LENGTH_SHORT).show();
                                                break;

                }
            }
        }, new IntentFilter(DELIVERED));


        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(theNumber, null, theMsg, sentPI, deliveredPI);
    }
Carmacarmack answered 11/4, 2014 at 10:44 Comment(0)
C
0

You can just wrap your code in try/catch. It works in all cases, even with the last api changes about sms sending.

try{
    // code that use telephony features
}
catch(Exception e){
    // code that doesn't use telephony features
}
Chilli answered 2/2, 2014 at 12:55 Comment(0)
E
0

Here is what I make to check is SMS available.

public boolean isAvailable(Context context, Intent intent) {
    final PackageManager mgr = context.getPackageManager();
    List<ResolveInfo> list = mgr.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

which is taken from developer.android.com.

And create an Intent to check like this:

Uri smsToUri = Uri.parse("smsto:");
Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);
if (isAvailable(intent)) {
    // do whatever you like.
}
Ebb answered 8/11, 2016 at 8:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.