无法使用Alarmmanager定期在后台工作

时间:2019-01-02 13:31:28

标签: android broadcastreceiver alarmmanager android-intentservice

我想按小时在后台调用服务。

第一个问题是警报管理器无法正常工作。计时器很糟糕,有时很早,有时又很晚。

第二个问题是,RemoteServiceException:Context.startForegroundService()然后没有调用Service.startForeground(),我不明白为什么会收到此异常

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        Intent intent1 = new Intent(MainActivity.this, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 60 * 1000L, pendingIntent);
    }
}

AlarmReceiver

public class AlarmReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {

        Intent downloadService = new Intent(context, CallService.class);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(downloadService);
        } else {
            context.startService(downloadService);
        }

    }

}

CallService

public class CallService extends IntentService {

    public CallService() {
        super("");
    }

    public CallService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent workIntent) {
        Log.d("Now : ", Calendar.getInstance().getTime().toString());



    }
}

清单

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <receiver android:name=".AlarmReceiver"/>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".CallService"
            android:exported="false"/>

对不起,我的英语不好。感谢您的帮助或建议。 我不知道我该怎么做。我只是定期打电话给服务

2 个答案:

答案 0 :(得分:0)

我在警报管理器中遇到了同样的问题。 您可以切换到RxJava的时间间隔。

protected fun startCountdown(period: Long, timeUnit: TimeUnit): Observable<Long> {
        return Observable.interval(period, timeUnit)
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
    }

用法;

startCountdown(MEDIA_LOCATION_CHANGE_PERIOD, TimeUnit.MILLISECONDS)
        .subscribe {
            fireSomethingUp()
        }

答案 1 :(得分:0)

AlarmManager将在api 27(oreo 8.1)及更低版本上正常运行。只需设置以下内容即可:

WAITFOR DELAY

别忘了每次触发 AlarmReceiver 时都需要重新设置警报。但是该代码将无法在api 28及更高版本(pie 9.0)上运行。发生这种情况是由于Android Pie中引入了Power management功能。在后台运行的应用程序中引入了严格的限制。 here说明了这些限制。尝试使用JobScheculer调用前台的IntentService。

关于第二个问题。您需要在您的 CallService 中发出通知。只需将此onCreate添加到您的 IntentService

public void setupAlarm(Context context, long triggerAtMillis) {
    PendingIntent pendingIntent = getPendingIntent(context);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
    } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
    } else {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, AlarmIntentBuilder.buildPendingIntent(context, uri));
    }
}

如果您在startForegroundService之后不调用服务中的startForeground(您有5秒钟的时间进行调用),则会引发RemoteServiceException。