【发布时间】:2017-05-04 20:55:59
【问题描述】:
您好,我在 android 中遇到以下问题/问题与位置 API 相关
电池消耗高达 30% - 40%,导致大量电池消耗。
状态栏中的位置图标始终处于打开状态,即使在关闭应用和卸载应用时它也会自动关闭。
要求:
- 打开应用时需要用户位置。
- 即使应用程序未打开或未使用基于距离,我也需要用户位置 - 需要在后台使用用户位置。
方法:
带 GPS
API 使用 FUSED LOCATION API 和未决意图。
LocationManager - 检查 GPS 开/关状态。
代码演练:
在 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("","");
}
}
}
以待定意图在后台获取位置的方法
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");
}
}
【问题讨论】:
-
我正在使用 FusedLocationApi 做类似的事情(我使用了长时间运行的服务而不是 IntentService),并且我的电池使用量很少(每 3 分钟更新一次位置)。我怀疑您的问题更有可能来自 LocationManager。你能在没有它的情况下尝试破解吗?
标签: android android-intent gps android-location android-fusedlocation