Current Location failed GoogleMap

前端 未结 3 2003
醉梦人生
醉梦人生 2021-01-27 05:36

I want to check if the GPS is on if it is should show the current location. If not it should ask to turn it on. If user click cancel or dont turn the coordinates will be set as

相关标签:
3条回答
  • 2021-01-27 06:19

    This requires a lot of case handling and I am providing a complete implementation of the all the features you requested with brief explanations below.

    1. Provide location permission in the manifest

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    

    2. Add location dependency in app's build.gradle

    compile 'com.google.android.gms:play-services-location:9.2.1'
    

    3. extend BroadcastReceiver and create GPSStatusReceiver

    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.d("ali", "unRegisterReceiver");
            mContext.unregisterReceiver(this);
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
                Log.d("ali", "in PROVIDERS_CHANGED");
                mCallback.onGpsStatusChange();
            }
        }
    
        public interface GpsStatusChangeListener{
            void onGpsStatusChange();
        }
    }
    

    4. Create a class GPSLocation

    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;
            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.d("ali", "getLastKnownLocation restart ");
                mGoogleApiClient.connect();
            }
            else {
                if (checkLocationPermission(mContext) && isLocationEnabled) {
                    Log.d("ali", "getLastKnownLocation read ");
                    if(mCurrentLocation == null) {
                        mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                        mCallback.onLastKnowLocationFetch(mCurrentLocation);
                    }
                    startLocationUpdates();
                }else{
                    Log.d("ali", "getLastKnownLocation get permission ");
                    requestPermission();
                }
            }
            Log.d("ali", "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) {
            Log.d("ali", "onConnected");
            requestPermission();
        }
    
    
        @Override
        public void onConnectionSuspended(int i) {
            Log.d("ali", "onConnectionSuspended");
        }
    
    
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
            Log.d("ali", "onConnectionFailed");
        }
    
    
        @Override
        public void onLocationChanged(Location location) {
            Log.d("ali", "onLocationChanged : " + location);
            mCallback.onLocationUpdate(location);
        }
    
    
        @Override
        public void onGpsStatusChange() {
            Log.d("ali", "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.d("ali", "SUCCESS");
                            isLocationEnabled = true;
                            isPermissionLocked = false;
                            getLastKnownLocation();
                            break;
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            Log.d("ali", "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.d("ali", "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();
        }
    }
    

    5. In the activity use the below code

    public class MainActivity extends AppCompatActivity implements GPSLocation.LocationCallback {
    
        private GPSLocation mGPSLocation;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mGPSLocation = new GPSLocation(this, this);
            mGPSLocation.init();
        }
    
        @Override
        public void onLastKnowLocationFetch(Location location) {
            if(location != null) {
                Log.d("ali ", "onLastKnowLocationFetch " + location);
            }
        }
    
        @Override
        public void onLocationUpdate(Location location) {
            if(location != null) {
                Log.d("ali ", "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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-27 06:21

    Add this override method for me its worked fine--

     @Override
    public void onLocationChanged(Location location) {
        getLocation("onLocationChanged");
    }
    
    0 讨论(0)
  • 2021-01-27 06:24

    The following code checks, if location is enabled or not. If not it shows alert dialog to enable location service.

    LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }catch (Exception ex){}
    try{
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }catch (Exception ex){}
    if(!gps_enabled && !network_enabled){
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setMessage(getResources().getString(R.string.gps_network_not_enabled));
        dialog.setPositiveButton(getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {                 
                Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                Startup.this.startActivity(myIntent);                    
            }
        });
        dialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {
    
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub
    
            }
        });
        dialog.show();
    }
    

    add below code in AndroidManifest.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" />
    
    0 讨论(0)
提交回复
热议问题