如何实现等待GPS信号的服务

时间:2016-09-20 05:34:49

标签: android gps

我想实现一项服务,该服务将显示加载屏幕,直到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。

1 个答案:

答案 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();
    }
}

这不是您在问题中提到的服务。但我希望它能帮到你。

快乐编码。