开发者

GPS provider and its performance

Is there a possible way开发者_开发百科 to detect the new location very fast using GPS provider?


GPS is often slow - that's just the way it is. But there are several things you can do in order to speed up the experience for the user:

  • Start looking for a location as soon as the app starts - don't wait until they get to an activity that needs a location

  • Use the network provider, which is often much faster

  • Use the passive provider. i.e. receive location updates that have been acquired by other apps on the device

  • Use the Last Known location - this is stored for a while, and if it exists, gives you a location instantly (though it may be a little old)

  • If suitable in your app's context, store a location yourself in prefs

This article by Google's Reto Meier is a great place to start - look at the related links for sample code and more detail http://blog.radioactiveyak.com/2011/06/how-to-build-location-based-apps-that.html


U can retrieve the location through network provider and GPS provider.

u can check both the providers simultaneously if u want a fast retrieval of the location. Here is the code..

Create a class like this first :

import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import com.tcs.android.eventinfo.data.DataStore;



public class GeoFence {
// public Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
Context mContext;

public Handler handler;
public GetLastLocation r;
public boolean isLocationNullSecondTime=false;

public GeoFence(Context context) {
    mContext=context;
    handler = new Handler();
    chekStatusOfLocationProvider(isLocationNullSecondTime);
}
public void chekStatusOfLocationProvider(boolean isLocationNullSecondTime){
    if(lm==null)
        lm = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);

    Log.i("GPS"," GPS"+lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER));
    Log.i("GPS"," Network"+lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER));
    Log.i("GPS"," Passive"+lm.isProviderEnabled(LocationManager.PASSIVE_PROVIDER));

    if ((!lm.isProviderEnabled(LocationManager.GPS_PROVIDER) 
            && !lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
            || isLocationNullSecondTime) {
        Log.i("GPS", "Inside Constructor");

        Toast.makeText(mContext, "Turn on your Location provider",
                Toast.LENGTH_LONG).show();
        Intent myIntent = new Intent(
                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        mContext.startActivity(myIntent);
    }


}

public boolean getLocation(LocationResult result)
{ 
    Log.i("GEo fence","DataStore.IS_THREAD_RUNNING : "+DataStore.IS_THREAD_RUNNING);
    if(!DataStore.IS_THREAD_RUNNING) {


/*      if ((!lm.isProviderEnabled(LocationManager.GPS_PROVIDER) 
                && !lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
                || isLocationNullSecondTime) {
            Log.i("GPS", "Inside Constructor");

            Toast.makeText(mContext, "Turn on your Location provider",
                    Toast.LENGTH_LONG).show();
            Intent myIntent = new Intent(
                    Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(myIntent);
        }*/

    Log.i("GPS","inside getlocation");
    //I use LocationResult callback class to pass location value from MyLocation to user code.
    locationResult=result;
    //exceptions will be thrown if provider is not permitted.
    try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
    try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}

    //don't start listeners if no provider is enabled
    if(!gps_enabled && !network_enabled){
        Log.i("GPS","nothing is enable");
        return false;
    }
    if(gps_enabled){
        Log.i("GPS","inside getlocation Gps is enabled");
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 5000, locationListenerGps);
    }
    if(network_enabled){
        Log.i("GPS","inside getlocation netwok is enable");
        lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0, 5000, locationListenerNetwork);
    }       
    r=new GetLastLocation();
    handler.postDelayed(r,20000);
    return true;
}
else {
    return false;
}}


LocationListener locationListenerGps = new LocationListener() {
    public void onLocationChanged(Location location) {
        DataStore.IS_THREAD_RUNNING=true;
        Log.i("GPS","inside onLocationcahnged of gps");
        isLocationNullSecondTime=false;
        lm.removeUpdates(this);
        lm.removeUpdates(locationListenerNetwork);
        handler.removeCallbacks(r);
        locationResult.gotLocation(location);

    }
    public void onProviderDisabled(String provider) {   Log.i("GPS","inside onProviderDisabled of gps");}
    public void onProviderEnabled(String provider) {    Log.i("GPS","inside onProviderEnabled of gps");}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
};

LocationListener locationListenerNetwork = new LocationListener() {
    public void onLocationChanged(Location location) {
        DataStore.IS_THREAD_RUNNING=true;
        Log.i("GPS","inside onLocationcahnged of Network");
        isLocationNullSecondTime=false;
        lm.removeUpdates(this);
        lm.removeUpdates(locationListenerGps);
        handler.removeCallbacks(r);
        locationResult.gotLocation(location);

    }
    public void onProviderDisabled(String provider) {Log.i("GPS","inside onProviderDisabled of Network");}
    public void onProviderEnabled(String provider) {Log.i("GPS","inside onProviderEnabled of Network");}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
};

class GetLastLocation implements Runnable {
    @Override
    public void run() {
        DataStore.IS_THREAD_RUNNING=true;
        Log.i("GPS","inside the thread run");
         lm.removeUpdates(locationListenerGps);
         lm.removeUpdates(locationListenerNetwork);

         Location net_loc=null, gps_loc=null;
         if(gps_enabled){
             gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
             Log.i("GPS","gps location object :"+gps_loc);
         }
         if(network_enabled){
             net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
             Log.i("GPS","neteork object :"+ net_loc);
         }
         //if there are both values use the latest one
         if(gps_loc!=null && net_loc!=null){
             handler.removeCallbacks(r);
             isLocationNullSecondTime=false;
             Log.i("GPS","neteork object not null :"+ net_loc);
             Log.i("GPS","GPS object not null :"+ gps_loc);
             if(gps_loc.getTime()>net_loc.getTime())
                 locationResult.gotLocation(gps_loc);
             else
                 locationResult.gotLocation(net_loc);
             return;
         }else{
             handler.removeCallbacks(r);
             if(gps_loc!=null){
                 isLocationNullSecondTime=false;
                 locationResult.gotLocation(gps_loc);
                 return;
             }
             else if(net_loc!=null){
                 isLocationNullSecondTime=false;
                 locationResult.gotLocation(net_loc);
                 return;
             }
             else{
                 isLocationNullSecondTime=true;
                 Log.i("GPS","Both the object is null and asking for turn on the Location provider  :");
                 locationResult.gotLocation(null);
                 return;
             }
         }



         //locationResult.gotLocation(null);
    }
}

public static abstract class LocationResult{
    public abstract void gotLocation(Location location);
}

then in your Activity write the code or implement the gotLocation( Location location) method like this:

public LocationResult locationResult = new LocationResult() {

    @Override
    public void gotLocation(final Location location) {
        // do something
        mLocation = location;
        if (geoFence.handler != null) {
            geoFence.handler.removeCallbacks(geoFence.r);
        }
        if (location == null) {
            if (DataStore.IS_THREAD_RUNNING) {
                DataStore.IS_THREAD_RUNNING=false;
            }
            if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                createAlert("Turn on ur GPS provider", new int[] {
                        R.string.yes, R.string.no },2);
                return;
            }
            if (!lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                createAlert("Turn on ur Network provider", new int[] {
                        R.string.yes, R.string.no },2);
                return;
            }
            Toast.makeText(PreHomeScreen.this,
                    "Turn on your both Location provider and try again ",
                    Toast.LENGTH_LONG).show();

        } else {
//////////////////////////////////Do ur work/////////////////////////////////////

}

    }
};


My blog contains example code on how to start the location services and wait for a location in a worker thread. You can start searching for a location the moment the app starts but continue running the app whilst it waits in the background. The user may need to do something before the location is required and in this time the location services could return a usable location.

http://www.scotthelme.co.uk/blog/android-location-services/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜