我想实现一项服务,该服务将显示加载屏幕,直到GPS找不到位置。一段时间后,它显示警报并返回最后已知位置或基本线(0.0)。不幸的是,第一次读取是空的,无论GPS打开还是关闭,它都会保持这种状态。
GPS HANDLER
public class GPSLocation implements ConnectionCallbacks,OnConnectionFailedListener,
LocationListener,
GPSStatusReceiver.GpsStatusChangeListener{
public static final int REQUEST_CHECK_SETTINGS = 100;
public static final int LOCATION_PERMISSION_REQUEST_CODE = 200;
private static final int PERMISSION_GRANTED = 0;
private static final int PERMISSION_DENIED = 1;
private static final int PERMISSION_BLOCKED = 2;
private GoogleApiClient mGoogleApiClient;
private Location mCurrentLocation;
private LocationCallback mCallback;
private Activity mActivity;
private Context mContext;
private LocationRequest mLocationRequest;
private GPSStatusReceiver mGPSStatusReceiver;
private long intervalMillis = 10000;
private long fastestIntervalMillis = 5000;
private int accuracy = LocationRequest.PRIORITY_HIGH_ACCURACY;
private boolean isInitialized = false;
private boolean isLocationEnabled = false;
private boolean isPermissionLocked = false;
public GPSLocation(Activity activity, LocationCallback callback) {
mActivity = activity;
mContext = activity.getApplicationContext();
mCallback = callback;
//creating new client Api
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
createLocationRequest();
mGPSStatusReceiver = new GPSStatusReceiver(mContext, this);
}
public void init(){
isInitialized = true;
if(mGoogleApiClient != null) {
if (mGoogleApiClient.isConnected()) {
requestPermission();
} else {
connect();
}
}
}
public void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(intervalMillis);
mLocationRequest.setFastestInterval(fastestIntervalMillis);
mLocationRequest.setPriority(accuracy);
}
public LocationRequest getLocationRequest() {
return mLocationRequest;
}
public void connect(){
if(mGoogleApiClient != null && isInitialized) {
mGoogleApiClient.connect();
}
}
public void disconnect(){
if(mGoogleApiClient != null && isInitialized) {
mGoogleApiClient.disconnect();
}
}
private void getLastKnownLocation(){
if(!mGoogleApiClient.isConnected()){
Log.i(TAG, "getLastKnownLocation restart ");
mGoogleApiClient.connect();
}
else {
if (checkLocationPermission(mContext) && isLocationEnabled) {
Log.i(TAG, "getLastKnownLocation read ");
if(mCurrentLocation==null){
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mCallback.onLastKnowLocationFetch(mCurrentLocation);
Log.i(TAG,"mCurrentLocation is "+mCurrentLocation);
}
startLocationUpdates();
}else{
Log.i(TAG, "getLastKnownLocation get permission ");
requestPermission();
}
}
Log.i(TAG, "mCurrentLocation " + mCurrentLocation);
}
public void startLocationUpdates() {
if(checkLocationPermission(mContext)
&& mGoogleApiClient != null
&& mGoogleApiClient.isConnected()
&& isLocationEnabled) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
public void stopLocationUpdates() {
if(mGoogleApiClient != null
&& mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (checkLocationPermission(mContext) && isLocationEnabled) {
Log.i(TAG, "getLastKnownLocation read ");
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
if(mCurrentLocation == null ) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mCallback.onLastKnowLocationFetch(mCurrentLocation);
}
startLocationUpdates();
}
Log.i(TAG, "onConnected");
mCallback.onLocationUpdate(mCurrentLocation);
requestPermission();
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "onConnectionSuspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.i(TAG, "onConnectionFailed");
}
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "onLocationChanged : " + location);
if(location!=null)
mCallback.onLocationUpdate(location);
}
@Override
public void onGpsStatusChange() {
Log.i(TAG, "onGpsStatusChange");
if(isInitialized && !isPermissionLocked) {
if (!isLocationEnabled(mContext)) {
isLocationEnabled = false;
isPermissionLocked = true;
stopLocationUpdates();
requestPermission();
}
}
}
private void requestPermission(){
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
String[] appPerm = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
ActivityCompat.requestPermissions(mActivity, appPerm, LOCATION_PERMISSION_REQUEST_CODE);
}else{
getLocationSetting();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GPSLocation.REQUEST_CHECK_SETTINGS) {
if (resultCode == Activity.RESULT_OK) {
getLastKnownLocation();
}else{
Toast.makeText(mContext, "Permission Denied", Toast.LENGTH_SHORT).show();
mCallback.onLocationSettingsError();
}
}
}
private void getLocationSetting(){
LocationSettingsRequest.Builder builder =
new LocationSettingsRequest
.Builder()
.addLocationRequest(mLocationRequest);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>(){
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "SUCCESS");
isLocationEnabled = true;
isPermissionLocked = false;
getLastKnownLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "RESOLUTION_REQUIRED");
try {
status.startResolutionForResult(
mActivity,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
mCallback.onLocationSettingsError();
}finally {
isPermissionLocked = false;
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG, "SETTINGS_CHANGE_UNAVAILABLE");
Toast.makeText(mContext, "Location Unavailable", Toast.LENGTH_SHORT).show();
mCallback.onLocationSettingsError();
isPermissionLocked = false;
break;
}
}
});
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
int permState;
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0) {
if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(
mActivity,
Manifest.permission.ACCESS_FINE_LOCATION)){
permState = PERMISSION_BLOCKED;
}else{permState = PERMISSION_DENIED;}
}else {permState = PERMISSION_GRANTED;}
}
else{permState = PERMISSION_DENIED;}
switch (permState){
case PERMISSION_BLOCKED:
Toast.makeText(mContext,"Please give gps location permission to use the app.",Toast.LENGTH_LONG).show();
startInstalledAppDetailsActivity(mContext);
mCallback.onLocationPermissionDenied();
break;
case PERMISSION_DENIED:
Toast.makeText(mContext,"Permission Denied, app cannot access the gps location.", Toast.LENGTH_LONG).show();
break;
case PERMISSION_GRANTED:
getLocationSetting();
break;
}
break;
}
}
public static boolean isLocationEnabled(Context context){
LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
boolean gpsEnabled = false;
boolean networkEnabled = false;
try {
gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}
try {
networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {}
return gpsEnabled && networkEnabled;
}
public static void startInstalledAppDetailsActivity(final Context context) {
if (context == null) {
return;
}
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + context.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(i);
}
public static boolean checkLocationPermission(Context context) {
String permission = "android.permission.ACCESS_FINE_LOCATION";
int res = context.checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
public interface LocationCallback {
void onLastKnowLocationFetch(Location location);
void onLocationUpdate(Location location);
void onLocationPermissionDenied();
void onLocationSettingsError();
}
public void close() {
mGPSStatusReceiver.unRegisterReceiver();
}}
Recivier Class
public class GPSStatusReceiver extends BroadcastReceiver {
private GpsStatusChangeListener mCallback;
private Context mContext;
public GPSStatusReceiver(Context context, GpsStatusChangeListener callback) {
mCallback = callback;
mContext = context;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.location.PROVIDERS_CHANGED");
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
context.registerReceiver(this, intentFilter);
}
public void unRegisterReceiver(){
Log.i(TAG, "unRegisterReceiver");
mContext.unregisterReceiver(this);
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Log.i(TAG, "in PROVIDERS_CHANGED");
mCallback.onGpsStatusChange();
}
}
public interface GpsStatusChangeListener{
void onGpsStatusChange();
}}
活动类
public class LocationFinder extends AppCompatActivity implements GPSLocation.LocationCallback,OnMapReadyCallback {
Log log;
private GoogleMap mMap;
Button confirmLocalizationButton;
private GPSLocation mGPSLocation;
private LatLng currentPosition= new LatLng(0,0);
MarkerOptions markerOptions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mGPSLocation = new GPSLocation(this, this);
mGPSLocation.init();
mapInit();
buttonInit();
checkInternetStatus();
}
private void buttonInit() {
confirmLocalizationButton = (Button)findViewById(R.id.confirm_location);
confirmLocalizationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
currentPosition=markerOptions.getPosition();
log.i(TAG,"currentPosition:: "+currentPosition);
Intent i = new Intent(LocationFinder.this,MainActivity.class);
i.putExtra("coordinates",currentPosition);
startActivity(i);
finish();
}
});
}
@Override
public void onLastKnowLocationFetch(Location location) {
if(location != null) {
Log.i(TAG, "onLastKnowLocationFetch " + location);
}
}
@Override
public void onLocationUpdate(Location location) {
if(location != null) {
Log.i(TAG, "onLocationUpdate " + location);
}
}
@Override
public void onLocationPermissionDenied() {
}
@Override
public void onLocationSettingsError() {
}
@Override
protected void onStart() {
mGPSLocation.connect();
super.onStart();
}
@Override
public void onResume() {
super.onResume();
mGPSLocation.startLocationUpdates();
}
@Override
protected void onPause() {
super.onPause();
mGPSLocation.stopLocationUpdates();
}
@Override
protected void onStop() {
mGPSLocation.disconnect();
super.onStop();
}
@Override
protected void onDestroy() {
mGPSLocation.close();
super.onDestroy();
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == GPSLocation.LOCATION_PERMISSION_REQUEST_CODE) {
mGPSLocation.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GPSLocation.REQUEST_CHECK_SETTINGS) {
mGPSLocation.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
CameraUpdate camera = CameraUpdateFactory.newLatLngZoom(currentPosition, 1);
mMap.moveCamera(camera);
markerOptions = new MarkerOptions()
.position(currentPosition);
mMap.addMarker(markerOptions);
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
markerOptions = new MarkerOptions().position(mMap.getCameraPosition().target);
mMap.clear();
mMap.addMarker(markerOptions);
}
});
}
private void mapInit(){
SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
private void checkInternetStatus(){
if(!InternetConnection.getConnectivityStatus(this)) {
new android.app.AlertDialog.Builder(this)
.setMessage("Turn on your network service to enjoy full functionality of this application ")
.setCancelable(true).
setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.show();
}
}
更新:我已经制作了等待GPS信号但仍能连接的功能
private void waitForGPSSignal(){
progressWindow();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getLastKnownLocation();
if(mCurrentLocation!=null)
progress.dismiss();
}
}, 10000);
}
ProgressDialog progress;
private void progressWindow() {
progress = new ProgressDialog(mContext);
progress.setMessage("waiting");
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(true);
if (mContext != null) {
progress.show();
}}
我在这里称之为GPSLocation:
result.setResultCallback(new ResultCallback<LocationSettingsResult>(){
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "SUCCESS");
isLocationEnabled = true;
isPermissionLocked = false;
waitForGPSSignal();
getLastKnownLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "RESOLUTION_REQUIRED");
try {
status.startResolutionForResult(
mActivity,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
mCallback.onLocationSettingsError();
}finally {
isPermissionLocked = false;
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG, "SETTINGS_CHANGE_UNAVAILABLE");
Toast.makeText(mContext, "Location Unavailable", Toast.LENGTH_SHORT).show();
mCallback.onLocationSettingsError();
isPermissionLocked = false;
break;
}
}
});
我仍然获得null。
答案 0 :(得分:0)
这是你可以做的。
if (Utility.isLocationEnabled(Splash_Activity.this)) {
new FetchCordinates.execute();
} else {
buildAlertMessageNoGps();
}
<强> FetchCordinates.java 强>
public class FetchCordinates extends AsyncTask<String, Integer, String> {
public LocationManager mLocationManager;
public VeggsterLocationListener mVeggsterLocationListener;
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
pDialog = ProgressDialog.show(InitialRegistration.this, "",
"Fetching Location");
mVeggsterLocationListener = new VeggsterLocationListener();
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0,
mVeggsterLocationListener);
}
@Override
protected void onCancelled() {
System.out.println("Cancelled by user!");
mLocationManager.removeUpdates(mVeggsterLocationListener);
}
@Override
protected void onPostExecute(String result) {
// Log.e("AsynckLL", "LATITUDE :" + mLatitude + " LONGITUDE :"
// + mLongitude);
if (pDialog.isShowing()) {
pDialog.dismiss();
}
// do your logic
mLocationManager.removeUpdates(mVeggsterLocationListener);
}
@Override
protected String doInBackground(String... params) {
while (mLatitude == 0.0) {
}
return null;
}
public class VeggsterLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
mLatitude = location.getLatitude();
mLongitude = location.getLongitude();
}
@Override
public void onProviderDisabled(String provider) {
// Log.e("OnProviderDisabled", "OnProviderDisabled");
}
@Override
public void onProviderEnabled(String provider) {
// Log.e("onProviderEnabled", "onProviderEnabled");
}
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
// Log.e("onStatusChanged", "onStatusChanged");
}
}
}
如果未启用位置。
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(
Splash_Activity.this);
builder.setMessage(
"Your GPS seems to be disabled, do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog,
final int id) {
startActivityForResult(
new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS),
100);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog,
final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
和onActivityResults
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100) {
if (Utility.isLocationEnabled(Splash_Activity.this)) {
new FetchCordinates().execute();
} else {
buildAlertMessageNoGps();
}
} else {
Toast.makeText(getApplicationContext(), "Location Off", 1000)
.show();
}
}
这不是您在问题中提到的服务。但我希望它能帮到你。
快乐编码。