我有一个名为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));
}
}
有人可以指出我通过通知发送对象时发生的错误。谢谢!
答案 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);
}