您好我正面临android下的位置API问题/问题
电池消耗高达30% - 40%,导致大量电池耗尽。
状态栏中的位置图标始终为ON,即使应用已关闭且应用程序已卸载,它也会自动关闭。
要求:
方法:
使用GPS
API使用具有待定意图的FUSED LOCATION API。
LocationManager - 检查GPS开/关的状态。
代码walkthru:
在OnCreate中获取位置管理器实例 - 获取位置管理器的实例。
检查是启用GPS还是网络状态可用,否则显示对话框以启用位置:代码: -
// get GPS state.
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (isGPSLocationEnabled(locationManager)) {
buildGooleLocationApiClient();
} else if (isNetworkLocationEnabled(locationManager)) {
buildGooleLocationApiClient();
} else {
showAlert();
}
goolgeLocationAPiClient的代码:在这个方法中,我正在检查android版本,请求权限和启用服务
private void buildGooleLocationApiClient() {
if (Build.VERSION.SDK_INT >= 23) {
int isFineLocationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
int isCoarseLocationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
if (isFineLocationPermission == PackageManager.PERMISSION_DENIED || isCoarseLocationPermission == PackageManager.PERMISSION_DENIED) {
requestPermission();
} else {
checkGoogleLocationApiClient();
}
} else {
checkGoogleLocationApiClient();
}
}
构建GoogleAPI客户端:
private void checkGoogleLocationApiClient() {
try {
if (mGoogleApiClient != null) {
if (mGoogleApiClient.isConnected()) {
getMyLocationCampaigns();
} else {
mGoogleApiClient.connect();
}
} else {
buildGoogleApiClient();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void getMyLocationCampaigns() {
if (mCurrentLocation != null) {
getData(mCurrentLocation.getLatitude()+"",mCurrentLocation.getLongitude()+"");
} else {
try {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
getData(mCurrentLocation.getLatitude()+"",mCurrentLocation.getLongitude()+"");
} catch (SecurityException ex) {
ex.printStackTrace();
getData("","");
}
}
}
private synchronized void buildGoogleApiClient() {
try {
Log.i(TAG, "activity Building GoogleApiClient===");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
} catch (Exception e) {
e.printStackTrace();
getData("","");
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(60 * 60 * 1000);
mLocationRequest.setFastestInterval(60 * 1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setSmallestDisplacement(100);
connectGoogleApiClient();
}
private void connectGoogleApiClient() {
if (mGoogleApiClient != null) {
if (!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
}
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (mCurrentLocation == null) {
try {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mCurrentLocation != null) {
// MyAPICALL getData(mCurrentLocation.getLatitude()+"",mCurrentLocation.getLongitude()+"");
} else {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest, this);
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mCurrentLocation == null) {
if (locationManager != null) {
String provider = Utils.getUserLastLocation(locationManager);
if (provider != null) {
try {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
getData(location.getLatitude() + "", location.getLongitude() + "");
} else {
getData("", "");
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
} else {
getData(mCurrentLocation.getLatitude()+"",mCurrentLocation.getLongitude()+"");
}
}
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
getData("","");
}
}
}
具有待定意图的背景中的getlocation方法
private void startLocationUpdates() {
try {
Intent receiverIntentService = new Intent(this, LocationIntentService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 1, receiverIntentService, 0);
if (mGoogleApiClient != null) {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, pendingIntent);
}
}
} catch (SecurityException se) {
se.printStackTrace();
}
}
BroadCastReceiver:如果设备重新启动:
public class LocationBroadcastReceiver extends BroadcastReceiver implements
GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener, LocationListener {
Context context;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
public static Boolean mRequestingLocationUpdates = false;
SharedPreferences checkUserStatus;
public LocationBroadcastReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
try {
this.context = context;
checkUserStatus = context.getSharedPreferences(Params.LOGIN_DETAILS_PREFERENCE, 0);
String isUserLogedIn = checkUserStatus.getString(Params.TOKEN,"");
// if user is still logged in then only trigger background service
if (!isUserLogedIn.equals("")) {
buildGoogleApiClient();
if (mGoogleApiClient != null) {
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
} else {
buildGoogleApiClient();
}
} else {
buildGoogleApiClient();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i("Broadcast receiver", "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(60 * 60 * 1000);
mLocationRequest.setFastestInterval(60 * 1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setSmallestDisplacement(100);
}
protected void startLocationUpdates() {
try {
Intent receiverIntentService = new Intent(context,LocationIntentService.class);
PendingIntent pendingIntent = PendingIntent.getService(context,1,receiverIntentService,0);
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, pendingIntent);
}catch (SecurityException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
我的意向服务类:获取用户更新的位置并进行API调用
public class LocationIntentService extends IntentService {
Context context;
Bitmap myBitmap;
URL url;
SharedPreferences.Editor mMyLastLocationHolder;
SharedPreferences mMyLastLocation;
SharedPreferences checkUserStatus;
public LocationIntentService() {
super("LocationIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Location location = bundle.getParcelable("com.google.android.location.LOCATION");
if (location != null) {
context = getApplicationContext();
// API call to server
updateAPI(location.getLatitude()+"",location.getLongitude()+"");
Log.v("TAG LOCATION ", " ==== " + location.getLatitude() + " - " + location.getLongitude() + " ==== ");
Log.v("TAG LOCATION ", " ==== calling my-campaigns near me ========");
}
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionFoo(String param1, String param2) {
// TODO: Handle action Foo
throw new UnsupportedOperationException("Not yet implemented");
}
/**
* Handle action Baz in the provided background thread with the provided
* parameters.
*/
private void handleActionBaz(String param1, String param2) {
// TODO: Handle action Baz
throw new UnsupportedOperationException("Not yet implemented");
}
}
答案 0 :(得分:0)
我希望这可以帮助您找到最佳解决方案/方法。
个人更喜欢使用具有特定优先级和间隔的GoogleApiClient和LocationRequest。 编写实现以下接口的服务:
LocationListener的
public class PositionService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {}
使用GoogleApiClient和LocationRequest类。
进入 onCreate() 实例化GoogleApiClient对象,LocationRequest对象并使mGoogleApiClient连接。
public void onCreate() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(mInterval).setFastestInterval(mFastInterval);
mGoogleApiClient.connect();
}
进入 onDestroy() 方法,使mGoogleApiClient断开连接
@Override
public void onDestroy() {
mGoogleApiClient.disconnect();
}
现在实现接口
@Override
public void onLocationChanged(Location location) {
Log.d("NewLocation", location.toString());
}
@Override
public void onConnected(@Nullable Bundle bundle) throws SecurityException {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
现在GoogleApiClient会根据LocationRequest的设置通知您调用 onLocationChanged() 回调的位置
您的业务逻辑应放在 onLocationChanged() 方法中。只需为LocationRequest选择一个良好的间隔时间和优先级。 (见documentation)
请参阅有关location strategies的官方文档,我的解决方案就是基于此。
我习惯于在Foreground中启动服务以防止操作系统出现意外行为(例如服务被杀)
答案 1 :(得分:0)
这只会向您解释更好的逻辑
而不是长时间运行的服务或IntentService只需使用Firebase JobDispatcher或任何第三方lib Jobscheduler API,以便将所有位置更新代码移动到Jobscheduler(https://github.com/googlesamples/android-JobScheduler/blob/master/Application/src/main/java/com/example/android/jobscheduler/service/MyJobService.java)
根据您的位置更新间隔启动作业,根据您的要求配置或更改作业!与长期运行的服务相比,它确实是一个更好的解决方案!!!(您可以在Activity或片段中使用eventBus或RxBus进行位置更新!!)
提示:每次作业开始时,在作业关闭之前触发位置更新设置一些系统延迟3秒或更长时间,因为有些时候Googleapiclient需要更多时间来更新延迟后更新新的GPS时间您可以使用正在运行的JobService关闭Googleapiclient所有不需要的回调。通过检测用户活动,使用Google Awareness Api或Google Fit API智能地控制作业配置!
一体化Job Jobscheduler Lib:https://github.com/evernote/android-job
P.S:代码将很快更新
答案 2 :(得分:0)
文档link
因此,当我遇到类似问题时,我所做的是:活动应该强烈考虑在何时删除所有位置请求 进入后台(例如在onPause()),或至少交换 要求更大的间隔和更低的质量。
这些步骤帮助我将应用的电池使用量从> 30%降低到<3%。