Как реализовать широковещательный приемник, который будет синхронизировать любые входящие текстовые сообщения с сервером каждый раз, когда приходит новое смс - PullRequest
0 голосов
/ 20 октября 2019

Я занимаюсь разработкой приложения, которое синхронизирует все входящие текстовые сообщения с сервером. Я использую Broadcast Receiver, но в какой-то момент синхронизация не происходит, что означает, что процесс вещательного приемника вроде как убит. Большинство предложений, которые я получаю в Интернете, еще больше сбивают меня с толку, учитывая, что я все еще изучаю Android. Мне нужна помощь, чтобы решить эту проблему, обеспечивая синхронизацию без необходимости запуска приложения пользователем вручную и даже после перезапуска системы Android. Это мой широковещательный приемник.

Некоторые предложения, которые я получил, включали реализацию JobService, который я пробовал, но не смог правильно узнать, как запустить приемник из класса JobService. Я думаю, что концепция смутила меня. Вот код, который я попробовал

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class TextBroadcastService extends JobService {
    MessageReceiver messageReceiver;
    static String TAG = "TextBroadcastService";

    @Override
    public boolean onStartJob(JobParameters params) {
        //Code to be executed by the service

        BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

            }
        };
//        registerReceiver(broadcastReceiver,Telephony.Sms.Intents);

        Log.d(TAG, "onStartJob: serviceRunning: " );
        ServiceUtil.scheduleJob(getApplicationContext());
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.d(TAG, "onStopJob: Service destroyed:  ");
        return false;
    }
}

Тогда вот как я пытался запланировать задание, затем я понял, что не соединяюсь, как организовать вещание, и класс JobService запускает другой.

public class ServiceUtil {
    /** This class is responsible for scheduling jobs using the JobScheduler **/
    public static void scheduleJob(Context context){
        ComponentName serviceComponent = new ComponentName(context, TextBroadcastService.class);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            JobInfo.Builder jobBuilder = new JobInfo.Builder(0,serviceComponent);
            jobBuilder.setMinimumLatency(30 *1000); // Wait at least 30s
            jobBuilder.setOverrideDeadline(60 * 1000); //Setting Maximum delay at 60s

            JobScheduler jobScheduler = (JobScheduler)context
                    .getSystemService(context.JOB_SCHEDULER_SERVICE);
            jobScheduler.schedule(jobBuilder.build());
        }

    }

}


public class MessageReceiver extends BroadcastReceiver {
    Handler mHandler;
    Context context;
    String sender, timestamp, msgID, text_message;
    MessageDbHelper dbHelper;

    private static  String BASE_API_URL= "";
    public static final String PREFS_NAME = "server_url";
    private static final String TAG = "MessageReceiver";

    String DATE_FORMAT = "dd/MM/yyyy HH:mm:ss";
    SimpleDateFormat formatter =
            new SimpleDateFormat(DATE_FORMAT, Locale.getDefault());

    private static int counter = 0;
    static int successMessageCounter = 0;
    static int failedMessageCounter = 0;

    public MessageReceiver() {

    }

    @TargetApi(Build.VERSION_CODES.M)
    @Override
    public void onReceive(final Context context, Intent intent) {
        this.context= context;
        dbHelper = new MessageDbHelper(context);
        SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
        BASE_API_URL = settings.getString("server_url_str", "");
        Log.d(TAG, "onCreate: base url"+BASE_API_URL);

       if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
           final Bundle data = intent.getExtras();
           HandlerThread bgHandlerThread=new HandlerThread("MyCoolBackgroundThread");
           bgHandlerThread.start();
           mHandler=new Handler(bgHandlerThread.getLooper());

           Runnable backgroundRunnable = new Runnable() {
               @Override
               public void run() {
                   passReceivedMsg(data);
               }
           };
           mHandler.post(backgroundRunnable);

       }

    }

    private void passReceivedMsg(final Bundle bundleData) {
        if (bundleData !=null ){
            try {
                final Object[] pdusObj = (Object[]) bundleData.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);

//        msgID = UUID.randomUUID().toString();

                        String received_message = "You Received message from: " +sender
                                + " message: " + text_message
                                + " at: " + timestamp;
                        Log.d(TAG, "passReceivedMsg: received msg "+received_message);


                        Toast.makeText(context, received_message, Toast.LENGTH_SHORT).show();

                        try {
                            uploadMessageData();
                        } catch (JSONException e) {
                            e.printStackTrace();
                            Log.d(TAG, "passReceivedMsg: exception "+e.getMessage());
                            Log.d(TAG, "passReceivedMsg: exception: errorCause  "+e.getCause());
                        }

                    }
                }
            }
            catch (Exception e){
                Log.d(TAG, "onReceive: Error occurred "+e);

            }

        }

    }

Я ожидаю, что приемник вещания перехватит все входящие SMS без необходимости запуска приложения вручную. Я также ожидаю, что приемник будет запущен после включения устройства в случае, если устройство было выключено, что в данный момент не происходит.

Ниже описано, как я регистрирую приемник в манифесте

        <receiver
            android:name=".utils.MessageReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...