Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start Viber call from an Android app [new version]?

Tags:

android

viber

A while ago I created this post, and my colleague and I have found two different answers to it (both of them worked):

  1. First solution was to use

    Intent callIntent = new Intent("android.intent.action.CALL_PRIVILEGED");

    which would open new window offering for call to be made by all possible means for placing call - in this particular case, they were Dialer and Viber and Skype (or any other method added later).

  2. Second solution was to explicitly call Viber and place a phone number to be called as well

    Intent viberCallIntent = new Intent("com.viber.voip.action.CALL"); viberCallIntent.setType("vnd.android.cursor.item/vnd.com.viber.voip.call"); viberCallIntent.setData(Uri.parse("tel:" + dialNumber)); viberCallIntent.putExtra("external_call", true); viberCallIntent.putExtra("contact_id", -1L); startActivity(viberCallIntent);

Since last Viber update (we noticed it yesterday), none of those methods work. First one just calls using Skype, not even offering Dialer (!?!), but if Skype is not installed then it will fall back to Dialer and place call. Second one crashes claiming that there is no Activity found to handle Intent?

Any idea what is happening and how could this be resolved ?

Error log is as follows:

01-27 17:35:03.794: E/AndroidRuntime(7738): FATAL EXCEPTION: main
01-27 17:35:03.794: E/AndroidRuntime(7738): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.viber.voip dat=tel:xxxxxxxxx (has extras) }
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1628)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1423)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.Activity.startActivityForResult(Activity.java:3388)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.Activity.startActivityForResult(Activity.java:3349)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.Activity.startActivity(Activity.java:3584)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.Activity.startActivity(Activity.java:3552)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at rs.limitline.maxitaxins.MainActivity.callViber(MainActivity.java:96)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at rs.limitline.maxitaxins.MainActivity.onClick(MainActivity.java:186)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.view.View.performClick(View.java:4212)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.view.View$PerformClick.run(View.java:17476)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.os.Handler.handleCallback(Handler.java:800)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.os.Handler.dispatchMessage(Handler.java:100)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.os.Looper.loop(Looper.java:194)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at android.app.ActivityThread.main(ActivityThread.java:5431)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at java.lang.reflect.Method.invokeNative(Native Method)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at java.lang.reflect.Method.invoke(Method.java:525)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
01-27 17:35:03.794: E/AndroidRuntime(7738):     at dalvik.system.NativeStart.main(Native Method)

[UPDATE] This shows as error as well:

01-27 19:46:56.704: D/Greska(19822): Permission Denial: starting Intent { act=com.viber.voip.action.CALL dat=tel:xxxxxxxxx cmp=com.viber.voip/com.viber.service.OutgoingCallBroadcaster (has extras) } from ProcessRecord{416c41b8 19822:rs.limitline.maxitaxins/u0a10065} (pid=19822, uid=10065) not exported from uid 10147
like image 318
Nenad Bulatović Avatar asked Jan 27 '14 17:01

Nenad Bulatović


People also ask

What is Viber audio call?

Viber is a VoIP and instant messaging application with cross-platform capabilities that allows users to exchange audio and video calls, stickers, group chats, and instant voice and video messages.

Why is my Viber not calling?

Grant Viber Permissions If Viber is not working correctly or if you cannot make calls or receive calls over Viber the app on your Android mobile, it is good to check for app permissions.


3 Answers

According to Viber's manifest, there is activity "com.viber.voip.phone.PhoneActivity" that is responsible for action "com.viber.voip.action.CALL". In new version of Viber (4.2.1.1) this activity is marked by android:exported="false". As result, it's not possible anymore to start this activity from external applications...

Edit

This code opens welcome screen for specified contact

String sphone = "12345678";
Uri uri = Uri.parse("tel:" + Uri.encode(sphone)); 
Intent intent = new Intent("android.intent.action.VIEW");
intent.setClassName("com.viber.voip", "com.viber.voip.WelcomeActivity");
intent.setData(uri); 
context.startActivity(intent);

but user should click button "free call" to start call.

like image 139
dvpublic Avatar answered Oct 19 '22 04:10

dvpublic


It is possible to call per Viber direct (without WelcomeActivity), but user should have this number in Contacts.

public void callToViberContact(String phoneNumber, Context context) {
    Uri uri = getUriFromPhoneNumber(phoneNumber, context);
    if (uri != null) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.setClassName("com.viber.voip", "com.viber.voip.SystemDialogActivityPublic");
        intent.setData(uri);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    } else {
        Toast.makeText(context, "Number is not in Viber Contacts List", Toast.LENGTH_LONG).show();
    }
}

private Uri getUriFromPhoneNumber(String phoneNumber, Context context) {
    Uri uri = null;
    String contactId = getContactIdByPhoneNumber(phoneNumber, context);
    if (!TextUtils.isEmpty(contactId)) {
        Cursor cursor = context.getContentResolver().query(
                ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data._ID},
                ContactsContract.Data.DATA2 + "=? AND " + ContactsContract.Data.CONTACT_ID + " = ?",
                new String[]{"Viber", contactId}, null);
        if (cursor != null) {
            while (cursor.moveToNext()){
                String id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data._ID));
                if (!TextUtils.isEmpty(id)) {
                    uri = Uri.parse(ContactsContract.Data.CONTENT_URI + "/" + id);
                    break;
                }
            }
            cursor.close();
        }
    }
    return uri;
}

private String getContactIdByPhoneNumber(String phoneNumber, Context context) {
    ContentResolver contentResolver = context.getContentResolver();
    String contactId = null;
    Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));

    String[] projection = new String[]{ContactsContract.PhoneLookup._ID};

    Cursor cursor =
            contentResolver.query(
                    uri,
                    projection,
                    null,
                    null,
                    null);

    if (cursor != null) {
        while (cursor.moveToNext()) {
            contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
        }
        cursor.close();
    }
    return contactId;
}

READ_CONTACTS permission is required. Don't forget to add in Manifest:

<uses-permission android:name="android.permission.READ_CONTACTS" />
like image 31
jlga Avatar answered Oct 19 '22 05:10

jlga


String uriString = "content://com.android.contacts/data/" + _id;

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(uriString));
intent.setPackage(PKG_VIBER);
startActivity(intent);

_id can be queried from contacts2.db(Column ContactsContract.Data._ID)

like image 36
23snyga Avatar answered Oct 19 '22 05:10

23snyga