代码之家  ›  专栏  ›  技术社区  ›  gpuser

android中的gps定位更新

  •  0
  • gpuser  · 技术社区  · 7 年前

    在android中,使用前台服务在后台获取gps位置更新的最佳方式是什么?

    1 回复  |  直到 7 年前
        1
  •  0
  •   gpuser    7 年前

    每当应用程序在后台运行时,它都会消耗设备的一些有限资源,如ram。这可能会导致用户体验受损,特别是当用户使用资源密集型应用程序(如玩游戏或观看视频)时。为了改善用户体验,android 8.0(api级别26)对应用程序在后台运行时可以做什么施加了限制。

    • 您可以在后台使用前台服务和notifcation通道进行位置更新,它将在api级别26的上面和下面完美工作。
    • 我已经开发了下面的代码,它在我这边运行良好。

      希望对你有帮助

    (1)请在项目的manifest.xml文件中放入下面的代码行

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application>
    <service
            android:name="com.yourpackagename.location.LocationTracker"
            android:stopWithTask="true"
            />
    </application>
    

    (2)app.gradle文件

    implementation 'com.google.android.gms:play-services-location:16.0.0'
    

    (2)请将服务类代码放在项目的下面,可以将位置结果(lat,long)保存在共享的首选项或静态变量中,也可以在需要时绑定服务。

    public class LocationTracker extends Service implements
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener {
    
        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 GoogleApiClient mGoogleApiClient;
    
        private final int NOTIFICATION_ID = 9083150;
        private final String CHANNEL_ID = "test123";
        private final String CHANNEL_ID_NAME = "test123";
    
        @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(Constant.CHANNEL_ID);
                    notificationManager.createNotificationChannel(channel);
    
                    Notification notification = createNotification(getApplicationContext(),Constant.CHANNEL_ID,0);
                    if (notification == null) {
                        notification = new NotificationCompat.Builder(this, Constant.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)
                        .setContentText("TEST")
                        .setOnlyAlertOnce(true)
                        .setOngoing(true)
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .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);
                        //You can put location in sharedpreferences or static varibale and can use in app where need
                    }
    
                    @Override
                    public void onLocationAvailability(LocationAvailability locationAvailability) {
                        super.onLocationAvailability(locationAvailability);
                    }
                };
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        private void init() {
            try {
                setLocationUpdateCallback();
                buildGoogleApiClient();
                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();
            }
        }
    
        protected synchronized void buildGoogleApiClient() {
            try {
                mGoogleApiClient = null;
                mGoogleApiClient = new GoogleApiClient.Builder(this)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .addApi(LocationServices.API).build();
    
                mGoogleApiClient.connect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            init();
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
        @Override
        public void onConnected(@Nullable Bundle bundle) {
            startLocationUpdates();
        }
    
        public void requestingLocationUpdates() {
            try {
                mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                        mLocationCallback, Looper.myLooper());
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        protected void startLocationUpdates() {
            try {
                if (mGoogleApiClient != null) {
                    mSettingsClient
                            .checkLocationSettings(
                                    mLocationSettingsRequest)
                            .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                                @SuppressLint("MissingPermission")
                                @Override
                                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                                    Log.e(TAG, "LocationSettingsStatusCodes onSuccess");
                                    requestingLocationUpdates();
                                }
                            })
                            .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");
                                            requestingLocationUpdates();
                                            break;
                                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                            Log.e(TAG, "LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE");
                                    }
                                }
                            });
                }
    
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onConnectionSuspended(int i) {
    
        }
    
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    
        }
    
        @Override
        public void onDestroy() {
            WakeLocker.releasePartialLock();
            super.onDestroy();
        }
    
        @Override
        public void onTaskRemoved(Intent rootIntent) {
            super.onTaskRemoved(rootIntent);
        }
    
        public void stopLocationService(Context context) {        
            try {      
                stopForeground(true);
                stopSelf();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        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();
            }
        }
    }
    
    推荐文章