在Android中运行永无止境服务的最佳方式

在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

我有一个服务,它会在用户更改位置时发出通知。我希望此服务继续运行,直到用户在application manager中显式强制停止我的应用程序。我使用了以下方法:

        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请查收