Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send WhatsApp message programmatically in background without opening WhatsApp application

I have found a lot of threads for the similar question but nowhere I have found what I was looking for.

Given a contact number and text message, I want to send WhatsApp message to that contact programmatically without opening the app or choosing the contact.

I have written below code as of now :

private static void sendTextUsingWhatsapp(Context context, Pair<S, S> contact, String Text) {    
Intent sendIntent = new Intent("android.intent.action.MAIN");
        sendIntent.setComponent(new ComponentName("com.whatsapp","com.whatsapp.Conversation"));
        sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators(countryCode +
                contact.second)+"@s.whatsapp.net");
        sendIntent.putExtra(Intent.EXTRA_TEXT, text);
        sendIntent.setType("text/plain");
        sendIntent.setAction(Intent.ACTION_SEND);
        context.startActivity(sendIntent);
}

With this piece of code I am getting to the window of WhatsApp contact.

This SO question states that this kind of feature is not supported. But then, how Google Now ("OK Google, send a message") is able to send WhatsApp messages in the background?

like image 270
Jatin Singla Avatar asked Feb 05 '17 16:02

Jatin Singla


People also ask

Can you send a WhatsApp message without opening the app?

Using Ok Google, you can command your phone to send messages without opening WhatsApp.

Can you reply to WhatsApp messages without opening the app?

For Android users, tap the message on the home screen. The 'Mark as read' & 'reply' options will appear, tap on reply to send the message. The quick reply feature in WhatsApp not only allows you to reply from the notification panel without even opening the app but also hides your online status from other contacts.

How can I secretly read WhatsApp messages without opening them?

Step 1: Open WhatsApp and go to the Settings menu. Step 2: Go to the Account option then go to the Privacy option. Step 3: Toggle off the Read Receipts button. Step 4: Tap on the Last Seen button on top.

Can you automate a WhatsApp message?

WhatsApp does not have a feature to schedule any message within the app. Having said that, there are several third-party apps available on Google Play Store that lets users schedule any message at the given time and date.


1 Answers

You can't send whatsApp message in background. You can use android accessibility service to automate it.

My AndroidManifest.xml

<service android:name=".helper.MyAccessibilityService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
        android:label="@string/app_name"
        android:exported="true">
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/config_accessibility_service" />
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
    </service>

config_accessibility_service.xml

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/app_name"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"/>

MyAccessibilityService.java

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.PowerManager;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;

import java.util.List;

public class MyAccessibilityService extends AccessibilityService {

    private static final String TAG = "MyAccessibilityService";

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        String packageName = event.getPackageName().toString();
        if (packageName.equals("com.whatsapp")){
            PackageManager packageManager = this.getPackageManager();
            try {
                ApplicationInfo info = packageManager.getApplicationInfo(packageName,0);
                String name = packageManager.getApplicationLabel(info).toString();
                try {
                    AccessibilityNodeInfoCompat rootNodeInfo = AccessibilityNodeInfoCompat.wrap(getRootInActiveWindow());
                    List<AccessibilityNodeInfoCompat> sendMessageNodeList = rootNodeInfo.findAccessibilityNodeInfosByViewId("com.whatsapp:id/send");
                    if (sendMessageNodeList == null || sendMessageNodeList.isEmpty()){
                        return;
                    }
                    AccessibilityNodeInfoCompat sendMessage = sendMessageNodeList.get(0);
                    if (!sendMessage.isVisibleToUser()){
                        return;
                    }
                    sendMessage.performAction(AccessibilityNodeInfo.ACTION_CLICK);

                    try {
                        Thread.sleep(2000);
                        performGlobalAction(GLOBAL_ACTION_BACK);
                        Thread.sleep(2000);
                    }catch (Exception e){
                        Log.e("onAccessibilityEvent", "onAccessibilityEvent: ",e );
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                Log.e(TAG, "onAccessibilityEvent: "+name );
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onInterrupt() {

    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED |
                AccessibilityEvent.TYPE_VIEW_FOCUSED;
        info.packageNames = new String[]
                {"com.whatsapp"};
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
        this.setServiceInfo(info);
        Log.d(TAG, "Accessibility service connected");
    }
}

AccessibilityServiceManager.java

public class AccessibilityServiceManager {
    Context context;

    public AccessibilityServiceManager(Context context) {
        this.context = context;
    }

    public boolean hasAccessibilityServicePermission(Class<? extends AccessibilityService> clazz) {
        int accessibilityEnabled = 0;
        final String service = context.getPackageName() + "/" + clazz.getCanonicalName();
        try {
            accessibilityEnabled = Settings.Secure.getInt(context.getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (Settings.SettingNotFoundException ignored) {
        }
        TextUtils.SimpleStringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(':');
        if (accessibilityEnabled == 1) {
            String settingValue = Settings.Secure.getString(context.getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            if (settingValue != null) {
                colonSplitter.setString(settingValue);
                while (colonSplitter.hasNext()) {
                    String accessibilityService = colonSplitter.next();

                    if (accessibilityService.equalsIgnoreCase(service)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }
    public void requestUserForAccessibilityService(Activity activity){
        new AlertDialog.Builder(context)
                .setTitle("Permission needed")
                .setMessage("You have to enable Accessibility service to use this feature")
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                    }
                })
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
                        activity.startActivity(intent);
                    }
                })
                .show();

    }
}

And you can call it in MainActivity.java

AccessibilityServiceManager serviceManager = new AccessibilityServiceManager(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (serviceManager.hasAccessibilityServicePermission(MyAccessibilityService.class)){
                    String message = "Your message",to = "91XXXXXXXXXX";
                        startActivity(
                                new Intent(Intent.ACTION_VIEW,
                                        Uri.parse(
                                                String.format("https://api.whatsapp.com/send?phone=%s&text=%s", to, message)
                                        )
                                ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        );
                }else{
                    serviceManager.requestUserForAccessibilityService(MainActivity.this);
                }
            }
        });

This worked for me.

like image 123
Adhil mhdk Avatar answered Oct 28 '22 02:10

Adhil mhdk