Android Activity 不会停止服务和位置更新

Posted

技术标签:

【中文标题】Android Activity 不会停止服务和位置更新【英文标题】:Android Activity doesn't stop service and location updates 【发布时间】:2020-01-28 08:49:38 【问题描述】:

我正在使用 google api 客户端跟踪 MainActivity 中用户的当前位置并更新当前位置的标记。在服务中,我跟踪用户的当前位置并将其存储到 firebase 实时数据库。

MainActivity 中,我使用按钮停止服务,方法是断开 api 客户端以及停止服务。

根据类似的问题,我已经在我的服务中实现了 ondestroy。仍然在 api 客户端断开连接后,服务正在运行并将位置存储到 firebase。

如何停止此服务?

地图活动:

protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    process = (Button)findViewById(R.id.buttonMaps);
    stoptrek = (Button) findViewById(R.id.buttonService);

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
        checkLocationPermission();
    
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    process.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            Toast.makeText(MapsActivity.this,"processing...",Toast.LENGTH_SHORT).show();
            Intent i = new Intent(MapsActivity.this,MapsActivity2.class);
            MapsActivity.this.startActivity(i);
            finishActivity(1);

        
    );

    stoptrek.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            stopTrackerService();
            stopService(new Intent(MapsActivity.this, TrackingService.class));
            Toast.makeText(MapsActivity.this, "GPS tracking disabled", Toast.LENGTH_SHORT).show();
        
    );


public void onMapReady(GoogleMap googleMap) 
    mMap = googleMap;
    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
            startTrackerService();
        
    
    else 
        buildGoogleApiClient();
        mMap.setMyLocationEnabled(true);
        startTrackerService();
    



public void stopTrackerService()

    if(mGoogleApiClient.isConnected())
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) MapsActivity.this);
        mGoogleApiClient.disconnect();
        Toast.makeText(MapsActivity.this,"Disconnected api client",Toast.LENGTH_SHORT).show();
    
    else
        Toast.makeText(MapsActivity.this,"api client is already disconnected",Toast.LENGTH_SHORT).show();

服务:

公共类 TrackingService 扩展服务

FusedLocationProviderClient client;

private static final String TAG = TrackingService.class.getSimpleName();

public TrackingService() 


@Override
public IBinder onBind(Intent intent) 
    return null;


@Override
public void onCreate() 
    super.onCreate();
    buildNotification();
    loginToFirebase();

@Override
public void onDestroy()

    stopSelf();


//Create the persistent notification//

private void buildNotification() 
    String stop = "stop";
    // Create the persistent notification
    Notification.Builder builder = new Notification.Builder(this)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(getString(R.string.tracking_enabled_notif))
            .setOngoing(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) 
        startForeground(1, builder.build());
    


private void loginToFirebase() 

    String email = "xyz@sdl.com";//getString(R.string.test_email);
    String password = "xyz123";//getString(R.string.test_password);


    FirebaseAuth.getInstance().signInWithEmailAndPassword(
            email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() 
        @Override
        public void onComplete(Task<AuthResult> task) 


            if (task.isSuccessful()) 

                requestLocationUpdates();
             else 
                Log.d(TAG, "Firebase authentication failed");
            
        
    );


private void requestLocationUpdates() 
    LocationRequest request = new LocationRequest();
    request.setInterval(5000);

    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    client = LocationServices.getFusedLocationProviderClient(this);
    final String path = "location";
    int permission = ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);

    if (permission == PackageManager.PERMISSION_GRANTED) 

        client.requestLocationUpdates(request, new LocationCallback() 
            @Override
            public void onLocationResult(LocationResult locationResult) 
                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                String uid = user.getUid();

                DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
                Location location = locationResult.getLastLocation();
                if (location != null) 
                    Toast.makeText(TrackingService.this,"recently add to DB",Toast.LENGTH_SHORT).show();
                    ref.child(uid).child(path).push().setValue(location);
                
            
        , null);
    

我有地图活动,我与 googleapiclient 断开连接,但即使在停止位置更新和服务之后,位置也会被推送到数据库中。

请告诉我如何完全停止服务。 谢谢

【问题讨论】:

因为你没有停止后台服务 我该如何阻止它?我在服务运行时显示通知,当服务停止时,通知不存在。但我可以看到值被推入数据库。 等我贴出停止服务的代码 是的,当然!谢谢。 看看我的回答。 【参考方案1】:

此方法检查服务是否正在运行。如果服务正在运行,则返回 true,否则返回 false。

检查运行服务:

public static boolean isServiceRunning(Context context, Class<?> cls) 
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    if (activityManager != null) 
        for (ActivityManager.RunningServiceInfo runningServiceInfo : activityManager.getRunningServices(Integer.MAX_VALUE)) 
            if (cls.getName().equals(runningServiceInfo.service.getClassName())) 
                return true;
            
        
    
    return false;

停止运行服务:

ActivityStackManager.getInstance().stopLocationService(TrackingService.this);

工作原理:

if (isServiceRunning(this, TrackingService.class)) 
    ActivityStackManager.getInstance().stopLocationService(TrackingService.this);

注意:在您想断开位置更新的位置也停止服务,我可以看到您正在断开位置更新 stopTrackerService() 方法

例如:

  public void stopTrackerService()
    

    if (isServiceRunning(this, TrackingService.class)) 
        ActivityStackManager.getInstance().stopLocationService(TrackingService.this);
    

    if(mGoogleApiClient.isConnected())
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) MapsActivity.this);
            mGoogleApiClient.disconnect();
            Toast.makeText(MapsActivity.this,"Disconnected api client",Toast.LENGTH_SHORT).show();
    
     else
            Toast.makeText(MapsActivity.this,"api client is already disconnected",Toast.LENGTH_SHORT).show();
    

ActivityStackManager

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;

public class ActivityStackManager 

    private static final ActivityStackManager mActivityStack = new ActivityStackManager();

    private ActivityStackManager() 
    

    public static ActivityStackManager getInstance() 
        return mActivityStack;
    

    public void stopLocationService(Context context) 
        if (isServiceRunning(context, TrackingService.class)) 
            context.stopService(new Intent(context, LocationService.class));
            Log.e("StackManager", "TrackingServiceStop");
        
    

    public void startLocationService(Context context)
        Intent serviceIntent = new Intent(context, TrackingService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
            context.startForegroundService(serviceIntent);
         else 
            context.startService(serviceIntent);
        
    

【讨论】:

如果有帮助请告诉我。 是的,实现它。 我有 android studio v 对不起,我忘记添加那个类了,这是我为服务而写的单例类。 请通过 ActivityStackManager 中的 isServiceRunning...我刚刚从我的项目中提取了一段代码,这就是为什么它丢失了一些代码

以上是关于Android Activity 不会停止服务和位置更新的主要内容,如果未能解决你的问题,请参考以下文章

即使 Activity 已销毁,AsyncTask 也不会停止

8) 十分钟学会android--Activity的生命周期之停止与重启

25.Android开发艺术探究Note

没有活动的 Android 应用程序即服务

没有活动的 Android 应用程序即服务

android:当Activity和Service 都被销毁后,如何控制其中生成的线程?