Нужно ли пример кода о том, как запустить службу Android навсегда в фоновом режиме даже при спящем устройстве, например Whatsapp?
Я пробовал различные способы достижения этого, но мой сервис в конечном итоге убивается.
Я хочу использовать AlarmManager для запуска класса каждые один час. Даже если устройство спит, оно должно посылать мигающий светодиодный сигнал, вибрацию или звук. В любом случае, он должен работать вечно.
Я заметил, что Whatsapp всегда работает, хотя я убиваю все запущенные приложения и очищаю память, убираю устройство и все еще Whatsapp получает сообщения и предупреждает меня. Как они это делают? Я хочу сделать то же самое с моим приложением.
Ответы
Ответ 1
Поскольку я разместил этот вопрос, я применил два разных подхода к этому решению в нескольких приложениях.
ПОДХОД 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;
}
}
Пример класса действия:
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 для вызова класса Service через равные промежутки времени. Вот код из моего приложения 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.class - это то, где я делаю свои вещи. В этом случае будильник просыпается каждый час и запускает BroadcastReceiver, который в свою очередь запускает службу. Это еще не все, чтобы убедиться, что обслуживание не выполняется дважды и так далее, но вы понимаете, как это делается. И AlarmManager на самом деле лучший способ сделать это, так как вы не беспокоитесь об использовании аккумулятора и т.д., И Android заботится о том, чтобы разбудить вашу службу через регулярные промежутки времени.
Ответ 2
Это очень просто.
шаги:
1. создать класс службы.
2. создать класс BroadcastReceiver
3.call BroadReceiver в onDestroy метод обслуживания
4.In 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>
`
Класс обслуживания
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));
}
}
Ответ 3
Следуйте этим простым шагам, чтобы поддерживать работоспособность навсегда в устройстве Android.
1. Вызовите службу, используя диспетчер аварийных сигналов.
2. Верните START_STICKY в метод onStart.
3. In on destroy вызовите диспетчер аварийных сообщений и перезапустите службу, используя метод startService.
4. (Необязательно) Повторите номер точки 3 в методе onTaskRemoved.
Ответ 4
Запросить частичный 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 повторно запустите START_STICKY:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
Ответ 5
Вы можете использовать функцию startForeground (int, Notification) см. здесь и здесь
Начальная служба может использовать API startForeground (int, Notification) поставить службу в состояние переднего плана, где система учитывает это то, что пользователь активно осознает и, следовательно, не кандидат на убийство при низкой памяти. (Теоретически теоретически возможно, чтобы служба была убита при чрезвычайном давлении памяти от текущего приложения переднего плана, но на практике это должно не беспокойтесь.)