android - 从最近的任务中删除应用程序后,服务将重新启动
问题描述
我正在开发一个用于在后台服务中获取用户位置的应用程序。我的情况如下
- 用户去一个活动并运行一个后台服务。
- 服务必须在 5000 毫秒内获取用户位置,并将此数据发送给调用者活动并显示给用户。
- 用户从最近的任务中删除应用程序。
- 服务通常必须收集用户位置数据周期 5000 毫秒。
- 当用户返回应用程序时,必须看到自己从开始到当前位置的步行位置。
我在谷歌上搜索了这个并找到了答案,但是当我使用他们的解决方案时,我的服务将在我回到应用程序后重新启动,并在应用程序被销毁时向我发送空数据。
我的服务
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
我的活动
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
do stuff;
}
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(
MyService.NOTIFICATION));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
解决方案
这是跟踪服务,它使用融合位置 api 跟踪您的位置,并且在应用程序关闭并将数据发送到 firebase 时也会启动,您可以跟踪您想要的方式
public class TrackingService extends Service implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
DatabaseReference ref = FirebaseDatabase.getInstance().getReference(Constant.DISPATCHER_LOCATION);
private DatabaseReference mDatabase;
private static String TAG = "MyService";
@Override
public void onCreate() {
super.onCreate();
mDatabase = FirebaseDatabase.getInstance().getReference(Constant.TBL_USER);
Log.d(TAG, "onCreate");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
protected void createLocationRequest() {
Log.d(TAG, "onCreateLocationRequest");
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(7000).setFastestInterval(5000);
;
}
public void startTracking() {
if (mGoogleApiClient != null) {
startLocationUpdates(getApplicationContext());
// Toast.makeText(this, "start tracking", Toast.LENGTH_LONG).show();
}
}
public void stopTracking() {
if (mGoogleApiClient != null) {
try {
Log.d(TAG, "onStop fired ..............");
stopLocationUpdates();
} catch (Exception e) {
ref.getParent().child(Constant.TBL_USER).child(new SaveInSharedPreference(this).getString(Constant.CURRENT_USER)).child("dispatcher").setValue(false);
Intent i = new Intent(this, UserWelcome.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
}
protected void startLocationUpdates(Context context) {
if (mGoogleApiClient.isConnected()) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
}
}
protected void stopLocationUpdates() {
try {
// stop update location
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
// mGoogleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
} catch (Exception e) {
ref.getParent().child(Constant.TBL_USER).child(new SaveInSharedPreference(this).getString(Constant.CURRENT_USER)).child("dispatcher").setValue(false);
Intent i = new Intent(this, UserWelcome.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
try {
stopTracking();
} catch (Exception e) {
ref.getParent().child(Constant.TBL_USER).child(new SaveInSharedPreference(this).getString(Constant.CURRENT_USER)).child("dispatcher").setValue(false);
Intent i = new Intent(this, UserWelcome.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}
@Override
public void onLocationChanged(final Location location) {
Constant.CURRENT_LOCATION = new LatLng(location.getLatitude(), location.getLongitude());
if (!new SaveInSharedPreference(getApplicationContext()).getString(Constant.CURRENT_USER).equals("no")) {
mDatabase.child(new SaveInSharedPreference(getApplicationContext()).getString(Constant.CURRENT_USER)).child("lat").setValue(location.getLatitude());
mDatabase.child(new SaveInSharedPreference(getApplicationContext()).getString(Constant.CURRENT_USER)).child("lon").setValue(location.getLongitude());
if (new SaveInSharedPreference(this).getString(Constant.ACCEPT_ORDER).equals("no")) {
mDatabase.child(new SaveInSharedPreference(getApplicationContext()).getString(Constant.CURRENT_USER)).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
firebaseUserModal firebaseUserModal = dataSnapshot.getValue(firebaseUserModal.class);
if (firebaseUserModal.isDispatcher()) {
GeoFire geoFire = new GeoFire(ref);
geoFire.setLocation(new SaveInSharedPreference(getApplicationContext()).getString(Constant.CURRENT_USER), new GeoLocation(location.getLatitude(), location.getLongitude()), new GeoFire.CompletionListener() {
@Override
public void onComplete(String key, DatabaseError error) {
if (error != null) {
System.err.println("There was an error saving the location to GeoFire: " + error);
} else {
System.out.println("Location saved on server successfully!");
}
}
});
} else {
mDatabase.getParent().child(Constant.DISPATCHER_LOCATION)
.child(new SaveInSharedPreference(getApplicationContext())
.getString(Constant.CURRENT_USER))
.removeValue();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startTracking();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed: " + connectionResult.toString());
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
try {
GooglePlayServicesUtil.getErrorDialog(status, (Activity) getApplicationContext(), 0).show();
} catch (Exception ex) {
Log.e("error", ex.getMessage());
}
return false;
}
}
}
推荐阅读
- android - 我的 RecyclerView 不断重复相同的项目(Kotlin)
- windows - MongoDB:在 Windows 上安装 MongoDB 作为在 WAMP 上使用的服务不使用 conf 文件?
- python - python中是否存在while循环?
- android - 如何在没有通知的情况下启动后台服务?
- c# - 如何将文本文件中的一行存储到固定大小的数组中
- c - 在使用 lldb 调试 macOS 应用程序时,是否可以通过观察点观察寄存器的内容以进行更改?
- java - 用Java实现模型-视图-控制器的不同风格
- angular - Angular AsyncValidator 不能按我的意愿工作
- python - 当 fps 高于 15 时 Pygame 蛇速度太高
- numpy - 当某些数据丢失时,NumPy 如何重塑?