Можно ли запустить приемник brodacast из класса android WorkManager в Java / Kotlin - PullRequest
0 голосов
/ 29 мая 2020

Я не могу ответить на один вопрос уже больше месяца. Я хочу запустить широковещательный приемник из класса Android WorkManager. Я хочу получать / фильтровать все входящие текстовые сообщения, а затем отправлять их на сервер. Однако мое текущее решение не может работать в течение многих часов, пока система android не убьет приложение, а синхронизация приемника c не остановится, или к тому времени, когда я извлечу текстовое сообщение из объекта PDU (поступающего с телефона Intent), будет метод onReceive уже вернулся. Поэтому, чтобы решить эту проблему, я должен sh поддерживать широковещательный метод onReceive внутри WorkManager, чтобы гарантировать, что процесс не завершится так быстро. Я пробовал читать, но не получаю того решения, которое хорошо работает со мной, или, может быть, мне что-то непонятно насчет широковещательного приемника или того, как работают фоновые процессы android. Это моя текущая реализация. Ниже приведен метод onReceive (), реализованный в MessageReceiver, который расширяет 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, расширяющий метод WorkerdoWork ()

@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();
}

1 Ответ

0 голосов
/ 01 июня 2020

Наконец, я взломал его после подробного обсуждения, которое можно увидеть в области комментариев (для этого вопроса). Теперь у меня есть рабочий код, и я верю, что, поделившись им, я смогу помочь кому-то другому, у которого есть подобное. Ниже показано, как я это сделал.
вот метод 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...