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

时间:2015-12-11 04:50:55

标签: android android-service alarmmanager

如果用户更改了位置,我会提供通知。我希望此服务继续运行,直到用户明确强制在应用程序管理器中停止我的应用程序。我使用了以下方法:

        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是最好的方法吗?如果是,那么如何改进此代码以适用于所有手机?

6 个答案:

答案 0 :(得分:2)

您应该将服务设为Foreground Service。您可以找到教程here

答案 1 :(得分:1)

清单条目

<receiver android:name="YourPackagename.RestartReceiver">
<intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

<receiver android:name="YourPackagename.AlarmReceiver" >
</receiver>

在手机重启时需要重新初始化警报管理器 的 RestartReceiver.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);
        }
    }

}

<强> AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        //you can put your logic over here
    }
}

将以下代码放入启动画面

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服务的好方法是否正在运行。

答案 2 :(得分:1)

制作永无止境的服务的步骤是:

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). 

这样你的服务永远不会被杀死。

答案 3 :(得分:0)

在给定的代码中,我通过listner使用communicate with activity添加了一些好东西,例如 binder service 。您可以通过编写服务代码来通知您的活动您丢失了互联网连接...

创建永远不会结束的 service as sticky 。如果用户将杀死应用程序,它将再次自动重启。

与警报管理器比较时,您可能会面临重复/多服务开始。就像我们需要识别和防止,如果我已经创建了警报管理器,那么不要按照我在同一问题中写的另一个答案重新开始。

<强>的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"/>

<强> MyService.java

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() {
        }

    }

在重启手机上重启服务 的 BootCompleteReceiver.Java

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));
        }
    }
}

如果代码已经启动,请将代码放入启动画面以启动我的服务,然后也无需担心。

startService(new Intent(getApplicationContext(), MyService.class));

答案 4 :(得分:0)

随时杀死服务。

@Override
public void onDestroy() {
    super.onDestroy();
    mGoogleApiClient.disconnect();
    startService(new Intent(this, LocationService2.class));
}

答案 5 :(得分:0)

android 5及更高版本中的解决方案使用AlarmManger和Broadcast Receiver