automation - 退出应用程序后,WhatsApp 自动消息不起作用并且应用程序无法工作
问题描述
**我正在开发一个向 WhatsApp 发送消息的项目。它不工作 SMS 工作正常,但 WhatsApp 消息不工作。它会打开 WhatsApp,但未发送消息。还有一件事,当我退出应用程序时,它不再起作用。从设置中清除数据或缓存后,它再次起作用。它每次都请求许可。我希望应用程序在用户单击 WhatsApp 按钮时请求许可。如果有人可以帮助我安排 WhatsApp 消息,我将不胜感激**
主要活动
enter code here
package com.example.automated_demo;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.telephony.SmsManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
import com.karumi.dexter.listener.single.PermissionListener;
import com.wafflecopter.multicontactpicker.ContactResult;
import com.wafflecopter.multicontactpicker.LimitColumn;
import com.wafflecopter.multicontactpicker.MultiContactPicker;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final int CONTACT_PICKER_REQUEST =20 ;
EditText phn,sms,count;
Button send,chose,whtsapp,timer;
List<ContactResult> results=new ArrayList<>();
int hr,min,sec;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
phn=findViewById(R.id.phone);
sms=findViewById(R.id.txt);
count=findViewById(R.id.count);
send=findViewById(R.id.send);
chose=findViewById(R.id.choose);
whtsapp=findViewById(R.id.whtsapp);
timer=findViewById(R.id.time);
Dexter.withContext(this)
.withPermissions(
Manifest.permission.SEND_SMS,
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECORD_AUDIO
).withListener(new MultiplePermissionsListener() {
@Override public void onPermissionsChecked(MultiplePermissionsReport report) {/* ... */}
@Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {/* ... */}
}).check();
if (!isAccessibilityOn(getApplicationContext())){
Intent intent=new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MysmsService.startActionSMS(getApplicationContext(),sms.getText().toString(),
count.getText().toString(),results);
}
});
whtsapp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MysmsService.startActionWHATSAPP(getApplicationContext(),sms.getText().toString(),
count.getText().toString(),results);
}
});
}
chose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new MultiContactPicker.Builder(MainActivity.this) //Activity/fragment context
.theme(R.style.MyCustomPickerTheme) //Optional - default: MultiContactPicker.Azure
.hideScrollbar(false) //Optional - default: false
.showTrack(true) //Optional - default: true
.searchIconColor(Color.WHITE) //Option - default: White
.setChoiceMode(MultiContactPicker.CHOICE_MODE_MULTIPLE) //Optional - default: CHOICE_MODE_MULTIPLE
.handleColor(ContextCompat.getColor(MainActivity.this, R.color.purple_500)) //Optional - default: Azure Blue
.bubbleColor(ContextCompat.getColor(MainActivity.this, R.color.purple_700)) //Optional - default: Azure Blue
.bubbleTextColor(Color.WHITE) //Optional - default: White
.setTitleText("Select Contacts") //Optional - default: Select Contacts
.setLoadingType(MultiContactPicker.LOAD_ASYNC) //Optional - default LOAD_ASYNC (wait till all loaded vs stream results)
.limitToColumn(LimitColumn.NONE) //Optional - default NONE (Include phone + email, limiting to one can improve loading time)
.setActivityAnimations(android.R.anim.fade_in, android.R.anim.fade_out,
android.R.anim.fade_in,
android.R.anim.fade_out) //Optional - default: No animation overrides
.showPickerForResult(CONTACT_PICKER_REQUEST);
}
});
IntentFilter filter=new IntentFilter("my.own.broadcast");
LocalBroadcastManager.getInstance(this).registerReceiver(myLocalbroadcastreciever,filter);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CONTACT_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
results = MultiContactPicker.obtainResult(data);
StringBuilder names = new StringBuilder(results.get(0).getDisplayName());
for (int j = 0; j < results.size(); j++) {
names.append(", ").append(results.get(j).getDisplayName());
}
phn.setText(names);
Log.d("MyTag", results.get(0).getDisplayName());
} else if (resultCode == RESULT_CANCELED) {
System.out.println("User closed the picker without selecting items.");
}
}
}
private final BroadcastReceiver myLocalbroadcastreciever=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String result=intent.getStringExtra("result");
Toast.makeText(context, result, Toast.LENGTH_SHORT).show();
}
};
private boolean isAccessibilityOn(Context context) {
int accessibilityEnabled = 0;
final String service = context.getPackageName () + "/" + Whatsappaccesibility.class.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;
}
}
MysmsService
package com.example.automated_demo;
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.telephony.SmsManager;
import android.widget.Toast;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.wafflecopter.multicontactpicker.ContactResult;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
* <p>
* TODO: Customize class - update intent actions, extra parameters and static
* helper methods.
*/
public class MysmsService extends IntentService {
// TODO: Rename actions, choose action names that describe tasks that this
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_SMS = "com.example.automated_demo.action.FOO";
private static final String ACTION_WHATSAPP = "com.example.automated_demo.action.BAZ";
// TODO: Rename parameters
private static final String MESSEAGE = "com.example.automated_demo.extra.PARAM1";
private static final String NUMBER = "com.example.automated_demo.extra.PARAM2";
private static final String COUNT = "com.example.automated_demo.extra.PARAM3";
public MysmsService() {
super("MysmsService");
}
// TODO: Customize helper method
public static void startActionSMS(Context context, String message, String count, List<ContactResult> mobile_numbers) {
List<String> numbers =new ArrayList<String>();
for(int i = 0;i<mobile_numbers.size();i++){
numbers.add(mobile_numbers.get(i).getPhoneNumbers().get(0).getNumber());
}
String[] numbersArray = numbers.toArray(new String[0]);
Intent intent = new Intent(context, MysmsService.class);
intent.setAction(ACTION_SMS);
intent.putExtra(MESSEAGE, message);
intent.putExtra(COUNT, count);
intent.putExtra(NUMBER,numbersArray);
context.startService(intent);
}
/**
* Starts this service to perform action Baz with the given parameters. If
* the service is already performing a task this action will be queued.
*
* @see IntentService
*/
// TODO: Customize helper method
public static void startActionWHATSAPP(Context context, String message, String count, List<ContactResult> mobile_numbers) {
List<String> numbers =new ArrayList<String>();
for(int i = 0;i<mobile_numbers.size();i++){
numbers.add(mobile_numbers.get(i).getPhoneNumbers().get(0).getNumber());
}
String[] numbersArray = numbers.toArray(new String[0]);
Intent intent = new Intent(context, MysmsService.class);
intent.setAction(ACTION_WHATSAPP);
intent.putExtra(MESSEAGE, message);
intent.putExtra(COUNT, count);
intent.putExtra(NUMBER,numbersArray);
context.startService(intent);
}
private void handleActionWHATSAPP(String message, String count, String[] mobile_number) {
try {
PackageManager packageManager = getApplicationContext().getPackageManager();
if (mobile_number.length != 0) {
for (int j = 0; j < mobile_number.length; j++) {
for (int i = 0; i < Integer.parseInt(count.toString()); i++) {
String[] words = message.split(" ");
String number = mobile_number[j];
for(int k=0;k<words.length;k++) {
String url = "https://api.whatsapp.com/send?phone=" + number + "&text=" + URLEncoder.encode(words[k] + " ", "UTF-8");
Intent whatappIntent = new Intent(Intent.ACTION_VIEW);
whatappIntent.setPackage("com.whatsapp");
whatappIntent.setData(Uri.parse(url));
whatappIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (whatappIntent.resolveActivity(packageManager) != null) {
getApplicationContext().startActivity(whatappIntent);
Thread.sleep(10000);
sendBroadcastMessage("Result: " + k);
} else {
sendBroadcastMessage("Result: WhatsApp Not installed");
}
}
}
}
}else {
{
try {
packageManager = getApplicationContext().getPackageManager();
if (mobile_number.length != 0) {
for (int j = 0; j < mobile_number.length; j++) {
for (int i = 0; i < Integer.parseInt(count.toString()); i++) {
String number = mobile_number[j];
String url = "https://api.whatsapp.com/send?phone=" + number + "&text=" + URLEncoder.encode(message + " ", "UTF-8");
Intent whatappIntent = new Intent(Intent.ACTION_VIEW);
whatappIntent.setPackage("com.whatsapp");
whatappIntent.setData(Uri.parse(url));
whatappIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (whatappIntent.resolveActivity(packageManager) != null) {
getApplicationContext().startActivity(whatappIntent);
Thread.sleep(10000);
sendBroadcastMessage("Result: " + number);
} else {
sendBroadcastMessage("Result: WhatsApp Not installed");
}
}
}
}
} catch (Exception e) {
sendBroadcastMessage("Result: " + e.toString());
}
}
}
} catch (Exception e) {
sendBroadcastMessage("Result: " + e.toString());
}
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_SMS.equals(action)) {
final String message = intent.getStringExtra(MESSEAGE);
final String count = intent.getStringExtra(COUNT);
final String[] mobile_number = intent.getStringArrayExtra(NUMBER);
handleActionSMS(message, count,mobile_number);
} else if (ACTION_WHATSAPP.equals(action)) {
final String message = intent.getStringExtra(MESSEAGE);
final String count = intent.getStringExtra(COUNT);
final String[] mobile_number = intent.getStringArrayExtra(NUMBER);
handleActionWHATSAPP(message, count,mobile_number);
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionSMS(String message, String count, String[] mobile_number) {
// TODO: Handle action Foo
try {
if(mobile_number.length!=0) {
for(int j=0;j<mobile_number.length;j++) {
for (int i = 0; i < Integer.parseInt(count.toString()); i++) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(mobile_number[j], null, message, null, null);
sendBroadcastMessage("Result:"+ (i+1) + " "+ mobile_number[j]);
}
}
}
}catch(Exception e){
}
}
/**
* Handle action Baz in the provided background thread with the provided
* parameters.
*/
private void sendBroadcastMessage(String message){
Intent localIntent = new Intent("my.own.broadcast");
localIntent.putExtra("result",message);
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
}
Mywhatsapp 无障碍服务
package com.example.automated_demo;
import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import java.util.List;
public class Whatsappaccesibility extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if(getRootInActiveWindow() == null){
return;
}
//getting root node
AccessibilityNodeInfoCompat rootNodeInfo = AccessibilityNodeInfoCompat.wrap(getRootInActiveWindow());
//get edit text if message from whats app
List<AccessibilityNodeInfoCompat> messageNodeList = rootNodeInfo.findAccessibilityNodeInfosByViewId("com.whatsapp:id/entry");
if(messageNodeList == null || messageNodeList.isEmpty())
return;
//checking if message field if filled with text and ending with our suffix
AccessibilityNodeInfoCompat messageField = messageNodeList.get(0);
if(messageField == null || messageField.getText().length() == 0 || !messageField.getText().toString()
.endsWith(getApplicationContext().toString()))
return;
// get whatsapp send message button node list
List<AccessibilityNodeInfoCompat> sendMessageNodeList = rootNodeInfo.findAccessibilityNodeInfosByViewId("com.whatsapp:id/send");
if(sendMessageNodeList == null || sendMessageNodeList.isEmpty())
return;
AccessibilityNodeInfoCompat sendMessage = sendMessageNodeList.get(0);
if(!sendMessage.isVisibleToUser())
return;
//fire send button
sendMessage.performAction(AccessibilityNodeInfo.ACTION_CLICK);
//go back to our app by clicking back button twice
try{
Thread.sleep(2000); // some devices cant handle instant back click
performGlobalAction(GLOBAL_ACTION_BACK);
Thread.sleep(2000);
performGlobalAction(GLOBAL_ACTION_BACK);
}catch (InterruptedException ignored) {}
}
@Override
public void onInterrupt() {
}
}
解决方案
推荐阅读
- ios - 如何居中 TabBarItem - Swift
- javascript - Laravel 5:附加输入文本取决于所选选项 vue js
- python - 使用python将数据文件拆分为单独的文件
- amazon-web-services - Fargate 任务(容器)是否可以检索其元数据,例如服务名称?
- python - 绘制两个具有不同索引类型的 Panda 数据框
- list - 我如何对HashMap进行排序
按他们在 Kotlin 中的值排序? - python - Spacy - 将相似性函数应用于熊猫行中的文档
- javascript - 滚动时的jQuery不透明度被切断
- python - catalina 10.51.1 python3 w brew 或 xcode-select
- android - 如何在android datepicker中获取月份的第一个和最后一个日期