可通知对象通过通知接收为空的对象,但在活动之间起作用

时间:2018-10-11 08:41:16

标签: java android notifications

我有一个名为ParserService的Intent服务,该服务执行一些任务并创建一个可拆分的对象(ArtistInfo)。然后,它检查应用程序是否在前台。如果是,那么它将发送带有意向附加内容中可包裹对象的广播。活动MainActivity.java接收到此广播,然后该活动创建具有相同对象的意图,并启动一个名为ListSongsActivity的活动,在该活动中成功接收到可打包对象。

但是,如果该应用程序不在前台,则ParserService会发送一个与广播具有相同意图的通知。但是,当通过通知启动ListSongsActivity时,可打包对象(ArtistInfo)这次为null。而且我也传递了意图。该字符串已通过通知意图正确接收,但可打包对象为空。

请在下面找到相关的代码段。

来自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;
}

在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);
}

CommonUtils中的sendNotification:

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

这就是我如何在ListSongsActivity中获取IntentExtras:

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

当广播接收器启动ListSongsAtivity时,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 :(得分:0)

也许您在应用程序中创建的待定意图比其他更多。在这种情况下,您应该使用

PendingIntent.FLAG_CANCEL_CURRENT

从头开始创建Intent并为捆绑包充气

答案 1 :(得分:0)

在您的else条件下调用sendNotification()之前,您要将捆绑包放到另一个intent,而不是notifyIntent上。在下面的else中更改代码

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