簡體   English   中英

可通知對象通過通知接收為空的對象,但在活動之間起作用

[英]Parcelable object being received null via notification but works between activites

我有一個名為ParserService的Intent服務,該服務執行一些任務並創建一個可拆分的對象(ArtistInfo)。 然后,它檢查應用程序是否在前台。 如果是,那么它將發送帶有意向附加內容中可包裹對象的廣播。 活動MainActivity.java接收到此廣播,然后該活動創建具有相同對象的意圖,並啟動一個名為ListSongsActivity的活動,在該活動中成功接收了可拆分對象。

但是,如果該應用程序不在前台,則ParserService會發送一條與廣播具有相同意圖的通知。 但是,當通過通知啟動ListSongsActivity時,可打包對象(ArtistInfo)這次為null。 而且我也傳遞了意圖。 該字符串已通過通知意圖正確接收,但可打包對象為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中的getIntentExtras的方式:

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

有人可以指出我通過通知發送對象時發生的錯誤。 謝謝!

也許您在應用程序中創建的待定意圖比其他更多。 在這種情況下,您應該使用

PendingIntent.FLAG_CANCEL_CURRENT

從頭開始創建意圖並為您的捆綁包充氣

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM