现在,我一个问题停留了一个多月。我想从Android WorkManager类启动广播接收器。我想接收/过滤所有传入的文本消息,然后发布到服务器。但是,我的当前解决方案无法在android系统杀死该应用程序并且接收器同步停止之前,或者在我从PDU对象提取文本消息(来自电话意图)的onReceive方法已经返回之前,无法正常工作。因此,为解决此问题,我希望在WorkManager内保持广播的onReceive方法运行,以确保进程不会以如此快的速度终止。我已经尝试阅读,但是我没有找到适合自己的解决方案,或者也许我对广播接收器或android后台进程的工作方式尚不清楚。这是我当前的实现。下面是在MessageReceiver上实现的onReceive()方法,该方法扩展了BroadcastReceiver
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onReceive(final Context context, Intent intent) {
this.context= context;
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
final Bundle data = intent.getExtras();
if (data !=null ) {
try {
final Object[] pdusObj = (Object[]) data.get("pdus");
if (pdusObj != null) {
for (int i = 0; i < pdusObj.length; i++) {
SmsMessage currentMessage =
SmsMessage.createFromPdu((byte[]) pdusObj[i]);
Log.d(TAG, "run: currentMessage: " + currentMessage);
Log.d(TAG, "passReceivedMsg: handleMessage: message " + currentMessage);
int msgNo = counter++;
msgID = "SMS_ID_0" + msgNo;
sender = currentMessage.getDisplayOriginatingAddress();
text_message = currentMessage.getDisplayMessageBody();
long timestampMilliseconds = System.currentTimeMillis();
timestamp = formatter.format(timestampMilliseconds);
Data.Builder dataBuilder = new Data.Builder();
dataBuilder.putString("sender",sender);
dataBuilder.putString("message",text_message);
dataBuilder.putString("timestamp",timestamp);
dataBuilder.putString("sms_id",msgID);
// Log.d(TAG, "onReceive: key:" +key+ " and keyValue "+data.get(key));
WorkManager mWorkManager = WorkManager.getInstance();
OneTimeWorkRequest mRequest = new OneTimeWorkRequest
.Builder(MessageSyncWorker.class)
.setInputData(dataBuilder.build())
.build();
mWorkManager.enqueue(mRequest);
}
}
}
catch (Exception e){
Log.d(TAG, "onReceive: Exception occured "+e.getMessage());
}
}
}
}
下面是我的MessageSyncWorker类,它扩展了Worker-doWork()方法
@NonNull
@Override
public Result doWork() {
Data inputData1 = getInputData();
sender = inputData1.getString("sender");
text_message = inputData1.getString("message");
timestamp = inputData1.getString("timestamp");
msgID = inputData1.getString("sms_id");
Log.d(TAG, "doWork: Mesage "+text_message);
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
BASE_API_URL = sharedPreferences.getString("settings_server_url", "");
Log.d(TAG, "doWork: BASE URL "+BASE_API_URL);
try {
//here I upload the data to the server
uploadMessageData();
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "doWork: uploadMessage method Exception "+e.getMessage());
}
return Result.success();
}
最后,在详细讨论之后,我已经对它进行了破解,可以在评论区域中看到(针对此问题)。我现在有可以使用的代码,并且我相信通过共享,我可以帮助其他陷入困境的人。这就是我做的。这是onReceive()方法;
@Override
public void onReceive(Context context, Intent intent) {
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION
.equals(intent.getAction())){
this.context = context;
SmsMessage smsMessage = null;
StringBuilder fullMessage = new StringBuilder();
for (SmsMessage new_smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)){
smsMessage = new_smsMessage;
fullMessage.append(smsMessage.getDisplayMessageBody());
}
if (smsMessage ==null){
return;
}
String sender = smsMessage.getOriginatingAddress();
long timestampMilliseconds = System.currentTimeMillis();
String timestamp = formatter.format(timestampMilliseconds);
Log.d("NeTxt Receiver ", "onReceive: fullMessage: "+fullMessage);
Data.Builder dataBuilder = new Data.Builder();
dataBuilder.putString("fullMessage",fullMessage.toString());
dataBuilder.putString("sender", sender);
dataBuilder.putString("timestamp",timestamp);
//defining constraints
Constraints task_constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
//scheduling the work
WorkManager mWorkManager = WorkManager.getInstance();
OneTimeWorkRequest mRequest = new OneTimeWorkRequest
.Builder(NewTxtWorker.class)
.setInputData(dataBuilder.build())
.setConstraints(task_constraints)
.build();
mWorkManager.enqueue(mRequest);
mWorkManager.getWorkInfoById(mRequest.getId());
}
}
下面是我的doWork()方法;
@NonNull
@Override
public Result doWork() {
Data inputData = getInputData();
String sender = inputData.getString("sender");
String text_message = inputData.getString("fullMessage");
String timestamp = inputData.getString("timestamp");
Log.d("Txt WorkManager", "doWork: fullmessage: "+text_message);
assert sender != null;
assert text_message != null;
if (!timestamp.isEmpty()||
!sender.isEmpty()||
!text_message.isEmpty()){
FirebaseFirestore fireDb = FirebaseFirestore.getInstance();
Map<String, Object> message = new HashMap<>();
message.put("text_message", text_message);
message.put("sender", sender);
message.put("timestamp", timestamp);
//sync the received message with the firebase firestore db
fireDb.collection("text_messages")
.add(message)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
@Override
public void onSuccess(DocumentReference documentReference) {
Log.d("Txt WorkManager", "onSuccess: doc Id"
+documentReference.getId());
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("Txt WorkManager", "onFailure: "+e.getMessage());
}
}) ;
}
return Result.failure();
}