I just checking out the Application, is doing auto reply to WhatsApp message in background. I also trying to doing so, but can't get success in it. I had tried :
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
But it opening the WhatsApp application :(, not sending the message.
I go through with several links: Question1, Question2 also article on it but not getting satisfactory answer.
The application are accessing the notifications to get the messages, and replying to it, I also tried reading notifications using NotificationListenerService
, and got success to read message :), but can't send reply to it, I want to know how they are sending the messages in the background without opening the application.
Tap More options > Business tools > Away message. Turn on Send away message. Under Away message, tap the message to edit it, then tap OK. Tap Schedule to schedule your away message.
Basically that means that technically you never quit WhatsApp. So, the way you receive messages while you're "not running" WhatsApp is the exact same way you receive them when you're running it. The client, in this case WhatsApp, connects to the server. The client maintains that connection.
I haven't tested this but I think this can be done via Read Notification Bar title, message using Accessibility Service Programmatically
and https://developer.android.com/reference/android/app/RemoteInput
From doc :
public static final String KEY_QUICK_REPLY_TEXT = "quick_reply";
Notification.Action action = new Notification.Action.Builder(
R.drawable.reply, "Reply", actionIntent)
.addRemoteInput(new RemoteInput.Builder(KEY_QUICK_REPLY_TEXT)
.setLabel("Quick reply").build())
.build();
On a rooted device you can simply insert a message into the database
/data/data/com.whatsapp/databases/msgstore.db
like this.
Firstly get the contacts from the database. WhatsApp uses its own IDs for contacts(not user numbers) in the jid
column, will have to get that and the display name
.
class Contact{
public String jid;
public String displayName;
public Contact(String displayName,String jid){
this.displayName = displayName;
this.jid = jid;
}
}
public List<Contact> getContacts(){
Shell.SU.run("am force-stop com.whatsapp");
Shell.SU.run("chmod 777 /data/data/com.whatsapp");
db = SQLiteDatabase.openOrCreateDatabase(new File("/data/data/com.whatsapp/databases/wa.db"), null);
List<Contact> contactList = new LinkedList<>();
String selectQuery = "SELECT jid, display_name FROM wa_contacts where phone_type is not null and is_whatsapp_user = 1";
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
Contact contact = new Contact(cursor.getString(1), cursor.getString(0));
contactList.add(contact);
} while (cursor.moveToNext());
}
db.close();
}
Then send the message like so
private void sendBigMessage(String jid, String msg, String file, String mimeType) {
Shell.SU.run("am force-stop com.whatsapp");
db = SQLiteDatabase.openOrCreateDatabase(new File("/data/data/com.whatsapp/databases/msgstore.db"), null);
long l1;
long l2;
int k;
String query2, query1;
Random localRandom = new Random(20L);
l1 = System.currentTimeMillis();
l2 = l1 / 1000L;
k = localRandom.nextInt();
int mediaType = 0;
if (mimeType == null || mimeType.length() < 2)
mediaType = 0;
else
mediaType = (mimeType.contains("video")) ? 3
: (mimeType.contains("image")) ? 1
: (mimeType.contains("audio")) ? 2
: 0;
ContentValues initialValues = new ContentValues();
initialValues.put("key_remote_jid", jid);
initialValues.put("key_from_me", 1);
initialValues.put("key_id", l2 + "-" + k);
initialValues.put("status", 1);
initialValues.put("needs_push", 0);
initialValues.put("timestamp", l1);
initialValues.put("media_wa_type", mediaType);
initialValues.put("media_name", file);
initialValues.put("latitude", 0.0);
initialValues.put("longitude", 0.0);
initialValues.put("received_timestamp", l1);
initialValues.put("send_timestamp", -1);
initialValues.put("receipt_server_timestamp", -1);
initialValues.put("receipt_device_timestamp", -1);
initialValues.put("raw_data", -1);
initialValues.put("recipient_count", 0);
initialValues.put("media_duration", 0);
if (!TextUtils.isEmpty(file) && !TextUtils.isEmpty(mimeType)) {
//boolean isVideo = mimeType.contains("video");
Bitmap bMap = null;
File spec;
if (mediaType == 3) {
spec = new File(vidFolder, file);
bMap = ThumbnailUtils.createVideoThumbnail(spec.getAbsolutePath(), MediaStore.Video.Thumbnails.MICRO_KIND);
} else if(mediaType == 2) {
spec = new File(audFolder, file);
}else{
spec = new File(imgFolder, file);
bMap = BitmapFactory.decodeFile(spec.getAbsolutePath());
}
long mediaSize = (file.equals("")) ? 0 : spec.length();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if(mediaType == 1 || mediaType ==3) {
bMap = Bitmap.createScaledBitmap(bMap, 100, 59, false);
bMap.compress(Bitmap.CompressFormat.JPEG, 60, bos);
}
byte[] bArray = bos.toByteArray();
MediaData md = new MediaData();
md.fileSize = mediaSize;
md.file = spec;
md.autodownloadRetryEnabled = true;
byte[] arr = SerializationUtils.serialize(md);
initialValues.put("thumb_image", arr);
initialValues.put("quoted_row_id", 0);
//initialValues.put("media_mime_type", mimeType);
//initialValues.put("media_hash", "9vZ3oZyplgiZ40jJvo/sLNrk3c1fuLOA+hLEhEjL+rg=");
initialValues.put("raw_data", bArray);
initialValues.put("media_size", mediaSize);
initialValues.put("origin", 0);
initialValues.put("media_caption", msg);
} else
initialValues.put("data", msg);
long idm = db.insert("messages", null, initialValues);
query1 = " insert into chat_list (key_remote_jid) select '" + jid
+ "' where not exists (select 1 from chat_list where key_remote_jid='" + jid + "');";
query2 = " update chat_list set message_table_id = (select max(messages._id) from messages) where chat_list.key_remote_jid='" + jid + "';";
ContentValues values = new ContentValues();
values.put("docid", idm);
values.put("c0content", "null ");
db.insert("messages_fts_content", null, values);
db.execSQL(query1 + query2);
db.close();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With