Нужен пример кода о том, как запустить службу Android навсегда в фоновом режиме, даже когда устройство спит, как WhatsApp?
Я пробовал различные способы достичь этого, но моя служба в конечном итоге погибает.
Я хочу использовать AlarmManager для запуска класса каждый час. Даже если устройство спит,оно должно отправить мигающий сигнал тревоги, вибрацию или звук. В любом случае, он должен работать вечно.
Я заметил, что Whatsapp всегда работает, хотя я убиваю все запущенные приложения и очищаю память, помещаю устройство в спящий режим, и все еще Whatsapp получает сообщения и оповещения мне. Как они это делают? Я хочу сделать то же самое с моим приложением.
5 ответов
поскольку я опубликовал этот вопрос, я реализовал два разных подхода к этому решению в нескольких приложениях.
подход 1
этот экстракт из приложения, где я использую push-уведомления, которые нуждаются в мгновенных вызовах пробуждения для устройства. Вот что я делаю
- используйте разрешение WAKE_LOCK и
- используйте абстрактный класс Wakelocker
- использовать его в деятельности нужны:
Манифест:
<uses-permission android:name="android.permission.WAKE_LOCK" />
класс WakeLocker:
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context context) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "WakeLock");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
пример класса Activity:
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
// do something
WakeLocker.release();
}
подход 2
лучше всего, когда вы хотите дать Android контроль над просыпаться, и может жить с периодически просыпаться ваш код. Просто используйте AlarmManager для вызова класса обслуживания через регулярные промежутки времени. Вот некоторые код из моего приложения LifeLog24:
MainActivity
Intent ll24 = new Intent(context, AlarmReceiverLifeLog.class);
PendingIntent recurringLl24 = PendingIntent.getBroadcast(context, 0, ll24, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, first_log.getTime(), AlarmManager.INTERVAL_HOUR, recurringLl24); // Log repetition
Класс Сигнализации
public class AlarmReceiverLifeLog extends BroadcastReceiver {
private static final String TAG = "LL24";
static Context context;
@Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "Alarm for LifeLog...");
Intent ll24Service = new Intent(context, LifeLogService.class);
context.startService(ll24Service);
}
}
и LifeLogService.в классе я занимаюсь своими делами. В этом случае будильник просыпается каждый час и запускает BroadcastReceiver, который взамен запускает службу. Это еще не все, чтобы убедиться, что сервис не запускается дважды и так далее, но вы получите точку, как это делается. И AlarmManager на самом деле лучший способ сделать это, так как вы не волнуетесь об использовании батареи и т. д. и Android заботится о пробуждении вашего сервиса через регулярные промежутки времени.
Это очень просто.
шаги:
1.создайте класс обслуживания.
2.создайте класс BroadcastReceiver
3.вызовите BroadReceiver в onDestroy метод обслуживания
4.В onReceive метод службы запуска класса BroadReceiver еще раз.
здесь код
файл манифеста:`
<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">
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".utilities.NotificationService"
android:enabled="true">
</service>
<receiver
android:name=".utilities.RestartService"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="RestartService" />
</intent-filter>
</receiver>
</application>
`
сервис класс!--9-->
public class NotificationService extends Service {
public NotificationService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Intent restartService = new Intent("RestartService");
sendBroadcast(restartService);
}
}
класс BroadcastReceiver
public class RestartService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,NotificationService.class));
}
}
следуйте этим простым шагам, чтобы сохранить servce навсегда в android-устройстве. 1. Вызовите службу с помощью Alarm manager. 2. возврат START_STICKY в методе onStart. 3. В on destroy вызовите диспетчер сигналов тревоги и перезапустите службу с помощью метода startService. 4.(Необязательно)Повторите пункт 3 в методе onTaskRemoved.
запрос частичного WakeLock.
<uses-permission android:name="android.permission.WAKE_LOCK" />
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Tag");
mWakeLock.acquire();
onStartCommand retrun START_STICKY:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
вы можете использовать функцию startForeground (int, Notification) посмотреть здесь и здесь
запущенная служба может использовать API startForeground(int, Notification) чтобы поместить службу в состояние переднего плана, где система рассматривает это должно быть что-то, что пользователь активно знает и, следовательно, не кандидат на убийство при недостатке памяти. (Это все еще теоретически возможно, служба будет убита под экстремальным давлением памяти из текущего приложения переднего плана, но на практике это должно не беспокойтесь.)