Как я могу отправлять данные между классом activity и классом non-activity?

#android #android-activity #firebase-cloud-messaging #android-alertdialog

#Android #android-activity #firebase-облако-обмен сообщениями #android-alertdialog

Вопрос:

Я хочу отправить данные из класса non-activity в класс MainActivity и показать эти данные пользователю с помощью AlertDialog. Данные представляют собой удаленное сообщение из Firebase. Я думаю, что могу использовать интерфейс, но я попробовал несколько вариантов и не сработал. Любая помощь будет очень признательна. Спасибо!

Мой класс non-activity

 public class FcmMessageListenerService extends FirebaseMessagingService  {
private static final String NOTIFICATION_CHANNEL_ID = "CITYLINE_DEFAULT_NOTIFICATION_CHANNEL";

public static final String MANDATOR_ID_KEY = "mandator_id";
public static final String MACHINE_SERIAL_NUMBER_KEY = "serial_number";
private iDialogNotificationInterface myInterface;
private  Map<String, String> data;

private Intent openAppIntent;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    data = remoteMessage.getData();
    String mandatorId = data.get("mandatorID");
    String message = data.get("message");
    String serialNumber = data.get("pmID");
    if (message != null) {
        Log.i("OnMessageReceived: ", message);
        sendNotification(mandatorId, message, serialNumber);
        myInterface.sendDialogNotification(mandatorId, message, serialNumber);
    } else {
        Log.e("OnMessageReceived", "null error");
    }
}

@Override
public void onNewToken(String s) {
    super.onNewToken(s);

    SharedPrefsUtils.setBooleanValue(this, DEVICE_TOKEN_REFRESH_EVENT_KEY, true);
    SharedPrefsUtils.removeValueByKey(this, DEVICE_PUSH_NOTIFICATION_TOKEN_KEY);
    Intent intent = new Intent(this, DeviceRegistrationService.class);
    startService(intent);
}

private void sendNotification(String mandatorId, String message, String serialNumber){
    String notificationTitle = this.getString(R.string.app_name);

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O amp;amp; notificationManager != null) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Default Notifications", NotificationManager.IMPORTANCE_HIGH);
        notificationChannel.setDescription("Status Change Notification");
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.RED);
        notificationChannel.enableVibration(false);

        notificationManager.createNotificationChannel(notificationChannel);
    }


    if (SharedPrefsUtils.getStringValue(this, SharedPrefsUtils.SESSION_COOKIE_DATA_KEY).equals("")) {
        openAppIntent = new Intent(this, LoginActivity.class);
    } else {
        openAppIntent = new Intent(this, MainActivity.class);
    }
    openAppIntent.putExtra(MANDATOR_ID_KEY, mandatorId);
    openAppIntent.putExtra(MACHINE_SERIAL_NUMBER_KEY, serialNumber);
    TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
    taskStackBuilder.addNextIntentWithParentStack(openAppIntent);
    PendingIntent resultPendingIntent = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_cityline)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_cityline))
            .setStyle(new NotificationCompat.BigTextStyle().bigText(message))
            .setContentTitle(notificationTitle)
            .setContentText(message)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(resultPendingIntent)
            .setAutoCancel(true);

    int notificationId = SharedPrefsUtils.getIntValue(this, SharedPrefsUtils.NOTIFICATION_UNIQUE_ID_KEY);

    if (notificationManager != null) {
        notificationManager.notify(notificationId, notificationBuilder.build());
        notificationId  ;
        if (notificationId > 100000)
            notificationId = 0;
        SharedPrefsUtils.setIntValue(this, SharedPrefsUtils.NOTIFICATION_UNIQUE_ID_KEY, notificationId);
    }
}



 String id = mandatorId;
    String msg = message;
    String serial = serialNumber;

    Intent serviceIntent = new Intent(this, MainActivity.class);
    serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    serviceIntent.putExtra("ID", id);
    serviceIntent.putExtra("MSG", msg);
    serviceIntent.putExtra("SERIAL", serial);
  

}

MainActivity

 private void openNotificationDialog( String mandatorId, String message, String serialNumber){

    Log.i("RAZZ", getApplicationContext().toString());
    String notificationTitle = this.getString(R.string.app_name);
    infoDialog = mBuilder.create();
    mBuilder.setCancelable(true);
    infoDialog.setTitle(notificationTitle);
    infoDialog.setMessage(message);
    infoDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            infoDialog.dismiss();
        }
    });

    infoDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    infoDialog.show();
}


@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

    }

@Override
public void sendDialogNotification(String id, String message, String serialNmb) {
    openNotificationDialog(id, message, serialNmb);
}
  

Интерфейс

 public interface iDialogNotificationInterface {
 void sendDialogNotification(String id, String message, String serialNmb);
  

}

Комментарии:

1. Где вы даете какое-либо значение «MyInterface»? Как вы можете вызвать MyInterface.sendDialogNotification(mandatorId, message, SerialNumber); если MyInterface имеет значение null?

2. Это то, что я пробовал в коде, размещенном здесь, но я получаю исключение ссылки на нулевой объект.. В классе FcmMessageListener я создал элемент данных типа iDialogNotificationInterface и вызвал конкретный метод с правильными параметрами. И внутри моей MainActivity я реализовал этот интерфейс и создал реализацию метода (вызывая метод, который показывает AlertDialog). Но это не работает..

3. @DanBaruch но какое значение я должен присвоить MyInterface ?… Я точно не знаю..

Ответ №1:

Использование интерфейса должно быть следующим:

 public class A implements interfaceA{
private interfaceA dataMember;
public void setMember(interfaceA member)
{
dataMember = member;
}
// rest of class code
// when needed to notify interfacemember, you call dataMember.function()
}
  

в вашем MainActivity вы должны сделать что-то вроде

 FcmMessageListenerService obj.setMember(MainActivity.this)
  

Из вашего кода кажется, что вы используете сервис, а не класс. Поскольку это сервис, я бы отправил данные в MainActivity через intent, а не interface.

Комментарии:

1. Мне нужно получать сообщение из уведомления, и каждый раз, когда пользователь получает уведомление, мне нужно показывать AlertDialog с сообщением уведомления.

2. Итак, ваша рекомендация для меня — использовать намерение для отправки данных в MainActivity?

3. измените ваше личное уведомление о отправке void(String mandatorId, String message, String SerialNumber) следующим образом: String vala = mandatorid; String path = message; String serNum = SerialNumber; Намерение serviceIntent = новое намерение (контекст, MainActivity.class ); serviceIntent.addFlags(Намерение. FLAG_ACTIVITY_NEW_TASK); serviceIntent.putExtra(«VAL1», vala);// то же самое для других значений serviceIntent.setPackage(context.getPackageName()); context.getApplicationContext().startActivity(serviceIntent);

4. Meh, комментарий дает слишком мало места для записи… Я имел в виду, сохраните код вашей текущей функции, после того, как вы закончите все, что вам нужно, с данными, и вы хотите обновить ActivityClass, вы используете intent , с примером, который я дал вам в предыдущем комментарии, для передачи значений через intent. Затем в вашем MainActivity вы переопределяете onNewIntent и анализируете намерение там, чтобы убедиться, что вы получили нужное вам намерение с правильной информацией, и оттуда вы можете вызвать любую нужную вам функцию.

5. Я обновил вопрос, добавив предложенный вами код. Не могли бы вы проверить, пожалуйста? Спасибо

Ответ №2:

Вы можете использовать Sharepreference для хранения данных в классе Non-Activity, а затем извлекать данные в свой класс Activity и наоборот.

В классе Non-Activity

Инициализация

 SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
  

Хранение данных

 editor.putBoolean("IsNotificationReceived", true); // Storing boolean as true when you receive the notifiaction also store the body or message into this sharedpref form the notification 
editor.commit(); // commit changes !Important line to save data into the sharedpreference
  

В классе Activity

Извлечение данных

 SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0);
boolean isNotificationReceived = pref.getBoolean(IsNotificationReceived, false);
  

проверьте isNotificationReceived при onResume или при инициализации класса, если значение равно true, затем вызовите диалоговое окно и покажите соответствующее сообщение

Обязательно измените sharedpref isNotificationReceived на false при открытии диалогового окна в противном случае диалоговое окно будет открываться всякий раз, когда вы вводите класс независимо от того, получили вы уведомление или нет