java - 如何在 Oreo+ 中永久运行服务
问题描述
我想在 android 8(Oreo) 及更高版本中永远在后台运行服务。但我的服务不会永远运行它只会运行直到我的应用程序运行。
我尝试了使用 BroadcastReceiver 的作业调度程序、工作意图服务、前台服务和后台服务,但是当我销毁应用程序时,服务也会销毁
这就是我想永远运行的:
package ir.daneshja.www.alarm;
import android.app.Service;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.app.JobIntentService;
import android.util.Log;
import android.widget.Toast;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
public class AlertService extends JobIntentService {
public MqttAndroidClient mqttAndroidClient;
final String serverUri = "tcp://**.**.***.***:1883";
final String clientId = "qgpwexnp-12345";
final String username = "*****";
final String password = "*******";
public boolean issubs;
MediaPlayer mp;
@Override
public void onCreate() {
super.onCreate();
mqttAndroidClient = new MqttAndroidClient(AlertService.this, serverUri, clientId);
connect();
mp = MediaPlayer.create(AlertService.this, R.raw.alert_sound);
mqttAndroidClient.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean b, String s) {
Log.e("mqtt", s);
}
@Override
public void connectionLost(Throwable throwable) {
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
Log.e("Mqtt", mqttMessage.toString());
if (mqttMessage.toString().equals("alarm") || mqttMessage.toString().equals("alarm\n\r")) {
SharedPreferences.Editor editor = getSharedPreferences("alert", MODE_PRIVATE).edit();
editor.putBoolean("isalerting", true);
editor.apply();
}
while (true) {
Thread thread = new Thread() {
@Override
public void run() {
mp.start();
}
};
thread.start();
SharedPreferences prefs = getSharedPreferences("alert", MODE_PRIVATE);
boolean donNotPlayAgain = prefs.getBoolean("stopalert", false);
if (donNotPlayAgain) {
thread.stop();
break;
}
if (!mp.isPlaying()) {
thread.start();
}
}
SharedPreferences.Editor editor = getSharedPreferences("alert", MODE_PRIVATE).edit();
editor.putBoolean("isalerting", false);
editor.apply();
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
});
connect();
}
private void connect() {
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(false);
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setUserName(username);
mqttConnectOptions.setPassword(password.toCharArray());
try {
if (!mqttAndroidClient.isConnected()) {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
disconnectedBufferOptions.setBufferEnabled(true);
disconnectedBufferOptions.setBufferSize(100);
disconnectedBufferOptions.setPersistBuffer(false);
disconnectedBufferOptions.setDeleteOldestMessages(false);
mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
Log.e("issub", String.valueOf(issubs));
subscribeToTopic("alert");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("Mqtt", "Failed to connect to: " + serverUri + exception.toString());
}
});
}
} catch (MqttException ex) {
ex.printStackTrace();
}
}
private void subscribeToTopic(String topic) {
try {
mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.e("Mqtt", "Subscribed!");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("Mqtt", "Subscribed fail!");
}
});
} catch (MqttException ex) {
System.err.println("Exceptionst subscribing");
ex.printStackTrace();
}
}
public void disconnect() {
try {
mqttAndroidClient.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
谢谢。
解决方案
推荐阅读
- apache-camel - Apache Camel - 登录路由生成器的 Netty 异常
- wolfram-mathematica - 在 Mathematica 的 BarChart 中包含误差线
- ibm-integration-bus - IBM Integration Bus - 文件输入节点 - 更改 mqsiarchive 文件夹名称/位置
- android - 我需要后台线程和加载程序来从 firebase 检索数据吗?
- javascript - 将参数传递给函数而不传播(IE11)
- git - Git 不在 master 并且想要推送到 Github
- android - 关于“com.android.tools.r8.errors.b:成员类不能同时是(非成员)本地类”的错误。
- c# - 函数返回后是否可以将参数的属性标记为空/非空?
- webpack - 试图远离 nodeIntegration
- java - Spring Boot/@JDBCTest - 没有可用的“com.fasterxml.jackson.databind.ObjectMapper”类型的合格 bean