首页 > 解决方案 > 从最近的任务中删除应用程序后,服务将重新启动

问题描述

我正在开发一个用于在后台服务中获取用户位置的应用程序。我的情况如下

  1. 用户去一个活动并运行一个后台服务。
  2. 服务必须在 5000 毫秒内获取用户位置,并将此数据发送给调用者活动并显示给用户。
  3. 用户从最近的任务中删除应用程序。
  4. 服务通常必须收集用户位置数据周期 5000 毫秒。
  5. 当用户返回应用程序时,必须看到自己从开始到当前位置的步行位置。

我在谷歌上搜索了这个并找到了答案,但是当我使用他们的解决方案时,我的服务将在我回到应用程序后重新启动,并在应用程序被销毁时向我发送空数据。

我的服务

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

标签: androidservicebackground-service

解决方案


这是跟踪服务,它使用融合位置 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;
        }
    }
}

推荐阅读