Android 8.0-重新启动后未接收广播



我正在开发一个应用程序。我正在面临问题。问题是我的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.a5corp.weather">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher_x"
    android:label="@string/app_name"
    android:fullBackupContent="@xml/backup_rules"
    android:theme="@style/AppTheme.NoActionBar">
    ...
    <service android:name=".service.NotificationService" />
    <receiver
        android:name=".receiver.StartupReceiver"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    <receiver android:name=".receiver.UpgradeReceiver">
        <intent-filter>
            <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
        </intent-filter>
    </receiver>
    ...
</application>
</manifest>

startupreceiver:

public class StartupReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            ...
            NotificationService.setNotificationServiceAlarm(context, new Prefs(context).getNotifs());
        }
        else
            Log.i("No" , "Boot");
    }
}

升级器:

public class UpgradeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Log.i("In" , UpgradeReceiver.class.getSimpleName());
    NotificationService.setNotificationServiceAlarm(context , new Prefs(context).getNotifs());
}
}

notificationservice:

public class NotificationService extends IntentService {
    private static final String TAG = "NotificationsService";
    Prefs prefs;
    Notification.Builder builder;
    public NotificationService() {
        super(TAG);
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return super.onBind(intent);
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        CheckConnection checkNetwork = new CheckConnection(this);
        if (!checkNetwork.isNetworkAvailable()) {
            return;
        }
        ...
        try {
            WeatherInfo weather;
            weather = new Request(this).getItems(city, units);
            weatherNotification(weather);
        } catch (IOException e) {
            Log.e(TAG, "Error get weather", e);
        }
    }
    public static Intent newIntent(Context context) {
        Log.i("Trigger" , "newIntent");
        return new Intent(context, NotificationService.class);
    }
    public static void setNotificationServiceAlarm(Context context,
                                                   boolean isNotificationEnable) {
        Log.i("In" , "Notification Service Alarm");
        Intent intent = NotificationService.newIntent(context);
        PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        long intervalMillis = AlarmManager.INTERVAL_HOUR;
        if (alarmManager != null)
            if (isNotificationEnable) {
                alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        SystemClock.elapsedRealtime(),
                        intervalMillis,
                        pendingIntent);
            } else {
                alarmManager.cancel(pendingIntent);
                pendingIntent.cancel();
            }
    }
    private void weatherNotification(WeatherInfo weather) {
        Intent intent = new Intent(this, WeatherActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        ...
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        assert notificationManager != null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String id = "w01", name = getString(R.string.weather_notification_title);
            int importance = NotificationManager.IMPORTANCE_MIN;
            String desc = getString(R.string.weather_notification_description);
            NotificationChannel channel = new NotificationChannel(id, name, importance);
            channel.setDescription(desc);
            notificationManager.createNotificationChannel(channel);
            builder = new Notification.Builder(this , id);
        }
        else
            builder = new Notification.Builder(this);
        ...
        Notification notification = builder.build();
        notificationManager.notify(0 , notification);
    }
}

问题在于,Notificationservice单独使用,但是当应用程序升级或重新启动手机时,这并没有被调用。事实是,这是在Android O上发生的。据我所知,在我升级到Android 8之前,这曾经在Android 7.1上工作。

编辑1:尝试JobIntentservice之后,这是我的代码现在看起来的样子:

更新清单:

...
<service android:name=".service.ReactivationService"
            android:permission="android.permission.BIND_JOB_SERVICE"/>
...

重新激活服务:

public class ReactivationService extends JobIntentService {
    public static final int JOB_ID = 0x01;
    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, ReactivationService.class, JOB_ID, work);
    }
    @Override
    protected void onHandleWork(@NonNull Intent intent) {
        Log.i("In" , "onHandleWork()");
        ....
            NotificationService.setNotificationServiceAlarm(this, new Prefs(this).getNotifs());
    }
}

启动接收器:

public class StartupReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            Log.i("In" , "getAction()");
            ReactivationService.enqueueWork(context, intent);
        }
        else
            Log.i("No" , "Boot");
    }
}

升级接收器:

public class UpgradeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED)) {
            Log.i("In" , "getAction()");
            ReactivationService.enqueueWork(context, intent);
        }
        else
            Log.i("No" , "Upgrade");
    }
}

现在,我的问题是,action_my_package_rephaced可以正常工作并显示了通知,但是action_boot_completed却没有显示通知。可能是什么原因,因为我正在为两个接收器使用相同的服务。

从android o开始,您无法从背景应用程序中启动服务而没有例外:

java.lang.illegalstateException:不允许启动服务意图 (my_service):应用在后台

如果您仍然需要在设备启动时启动服务,现在可以使用新的JobIntentservice。

将您的IntentService更改为JobIntentService

public class ReactivationService extends JobIntentService {
    public static final int JOB_ID = 0x01;
    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, ReactivationService.class, JOB_ID, work);
    }
    @Override
    protected void onHandleWork(@NonNull Intent intent) {
        // do your stuff here
    }
}

在您的StartupReceiver中使用它如下:

public class StartupReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            ReactivationService.enqueueWork(context, new Intent());
        }
    }
}

在清单中声明您的服务:

<service android:name=".ReactivationService"
         android:permission="android.permission.BIND_JOB_SERVICE"/>

就是这样。这将直接启动服务(在Pre-O平台上运行时),或者将其作为工作(在O上运行时)的工作来工作。无论该平台是什么,您在enqueueWork中传递的所有内容最终都会出现在onHandleWork中。

最新更新