Посылаемый объект получен нулевым через уведомление, но работает между активами - PullRequest
0 голосов
/ 11 октября 2018

У меня есть Intent Service, называемая ParserService, которая выполняет какую-то задачу и создает объект (ArtistInfo), который можно обработать.Затем он проверяет, находится ли приложение на переднем плане.Если это так, то он отправляет широковещательную рассылку с объектом parcelable в дополнительных функциях.Эта широковещательная передача принимается действием MainActivity.java, которое затем создает намерение с тем же объектом и запускает действие с именем ListSongsActivity, где удачно получаемый объект может быть получен.

Но если приложение не на переднем плане, то ParserServiceотправляет уведомление, которое имеет то же намерение, что и трансляция.Но когда ListSongsActivity запускается через уведомление, объект, подлежащий обработке (ArtistInfo), на этот раз равен нулю.И я также передаю строку в намерении.Эта строка корректно принимается через намерение уведомления, но объект пакета не имеет значения.

Ниже приведены соответствующие фрагменты кода.

Код трансляции и уведомления от ParserService:

if (CommonUtils.appInForeground(getApplicationContext())) {
                Log.d(TAG, "onHandleIntent(): Sending success broadcast.");
                sendBroadcast(createSuccessIntent(artistInfo));
            } else {
                // TODO: 10-10-2018 tapping on notification does nothing!!
                Log.d(TAG, "onHandleIntent(): Sending success notification.");
                String body = "Parsing complete for the url: " + url;
                Intent notifyIntent = new Intent(getApplicationContext(), ListSongsActivity.class);
                notifyIntent.putExtra(Constants.MUSIC_SITE, siteName);
                notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                Bundle bundle = new Bundle();
                bundle.putParcelable(Constants.PARSED_ARTIST_INFO, artistInfo);
                intent.putExtras(bundle);
                CommonUtils.sendNotification(getApplicationContext(), Constants.LIST_SONGS_NOTIFICATION_TITLE
                        , body, Constants.LIST_SONGS_NOTIFICATION_CHANNEL_ID, notifyIntent,
                        Constants.LIST_SONGS_NOTIFICATION_ID, R.drawable.ic_launcher_background);
            }

private Intent createSuccessIntent(ArtistInfo artistInfo) {
    Intent intent = new Intent();
    intent.setAction(Constants.PARSE_SUCCESS_ACTION_KEY);
    Bundle bundle = new Bundle();
    bundle.putParcelable(Constants.PARSE_SUCCESS_MESSAGE_KEY, artistInfo);
    intent.putExtras(bundle);
    return intent;
}

Broadcast, полученный во фрагменте MainActivity:

private class ParserBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "ParserBroadcastReceiver, onReceive()");
        String parseResult = intent.getAction();
        if (parseResult == null || parseResult.equals(Constants.EMPTY_STRING)) {
            return;
        }
        switch (parseResult) {
            case Constants.PARSE_SUCCESS_ACTION_KEY:
                ArtistInfo artistInfo = intent.getParcelableExtra(Constants.PARSE_SUCCESS_MESSAGE_KEY);
                Log.d(TAG, "ParserBroadcastReceiver, onReceive() PARSE_SUCCESS_ACTION_KEY, artistInfo: "
                        + artistInfo.toString());
                Log.d(TAG, "site: " + musicSite);
                createIntentAndDelegateActivity(artistInfo);
                break;
            default:
                break;
        }
    }
}

private void createIntentAndDelegateActivity(ArtistInfo artistInfo) {
    Log.d(TAG, "createIntentAndDelegateActivity()");
    Intent intent = new Intent(getContext(), ListSongsActivity.class);
    intent.putExtra(Constants.MUSIC_SITE, musicSite);
    Bundle bundle = new Bundle();
    bundle.putParcelable(Constants.PARSED_ARTIST_INFO, artistInfo);
    intent.putExtras(bundle);
    startActivity(intent);
}

sendNotification в CommonUtils:

public static void sendNotification(Context context, String title, String body,
                                    String channelId, Intent intent, Integer id, Integer iconResourceId) {
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (notificationManager == null) {
        Log.d(TAG, "sendNotification(): noti manager null!!");
        return;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId,
                Constants.DEFAULT_NOTIFICATION_CHANNEL_NAME,
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription(Constants.DEFAULT_NOTIFICATION_CHANNEL_DESCRIPTION);
        notificationManager.createNotificationChannel(channel);
    }

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addNextIntentWithParentStack(intent);
    PendingIntent pendingIntent1 = stackBuilder.getPendingIntent(Constants.PENDING_INTENT_DEFAULT_REQ_CODE,
            PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
    builder.setContentTitle(title);
    builder.setContentText(body);
    builder.setSmallIcon(iconResourceId);
    builder.setContentIntent(pendingIntent1);

    Notification notification = builder.build();
    // Play default notification sound
    notification.defaults |= Notification.DEFAULT_SOUND;

    // Vibrate if vibrate is enabled
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    NotificationManagerCompat.from(context).notify(id, notification);
}

Вот как я получаюIntentExtras в ListSongsActivity:

private void getIntentExtras() {
    Log.d(TAG, "getIntentExtras()");
    Intent intent = getIntent();
    parsedArtistInfo = intent.getParcelableExtra(Constants.PARSED_ARTIST_INFO);
    String siteName = intent.getStringExtra(Constants.MUSIC_SITE);
    Log.d(TAG, "getIntentExtras() sitename: " + siteName);
    musicSite = Enum.valueOf(MusicSite.class, siteName);
    Log.d(TAG, "getIntentExtras() artInfo: " + parsedArtistInfo.toString());
}

Когда ListSongsActivity запускается получателем широковещательной рассылки, объект parsedArtistInfo является правильным объектом, переданным ParserService, но когда ListSongsActivity открывается посредством уведомления, объект parsedArtistInfo имеет значение null.

Класс ArtistInfo:

public class ArtistInfo implements Parcelable {

private static final String TAG = ArtistInfo.class.getSimpleName();

private String url;

private String artist;

// album name to list of ids of songs
private HashMap<String, List<Integer>> albumInfo;

// song id to songInfo
private SparseArray<SongInfo> songsMap;

/**
 * to be used only for ui display logic, don't use for downloading logic
 */
private HashMap<String, Boolean> albumCheckedStatus;

public ArtistInfo() {
}

private ArtistInfo(Parcel in) {
    url = in.readString();
    artist = in.readString();
    // Read album info
    getAlbumInfo();
    int albumInfoSize = in.readInt();
    for (int i = 0; i < albumInfoSize; i++) {
        String key = in.readString();
        List<Integer> value = new ArrayList<>();
        in.readList(value, null);
        albumInfo.put(key, value);
    }

    // Read songs map
    getSongsMap();
    int songsMapSize = in.readInt();
    for (int i = 0; i < songsMapSize; i++) {
        int key = in.readInt();
        SongInfo value = in.readParcelable(SongInfo.class.getClassLoader());
        songsMap.put(key, value);
    }

    getAlbumCheckedStatus();
    int albumCheckStatusSize = in.readInt();
    for (int i = 0; i < albumCheckStatusSize; i++) {
        String key = in.readString();
        Boolean value = in.readByte() != 0;
        albumCheckedStatus.put(key, value);
    }
}

public static final Creator<ArtistInfo> CREATOR = new Creator<ArtistInfo>() {
    @Override
    public ArtistInfo createFromParcel(Parcel in) {
        return new ArtistInfo(in);
    }

    @Override
    public ArtistInfo[] newArray(int size) {
        return new ArtistInfo[size];
    }
};
@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(url);
    dest.writeString(artist);
    // Write album info
    getAlbumInfo();
    dest.writeInt(albumInfo.size());
    for (Map.Entry<String, List<Integer>> item : albumInfo.entrySet()) {
        dest.writeString(item.getKey());
        dest.writeList(item.getValue());
    }

    // Write song map
    getSongsMap();
    dest.writeInt(songsMap.size());
    for (int i = 0; i < songsMap.size(); i++) {
        int key = songsMap.keyAt(i);
        dest.writeInt(key);
        dest.writeParcelable(songsMap.get(key), flags);
    }

    getAlbumCheckedStatus();
    dest.writeInt(albumCheckedStatus.size());
    for (Map.Entry<String, Boolean> item : albumCheckedStatus.entrySet()) {
        dest.writeString(item.getKey());
        dest.writeByte((byte) (item.getValue() ? 1 : 0));
    }
}

Может кто-нибудь указать на ошибку, которую я совершаю при отправке объекта через уведомление.Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Перед вызовом sendNotification() в другом состоянии вы помещаете пакет в другой intent, а не в notifyIntent.Измените свой код в другом как показано ниже

else {
    // TODO: 10-10-2018 tapping on notification does nothing!!
    Log.d(TAG, "onHandleIntent(): Sending success notification.");
    String body = "Parsing complete for the url: " + url;
    Intent notifyIntent = new Intent(getApplicationContext(), ListSongsActivity.class);
    notifyIntent.putExtra(Constants.MUSIC_SITE, siteName);
    notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    Bundle bundle = new Bundle();
    bundle.putParcelable(Constants.PARSED_ARTIST_INFO, artistInfo);
    notifyIntent.putExtras(bundle);
    CommonUtils.sendNotification(getApplicationContext(), Constants.LIST_SONGS_NOTIFICATION_TITLE
                            , body, Constants.LIST_SONGS_NOTIFICATION_CHANNEL_ID, notifyIntent,
                            Constants.LIST_SONGS_NOTIFICATION_ID, R.drawable.ic_launcher_background);
   }
0 голосов
/ 11 октября 2018

Возможно, вы создаете ожидающие намерения больше, чем в вашем приложении.В этом случае вы должны использовать

PendingIntent.FLAG_CANCEL_CURRENT

, чтобы создать Намерение с нуля и раздуть свой пакет

...