在Android中运行永无止境服务的最佳方式
我有一个服务,它会在用户更改位置时发出通知。我希望此服务继续运行,直到用户在application manager中显式强制停止我的应用程序。我使用了以下方法:在Android中运行永无止境服务的最佳方式,android,android-service,alarmmanager,Android,Android Service,Alarmmanager,我有一个服务,它会在用户更改位置时发出通知。我希望此服务继续运行,直到用户在application manager中显式强制停止我的应用程序。我使用了以下方法: Intent intent1 = new Intent(context, LocationService2.class); PendingIntent contentIntent = PendingIntent.getService(context, 0, intent1, 0); Ala
Intent intent1 = new Intent(context, LocationService2.class);
PendingIntent contentIntent = PendingIntent.getService(context, 0, intent1, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(),2*60000, contentIntent);
服务类别:
public class LocationService2 extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("TAG", "STARTLS");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
return START_STICKY;
}
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Location services connected.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
// Use this location to give notification if required.
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
mGoogleApiClient.disconnect();
}
}
这种方法并不适用于所有手机。
AlarmManager是执行此操作的最佳方法。如果是,那么我如何改进此代码以适用于所有手机?您应该将您的服务设置为
前台服务。您可以找到教程。清单条目
<receiver android:name="YourPackagename.RestartReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name="YourPackagename.AlarmReceiver" >
</receiver>
AlarmReceiver.java
public class RestartReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intentReciever = new Intent(context, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intentReciever, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, (System.currentTimeMillis() + GlobalContext.PUSH_NOTIFICATION_INTERVAL),
GlobalContext.PUSH_NOTIFICATION_INTERVAL, alarmIntent);
}
}
}
public class AlarmReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//you can put your logic over here
}
}
public class MyService extends Service {
CommunicationListner listener;
public class LocalBinder extends Binder {
public MyService getService() {
// Return this instance of LocalService so clients can call public methods
return MyService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
unregisterReceiver(internetConnectionReceiver);
} catch (Exception e) {
}
registerReceiver(internetConnectionReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
//communication with activity
public void registerChatReceivedListener(CommunicationListner listener) {
this.listener = listener;
}
public void removeChatReceivedListener() {
chatListener = null;
}
private BroadcastReceiver internetConnectionReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
};
public MyService() {
}
}
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
context.startService(new Intent(context, MyService.class));
}
}
}
将下面的代码放在启动屏幕中
private void initService() {
if(!app_preferences.getBoolean("isServiceRunning", false))
{
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intentReciever = new Intent(LoadingScreen.this, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(LoadingScreen.this, 0, intentReciever, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, (System.currentTimeMillis()+GlobalContext.PUSH_NOTIFICATION_INTERVAL),
GlobalContext.PUSH_NOTIFICATION_INTERVAL, alarmIntent);
app_preferences.edit().putBoolean("isServiceRunning", true).commit();
}
}
//注意:使用共享首选项检查Alerm服务是否正在运行不是一个好方法。创建永无止境的服务的步骤包括:
1.) Start service using alarmManager.
2.) Check in onResume if service is running & restart if not.
3.) Return START_STICKY from onStartCommand().
4.) In OnStartCommand() , create a thread and do the needful from that thread .All the logical stuff should be there in while(true).
这样,您的服务将永远不会被终止。在给定的代码中,我添加了一些好东西,比如您可以通过listner使用。您可以通过在服务中编写代码来通知您的活动您失去了internet连接
创建永不结束的。若用户将关闭应用程序,它将再次自动重启
与alarm manager相比,您可能面临重复/多重服务启动。就像我们需要识别和防止那个样,若我已经创建了报警管理器,那个么就不要按照我在同一个问题中写的另一个答案重新开始
Manifest.xml
<receiver android:name=".BootCompleteReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter></receiver>
<service android:name=".MyService" android:enabled="true" android:exported="false"/>
在重新启动手机上重新启动服务
BootCompleteReceiver.Java
public class RestartReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intentReciever = new Intent(context, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intentReciever, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, (System.currentTimeMillis() + GlobalContext.PUSH_NOTIFICATION_INTERVAL),
GlobalContext.PUSH_NOTIFICATION_INTERVAL, alarmIntent);
}
}
}
public class AlarmReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//you can put your logic over here
}
}
public class MyService extends Service {
CommunicationListner listener;
public class LocalBinder extends Binder {
public MyService getService() {
// Return this instance of LocalService so clients can call public methods
return MyService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
unregisterReceiver(internetConnectionReceiver);
} catch (Exception e) {
}
registerReceiver(internetConnectionReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
//communication with activity
public void registerChatReceivedListener(CommunicationListner listener) {
this.listener = listener;
}
public void removeChatReceivedListener() {
chatListener = null;
}
private BroadcastReceiver internetConnectionReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
};
public MyService() {
}
}
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
context.startService(new Intent(context, MyService.class));
}
}
}
在你的启动屏幕中输入代码来启动myservice,如果它已经启动了,那么也没必要担心
startService(new Intent(getApplicationContext(), MyService.class));
随时启动服务
@Override
public void onDestroy() {
super.onDestroy();
mGoogleApiClient.disconnect();
startService(new Intent(this, LocationService2.class));
}
android 5及更高版本的解决方案是使用AlarmManger和广播接收器你能发布你的服务类别吗?我已经处理了bootcomlete接收器,但在我的情况下,问题是,即使在用户从某些手机的应用程序切换器中删除应用程序后,服务也会停止运行。我已经发布了我的服务类别。如您所见,我在onStartCommand中返回“START\u STICKY”。四、五分钟后服务仍然停止hours@RuchirBaronia请查收