如何创建具有间隔时间的后台服务
How to create a background Service with a interval time
在我的项目中我需要:
- 获取用户位置(纬度和经度)。
- 发送到我的API。
- 收到回复。
这一切都在 15 秒之间。我已经知道如何做这些事情,但它必须在后台。我使用的 JobSchedule
非常完美,它可以处理一切,连接、网络状态和时间,但问题是,它与旧版本 > 21 不兼容!
在这些条件下(后台请求和位置)最好的方法是 GCMNetworkManager
?谢谢!
这就是你的做法:
<service
android:name=".GeoLocationService"
android:exported="false" />
服务:
import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
public class GeoLocationService extends Service {
public static final String LOCATION_UPDATE =
GeoLocationService.class.getSimpleName();
public static final String LOCATION_DATA = "location_data";
private static final String TAG = GeoLocationService.class.getSimpleName();
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 10000; // 30 Seconds
private static final float LOCATION_DISTANCE = 1f; // meters = 100 m
public static void start(Context context) {
context.startService(new Intent(context, GeoLocationService.class));
}
public static void stop(Context context) {
context.stopService(new Intent(context, GeoLocationService.class));
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location) {
mLastLocation.set(location);
Log.i(TAG, "Location Changed! " + location.getLatitude() + " " + location.getLongitude());
Intent intent = new Intent(LOCATION_UPDATE);
intent.putExtra(LOCATION_DATA, location);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
if (checkLocationPermission()) {
mLocationManager.removeUpdates(mLocationListeners[i]);
}
} catch (Exception ex) {
}
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private boolean checkLocationPermission() {
if (Build.VERSION.SDK_INT < 23)
return true;
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
return ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
}
在你的 Activity:
private BroadcastReceiver mLocationUpdateMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Location location = intent.getParcelableExtra(GeoLocationService.LOCATION_DATA);
//SEND LOCATION TO YOUR API HERE
}
};
@Override
protected void onResume() {
super.onResume();
GeoLocationService.start(this);
LocalBroadcastManager.getInstance(context).registerReceiver(mLocationUpdateMessageReceiver,
new IntentFilter(GeoLocationService.LOCATION_UPDATE));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocationUpdateMessageReceiver);
GeoLocationService.stop(this);
super.onPause();
}
在我的项目中我需要:
- 获取用户位置(纬度和经度)。
- 发送到我的API。
- 收到回复。
这一切都在 15 秒之间。我已经知道如何做这些事情,但它必须在后台。我使用的 JobSchedule
非常完美,它可以处理一切,连接、网络状态和时间,但问题是,它与旧版本 > 21 不兼容!
在这些条件下(后台请求和位置)最好的方法是 GCMNetworkManager
?谢谢!
这就是你的做法:
<service
android:name=".GeoLocationService"
android:exported="false" />
服务:
import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
public class GeoLocationService extends Service {
public static final String LOCATION_UPDATE =
GeoLocationService.class.getSimpleName();
public static final String LOCATION_DATA = "location_data";
private static final String TAG = GeoLocationService.class.getSimpleName();
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 10000; // 30 Seconds
private static final float LOCATION_DISTANCE = 1f; // meters = 100 m
public static void start(Context context) {
context.startService(new Intent(context, GeoLocationService.class));
}
public static void stop(Context context) {
context.stopService(new Intent(context, GeoLocationService.class));
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location) {
mLastLocation.set(location);
Log.i(TAG, "Location Changed! " + location.getLatitude() + " " + location.getLongitude());
Intent intent = new Intent(LOCATION_UPDATE);
intent.putExtra(LOCATION_DATA, location);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
if (checkLocationPermission()) {
mLocationManager.removeUpdates(mLocationListeners[i]);
}
} catch (Exception ex) {
}
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private boolean checkLocationPermission() {
if (Build.VERSION.SDK_INT < 23)
return true;
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
return ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
}
在你的 Activity:
private BroadcastReceiver mLocationUpdateMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Location location = intent.getParcelableExtra(GeoLocationService.LOCATION_DATA);
//SEND LOCATION TO YOUR API HERE
}
};
@Override
protected void onResume() {
super.onResume();
GeoLocationService.start(this);
LocalBroadcastManager.getInstance(context).registerReceiver(mLocationUpdateMessageReceiver,
new IntentFilter(GeoLocationService.LOCATION_UPDATE));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocationUpdateMessageReceiver);
GeoLocationService.stop(this);
super.onPause();
}