android - 使用谷歌播放服务和 FusedLocationProviderClient 的位置更新

标签 android google-play-services android-location fusedlocationproviderapi google-location-services

我想使用最新的融合位置提供程序客户端在“后台服务”上获取位置更新。我不想使用所有人都在使用的位置监听器和 Google API 客户端。 我还需要使用 google play 服务提供的位置设置 Api 来检查该“后台服务”上的位置设置是禁用还是启用。请帮忙。

最佳答案

如果我们需要使用 fusion location api,那么我们需要使用 Google API 客户端,对于后台服务,使用它不是问题,以下是我用于在后台获取位置更新的示例,但还有一个由于 Google 从 6.0 开始引入了“打瞌睡”模式,因此我无法保证在您的设备处于“打瞌睡”模式时提供更新,

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.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

/**
 * Created By Dhaval Solanki
 */

public class ConnectionService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    String TAG = "ConnectionService";


    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private Location previousLocation;
    public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
    public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
            UPDATE_INTERVAL_IN_MILLISECONDS / 2;


    private Location mLastLocation;
    private Context context;

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind");
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        context = getApplicationContext();
        Log.i(TAG, "onStartCommand");
        if (checkPermsion(context)) {
            setupLocationService(context);
        }
        return Service.START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        ApplicationCLass.isServiceRunning = true;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "onUnbind");
        ApplicationCLass.isServiceRunning = false;
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        ApplicationCLass.isServiceRunning = false;
        super.onDestroy();
    }

    private void setupLocationService(Context context) {
        if (checkPlayServices()) {
            mGoogleApiClient = new GoogleApiClient.Builder(context)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
            createLocationRequest();
        }
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest().create();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        mGoogleApiClient.connect();
    }

    public boolean checkPermsion(Context context) {
        int MyVersion = Build.VERSION.SDK_INT;
        if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return false;
            } else if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return false;
            } else {
                return true;
            }
        } else {
            return true;
        }
    }

    private boolean checkPlayServices() {
        GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
        int result = googleAPI.isGooglePlayServicesAvailable(this);
        if (result != ConnectionResult.SUCCESS) {
            return false;
        }
        return true;
    }


    private void startLocationUpdates() {
        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) {
                return;
            }
            if (Prefs.getUserLat(context).trim().length() > 0 && Prefs.getUserLong(context).trim().length() > 0) {
            } else {
                mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                        mGoogleApiClient);
                if (mLastLocation != null) {
                    Prefs.setUserLat(context, String.valueOf(mLastLocation.getLatitude()));
                    Prefs.setUserLong(context, String.valueOf(mLastLocation.getLongitude()));
                }
            }
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.i(TAG, "Connected to onConnected");
        startLocationUpdates();
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.i(TAG, "Connected to onConnectionSuspended");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.i(TAG, "Connected to onConnectionFailed");
    }

    @Override
    public void onLocationChanged(Location location) {
        try {
            Logger.print("onLocationChanged", "latitued :" + location.getLatitude() + " ,, Longitude " + location.getLongitude());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}

另一个警报服务是否继续运行

import android.app.ActivityManager;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class AlarmService extends IntentService {
    @Override
    protected void onHandleIntent(Intent intent) {
        boolean isServiceRunning = false;
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (ConnectionService.class.getName().equals(service.service.getClassName())) {
                isServiceRunning = true;
                break;
            }
        }
        Log.i("AlarmService", "Service is running " + isServiceRunning);
        if(!isServiceRunning) {
            startService(new Intent(getApplicationContext(),ConnectionService.class));
        } else {
            ConnectionService.checkConnectionAndConnect(getApplicationContext());
        }
    }

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     */
    public AlarmService() {
        super("AlaramService");
    }
}

最后开始服务

private void checkAndStartService() {
        final ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        new AsyncTask<Void, Void, Boolean>() {
            boolean isServiceRunning = false;

            @Override
            protected Boolean doInBackground(Void... params) {
                for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
                    if (ConnectionService.class.getName().equals(service.service.getClassName())) {
                        isServiceRunning = true;
                        break;
                    }
                }
                return isServiceRunning;
            }

            @Override
            protected void onPostExecute(Boolean aBoolean) {
                super.onPostExecute(aBoolean);
                Log.i("onPostExecute", "Service running = " + aBoolean);
                if (!aBoolean) {
                    startService(new Intent(ActivitySplash.this, ConnectionService.class));
                    Intent i = new Intent(ActivitySplash.this, AlarmService.class);
                    PendingIntent pi = PendingIntent.getService(ActivitySplash.this, 0, i, 0);
                    AlarmManager am = (AlarmManager) ActivitySplash.this.getSystemService(Context.ALARM_SERVICE);
                    am.cancel(pi); // cancel any existing alarms
                    am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60000, pi);
                }
            }
        }.execute();
    }

关于android - 使用谷歌播放服务和 FusedLocationProviderClient 的位置更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45973778/

相关文章:

具有 Google Play 服务位置的 Android 服务导致应用程序随机打开

java - 如何调用 onCreateView 方法或刷新我的 fragment ?

android - 如何从以特定时间间隔分隔的 N 个连接的音频样本生成音频文件?

android - 使用属性文件签名的 Gradle Android Studio

android - 如何取消应用程序与谷歌驱动器帐户的链接

android - InterstitialAd 未被识别为 Android Studio 和 libgdx 的一类

java - 如何停止位置自动更新

android - 模拟器不显示在 ddms 的设备 View 中

java - ADT 升级后,Google map View 不再加载;明显的身份验证问题?

java - Android 10 (Q) ACCESS_BACKGROUND_LOCATION 权限