【问题标题】:Some Times Location Service is not working in background有时定位服务无法在后台运行
【发布时间】:2018-07-14 06:49:57
【问题描述】:

我在我的android 应用程序中使用了Location Service,它扩展了Service 并实现了GoogleApiClient、LocationListener。我正在更新位置 onLocationChanged() 方法,我的位置更新间隔为 20 秒。有时即使应用程序在后台,定位服务也无法正常工作。无论如何,我想始终运行我的位置服务。每个版本的 Android 和每个手机,即使该应用程序也在后台杀戮。 我也使用 AlarmManager 调用位置服务。 我在 onStartCommand() 方法中调用了位置更新。 如果位置服务停止,那么它将再次转到该方法中的 onDestroy() 方法或 onTaskRemoved() 方法我正在调用 startLocation 方法,例如,

startService(new Intent(this, LocationService.class));

我的服务清单代码:

<service
        android:name=".LocationService"
        android:enabled="true"
        android:stopWithTask="false"
        />

【问题讨论】:

    标签: java android


    【解决方案1】:

    您可以创建如下位置服务。在后台和前台模式下运行

    public class ServiceLocation extends Service implements
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener,
            LocationListener {
    
        private static final String NOTIFICATION_CHANNEL_ID = "my_notification_location";
        private static final long TIME_INTERVAL_GET_LOCATION = 1000 * 5; // 1 Minute
        private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 7; // meters
    
        private Handler handlerSendLocation;
        private Context mContext;
    
        private GoogleApiClient mGoogleApiClient;
        private LocationRequest mLocationRequest;
    
        private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 5000;
    
        Location locationData;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
    
            // Create the LocationRequest object
            mLocationRequest = LocationRequest.create()
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setInterval(TIME_INTERVAL_GET_LOCATION)    // 3 seconds, in milliseconds
                    .setFastestInterval(TIME_INTERVAL_GET_LOCATION); // 1 second, in milliseconds
    
            mContext = this;
    
    
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                    .setOngoing(false)
                    .setSmallIcon(R.drawable.ic_notification)
                    .setColor(getResources().getColor(R.color.fontColorDarkGray))
                    .setPriority(Notification.PRIORITY_MIN);
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                        NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW);
                notificationChannel.setDescription(NOTIFICATION_CHANNEL_ID);
                notificationChannel.setSound(null, null);
                notificationManager.createNotificationChannel(notificationChannel);
                startForeground(1, builder.build());
            }
        }
    
        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            Log.w("Service Update Location", "BGS > Started");
    
            if (handlerSendLocation == null) {
                handlerSendLocation = new Handler();
                handlerSendLocation.post(runnableSendLocation);
                Log.w("Service Send Location", "BGS > handlerSendLocation Initialized");
            } else {
                Log.w("Service Send Location", "BGS > handlerSendLocation Already Initialized");
            }
    
            return START_STICKY;
        }
    
        private Runnable runnableSendLocation = new Runnable() {
    
            @Override
            public void run() {
    
    
                // You can get Location
                //locationData and Send Location X Minutes
                if (locationData != null) {
                    Intent intent = new Intent("GPSLocationUpdates");
                    intent.putExtra("Latitude", "" + locationData.getLatitude());
                    intent.putExtra("Longitude", "" + locationData.getLongitude());
    
    
                    LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
    
                    Log.w("==>UpdateLocation<==", "" + String.format("%.6f", locationData.getLatitude()) + "," +
                            String.format("%.6f", locationData.getLongitude()));
    
                    Log.w("Service Send Location", "BGS >> Location Updated");
                }
                if (handlerSendLocation != null && runnableSendLocation != null)
                    handlerSendLocation.postDelayed(runnableSendLocation, TIME_INTERVAL_GET_LOCATION);
            }
        };
    
    
        @Override
        public void onConnected(@Nullable Bundle bundle) {
            if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    
                return;
            }
    
    
            FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    locationData = locationResult.getLastLocation();
                }
            }, null);
        }
    
        @Override
        public void onConnectionSuspended(int i) {
    
        }
    
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
            if (connectionResult.hasResolution() && mContext instanceof Activity) {
                try {
                    Activity activity = (Activity) mContext;
                    connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                Log.i("", "Location services connection failed with code " + connectionResult.getErrorCode());
            }
        }
    
        @Override
        public void onLocationChanged(Location location) {
            Log.w("==>UpdateLocation<==", "" + String.format("%.6f", location.getLatitude()) + "," + String.format("%.6f", location.getLongitude()));
            locationData = location;
    
        }
    
        @Override
        public void onDestroy() {
    
            if (handlerSendLocation != null)
                handlerSendLocation.removeCallbacks(runnableSendLocation);
    
    
            Log.w("Service Update Info", "BGS > Stopped");
    
            stopSelf();
            super.onDestroy();
        }
    
    
    }
    

    在 android manifest 文件中声明此服务,如下所示

    <service
                android:name=".ServiceLocation"
                android:enabled="true"
                android:exported="true" />
    

    您可以使用此代码从活动中启动服务

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         ContextCompat.startForegroundService(MainActivity.this, new Intent(MainActivity.this, ServiceLocation.class));
     } else {
         startService(new Intent(MainActivity.this, ServiceLocation.class));
     }
    

    【讨论】:

      猜你喜欢
      • 2016-04-27
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 2022-07-27
      • 2018-10-31
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多