服务在棉花糖上工作,但在Nougat上工作它不起作用

时间:2018-02-28 16:44:39

标签: android service background-process

我有这个问题,当我使用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!!

0 个答案:

没有答案