是否有可能从Java / Kotlin中的android WorkManager类启动brodacast接收器

问题描述 投票:0回答:1

现在,我一个问题停留了一个多月。我想从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();
}
android kotlin broadcastreceiver android-broadcast android-workmanager
1个回答
0
投票

最后,在详细讨论之后,我已经对它进行了破解,可以在评论区域中看到(针对此问题)。我现在有可以使用的代码,并且我相信通过共享,我可以帮助其他陷入困境的人。这就是我做的。这是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();
}
© www.soinside.com 2019 - 2024. All rights reserved.