我有这个问题,当我使用API 23在模拟器6.0上调试时,程序工作正常,创建正确的通知等等,但是当我在模拟器上使用带有API 25的7.1.1尝试相同的程序时 ResultReceiver rec = intent.getParcelableExtra(EXTRA_RECEIVER); rec总是为空。
MAINACTIVITY.java
public class MainActivity extends Activity {
public static final String TAG = "MainActivity";
public MySimpleReceiver receiverForSimple;
private PendingIntent alarmPendingIntent;
public static final String SERVICES_RESULT = "services_result";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupServiceReceiver();
checkForMessage();
StartAlarm();
}
public void StartAlarm() {
Context ctx = getApplicationContext();
AlarmManager alarm = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(ctx, MyAlarmReceiver.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(EXTRA_RECEIVER);
intent.putExtra("receiver", receiverForSimple);
Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 21);
cal.set(Calendar.MINUTE, 56);
cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));
alarmPendingIntent = PendingIntent.getBroadcast(this, MyAlarmReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup periodic alarm every 5 seconds
long firstMillis = System.currentTimeMillis(); // first run of alarm is immediate
int intervalMillis = 1000 * 60; // 1 minutes in milliseconds
if (alarm != null){
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, intervalMillis, alarmPendingIntent);
}
boolean isWorking = (PendingIntent.getBroadcast(this, MyAlarmReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag
Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working...");
}
// Setup the callback for when data is received from the service
public void setupServiceReceiver() {
receiverForSimple = new MySimpleReceiver(new Handler());
// This is where we specify what happens when data is received from the
// service
receiverForSimple.setReceiver(new MySimpleReceiver.Receiver() {
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == RESULT_OK) {
String resultValue = resultData.getString("resultValue");
Toast.makeText(MainActivity.this, resultValue, Toast.LENGTH_SHORT).show();
}
}
});
}
// Checks to see if service passed in a message
private void checkForMessage() {
String message = getIntent().getStringExtra("message");
if (message != null) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Intent myService = new Intent(MainActivity.this, MyAlarmReceiver.class);
stopService(myService);
}
}
这是我的服务代码: 的 MySimpleService.java
public class MySimpleService extends IntentService {
public static final int NOTIF_ID = 56;
public static final int REQUEST_CODE = 56;
long timestamp;
public static final String EXTRA_RECEIVER = "receiver";
static final String NAME=
"com.codepath.example.servicesnotificationsdemo.MySimpleService";
// Must create a default constructor
public MySimpleService() {
super("simple-service");
}
// This describes what will happen when service is triggered
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
//if (EXTRA_RECEIVER.equals(action)) {
timestamp = System.currentTimeMillis();
// Extract additional values from the bundle
String val = intent.getStringExtra("foo");
// Extract the receiver passed into the service
ResultReceiver rec = intent.getParcelableExtra(EXTRA_RECEIVER);
// Sleep a bit first
sleep(500);
Log.d("MySimpleService", "receiver: " + rec + " foo:" + val);
if(rec != null){
// Send result to activity
sendResultValue(rec, val);
// Let's also create notification
createNotification(val);
}
//}
}
}
// Send result to activity using ResultReceiver
private void sendResultValue(ResultReceiver rec, String val) {
// To send a message to the Activity, create a pass a Bundle
Bundle bundle = new Bundle();
bundle.putString("resultValue", "My Result Value. You Passed in: " + val + " with timestamp: " + timestamp);
// Here we call send passing a resultCode and the bundle of extras
rec.send(Activity.RESULT_OK, bundle);
}
// Construct compatible notification
private void createNotification(String val) {
// Construct pending intent to serve as action for notification item
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message", "Launched via notification with message: " + val + " and timestamp " + timestamp);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
// Create notification
String longText = "Intent service has a new message with: " + val + " and a timestamp of: " + timestamp;
Notification noti =
new NotificationCompat.Builder(this, DemoApplication.CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("New Result!")
.setContentText("Simple Intent service has a new message")
.setStyle(new NotificationCompat.BigTextStyle().bigText(longText))
.setContentIntent(pIntent)
.build();
// Hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(NOTIF_ID, noti);
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
Intent intent = new Intent(MainActivity.SERVICES_RESULT);
sendBroadcast(intent);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
MySimpleReceiver.java
public class MySimpleReceiver extends ResultReceiver {
private Receiver receiver;
// Constructor takes a handler
public MySimpleReceiver(Handler handler) {
super(handler);
}
// Setter for assigning the receiver
public void setReceiver(Receiver receiver) {
this.receiver = receiver;
}
// Defines our event interface for communication
public interface Receiver {
public void onReceiveResult(int resultCode, Bundle resultData);
}
// Delegate method which passes the result to the receiver if the receiver
// has been assigned
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (receiver != null) {
receiver.onReceiveResult(resultCode, resultData);
}
}
}
MyAlarmReceiver.java
public class MyAlarmReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
public static final int NOTIF_ID = 12345;
public static final String ACTION = "com.codepath.example.servicesdemo.alarm";
// Triggered by the Alarm periodically (starts the service to run task)
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("AlarmReceiver", "onRecieve: " + action);
// Put here YOUR code.
Intent i = new Intent(context, MySimpleService.class);
ResultReceiver receiver = intent.getParcelableExtra("receiver");
i.putExtra("foo", "Alarm!!");
i.putExtra("receiver", receiver);
Log.d("AlarmReceiver", "receiver: " + receiver);
context.startService(i);
}
}
这是我的 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.codepath.example.servicesnotificationsdemo"
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<!-- Permission to start Alarm on device reboot -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- permission required to use Alarm Manager -->
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<application
android:name=".DemoApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".activities.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.ImagePreviewActivity"
android:exported="true"
android:label="@string/title_activity_image_view">
</activity>
<service
android:name=".services.MySimpleService"
android:exported="false" />
<service
android:name=".services.ImageDownloadService"
android:exported="true" />
<receiver android:name=".receivers.MyAlarmReceiver"
android:process=":remote">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".receivers.DeviceBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service
android:name=".services.DirectReplyIntent">
</service>
</application>
</manifest>
和我的LOGCAT:
EMULATOR 6.0
02-28 16:11:57.040 16146-16146/com.codepath.example.servicesnotificationsdemo D/MainActivity: alarm is working...
02-28 16:12:02.577 16146-16203/com.codepath.example.servicesnotificationsdemo D/MySimpleService: receiver: android.os.ResultReceiver@38ff4cd foo:Alarm!!
02-28 16:13:16.902 16146-16218/com.codepath.example.servicesnotificationsdemo D/MySimpleService: receiver: android.os.ResultReceiver@a4ca1fc foo:Alarm!!
EMULATOR 7.1.1
02-28 16:15:29.469 9970-9970/com.codepath.example.servicesnotificationsdemo D/MainActivity: alarm is working...
02-28 16:15:35.019 9970-10012/com.codepath.example.servicesnotificationsdemo D/MySimpleService: receiver: null foo:Alarm!!
02-28 16:16:34.977 9970-10020/com.codepath.example.servicesnotificationsdemo D/MySimpleService: receiver: null foo:Alarm!!