【问题标题】:Getting GPS location updates while app in the background在后台应用程序时获取 GPS 位置更新
【发布时间】:2018-11-28 00:12:25
【问题描述】:

我有一个跟踪客户位置并每 10 秒发送一次位置的 android 应用程序,但是,在 android O 中,位置更新将每小时进行几次,如有关 android O 中 gps 位置更新限制的文档中所述. 无论如何,为了克服这个问题,我使用了带有通知的前台服务,以便 gps 位置更新在 fusedLocation 中不断更新。 之后,我遇到了另一个问题,fusedLocation 中的速度和方向为零,因为它从网络提供商和 gps 提供商那里获取位置,当位置来自网络提供商时,速度和方向为零,这些信息对我很重要,并且我将我的位置服务切换到 LocationManager 而不是 fusedLocation,因此我只能确定 gps 提供者,因为该功能在 fusedLocation 中不可用。 但是我注意到,即使我为此目的使用前台服务,android O 中的 LocationManager 在后台也不会获取位置更新。如何获得在后台不断更新位置并仅使用 gps 提供程序的解决方案?

我没有代码片段,我只是想讨论一下这个问题。

【问题讨论】:

    标签: android background gps location foreground-service


    【解决方案1】:

    试试下面的代码

    在 AndroidManifest.xml 中编写以下代码行

     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
    <application>
     <service
            android:name=".LocationTracker"
            android:stopWithTask="true"
            />
    </application>
    

    写下你想启动服务的那行代码

    LocationTracker.startLocationService(getApplicationContext());
    

    在服务类中编写以下代码

    public class LocationTracker extends Service{
    
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
    private static int DISPLACEMENT = 0;
    
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationRequest mLocationRequest;
    private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationCallback mLocationCallback;
    private String TAG = LocationTracker.class.getSimpleName();
    private final int NOTIFICATION_ID = 9083150;
    public static final String CHANNEL_ID = "CHANNEL_ID";
    public static final String CHANNEL_ID_NAME = "CHANNEL_ID_NAME";
    
    @Override
    public void onCreate() {
        super.onCreate();
        try {
            if (Build.VERSION.SDK_INT >= 26) {
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID_NAME,
                        NotificationManager.IMPORTANCE_HIGH);
                channel.setSound(null, null);
                channel.setShowBadge(false);
                NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.deleteNotificationChannel(CHANNEL_ID);
                notificationManager.createNotificationChannel(channel);
    
                Notification notification = createNotification(getApplicationContext(),CHANNEL_ID,0);
                if (notification == null) {
                    notification = new NotificationCompat.Builder(this, CHANNEL_ID).build();
                }
                startForeground(NOTIFICATION_ID, notification);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private Notification createNotification(Context context, String channelid,int type) {
        try {
            return new NotificationCompat.Builder(context,channelid)
                    .setContentTitle("")
                    .setContentText("")
                    .setOnlyAlertOnce(true)
                    .setOngoing(true)
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setCategory(NotificationCompat.CATEGORY_SERVICE)
                    .setVisibility(Notification.VISIBILITY_PRIVATE)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .build();
    
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    
    public void setLocationUpdateCallback() {
        try {
            mLocationCallback = null;
            mLocationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    super.onLocationResult(locationResult);
                    Logger.i(TAG, "locationResult ==== " + locationResult);
                }
            };
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    
    private void init() {
        try {
            setLocationUpdateCallback();
            mFusedLocationClient = null;
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
            mSettingsClient = LocationServices.getSettingsClient(this);
            mLocationRequest = null;
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
    
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            builder.addLocationRequest(mLocationRequest);
            mLocationSettingsRequest = null;
            mLocationSettingsRequest = builder.build();
    
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        init();
        startLocationUpdates();
        return START_STICKY;
    }
    
    @androidx.annotation.Nullable
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    protected void startLocationUpdates() {
        mSettingsClient
                .checkLocationSettings(
                        mLocationSettingsRequest)
                .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                    @SuppressLint("MissingPermission")
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                        Log.e(TAG, "LocationSettingsStatusCodes onSuccess");
                        mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                                mLocationCallback, Looper.myLooper());
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                Log.e(TAG, "LocationSettingsStatusCodes.RESOLUTION_REQUIRED");
                                mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                                        mLocationCallback, Looper.myLooper());
                                break;
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                Log.e(TAG, "LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE");
                        }
                    }
                });
    }
    
    public static void startLocationService(Context context) {
        try {
            Intent intent = new Intent(context, LocationTracker.class);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                ContextCompat.startForegroundService(context, intent);
            } else {
                context.startService(intent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    }

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多