2013-11-26 132 views
29

我使用下面的代码此给予获得位置:Android的定位管理,获取GPS位置,如果没有GPS,然后去网络提供商的位置

public Location getLocation() { 
     try { 
      mLocationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE); 

      // getting GPS status 
      boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 

      // getting network status 
      boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (!isGPSEnabled && !isNetworkEnabled) { 
       // no network provider is enabled 
      } else { 
       // First get location from Network Provider 
       if (isNetworkEnabled) { 
        mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("Network", "Network"); 
        if (mLocationManager != null) { 
         location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (location != null) { 
          lat = location.getLatitude(); 
          lng = location.getLongitude(); 
         } 
        } 
       } 
       //get the location by gps 
       if (isGPSEnabled) { 
        if (location == null) { 
         mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
         Log.d("GPS Enabled", "GPS Enabled"); 
         if (mLocationManager != null) {location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          if (location != null) { 
           lat = location.getLatitude(); 
           lng = location.getLongitude(); 
          } 
         } 
        } 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return location; 
    } 

它工作正常,但我想获得GPS首先定位,如果不可用,位置管理员应该查询网络提供商,在这个网络提供商中我遇到了麻烦。

请推荐我这样做的好方法。

+0

使用Play服务的新位置客户端。它很容易理解。 – TeeTracker

+0

此链接为您提供最佳方式 http://stackoverflow.com/questions/3145089/what-is-the-simplest-and-most-robust-way-to-get-the-users-current (),位置在一个?lq = 1 – 2013-11-26 15:25:55

回答

1

我在上面的代码中做了一些修改,以寻找由GPS和网络定位约5秒的定位,并给我最好的已知位置。

public class LocationService implements LocationListener { 

    boolean isGPSEnabled = false; 

    boolean isNetworkEnabled = false; 

    boolean canGetLocation = false; 

    final static long MIN_TIME_INTERVAL = 60 * 1000L; 

    Location location; 


    // The minimum distance to change Updates in meters 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 

    // The minimum time between updates in milliseconds 
    private static final long MIN_TIME_BW_UPDATES = 1; // 1 minute 

    protected LocationManager locationManager; 

    private CountDownTimer timer = new CountDownTimer(5 * 1000, 1000) { 

     public void onTick(long millisUntilFinished) { 

     } 

     public void onFinish() { 
      stopUsingGPS(); 
     } 
    }; 

    public LocationService() { 
     super(R.id.gps_service_id); 
    } 


    public void start() { 
     if (Utils.isNetworkAvailable(context)) { 

      try { 


       timer.start(); 


       locationManager = (LocationManager) context 
         .getSystemService(Context.LOCATION_SERVICE); 

       isGPSEnabled = locationManager 
         .isProviderEnabled(LocationManager.GPS_PROVIDER); 

       isNetworkEnabled = locationManager 
         .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
       this.canGetLocation = true; 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.NETWORK_PROVIDER, 
          MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("Network", "Network"); 
        if (locationManager != null) { 
         Location tempLocation = locationManager 
           .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (tempLocation != null 
           && isBetterLocation(tempLocation, 
             location)) 
          location = tempLocation; 
        } 
       } 
       if (isGPSEnabled) { 

        locationManager.requestSingleUpdate(
          LocationManager.GPS_PROVIDER, this, null); 
        locationManager.requestLocationUpdates(
          LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("GPS Enabled", "GPS Enabled"); 
        if (locationManager != null) { 
         Location tempLocation = locationManager 
           .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
         if (tempLocation != null 
           && isBetterLocation(tempLocation, 
             location)) 
          location = tempLocation; 
        } 
       } 

      } catch (Exception e) { 
       onTaskError(e.getMessage()); 
       e.printStackTrace(); 
      } 
     } else { 
      onOfflineResponse(requestData); 
     } 
    } 

    public void stopUsingGPS() { 
     if (locationManager != null) { 
      locationManager.removeUpdates(LocationService.this); 
     } 
    } 

    public boolean canGetLocation() { 
     locationManager = (LocationManager) context 
       .getSystemService(Context.LOCATION_SERVICE); 
     isGPSEnabled = locationManager 
       .isProviderEnabled(LocationManager.GPS_PROVIDER); 

     // getting network status 
     isNetworkEnabled = locationManager 
       .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     return isGPSEnabled || isNetworkEnabled; 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

     if (location != null 
       && isBetterLocation(location, this.location)) { 

      this.location = location; 

     } 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
    } 

    @Override 
    public Object getResponseObject(Object location) { 
     return location; 
    } 

    public static boolean isBetterLocation(Location location, 
      Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return true; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > MIN_TIME_INTERVAL; 
     boolean isSignificantlyOlder = timeDelta < -MIN_TIME_INTERVAL; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, 
     // use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return true; 
      // If the new location is more than two minutes older, it must 
      // be worse 
     } else if (isSignificantlyOlder) { 
      return false; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation 
       .getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and 
     // accuracy 
     if (isMoreAccurate) { 
      return true; 
     } else if (isNewer && !isLessAccurate) { 
      return true; 
     } else if (isNewer && !isSignificantlyLessAccurate 
       && isFromSameProvider) { 
      return true; 
     } 
     return false; 
    } 

} 

在上面的类,我报名参加了GPS和网络位置监听器,这样的onLocationChanged回调可以由一个或两个人多次,被称为我们还是用了比较新的位置锁定一个我们已经拥有并保持最好的一个。

+0

'isSameProvider'位于'布尔isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());'声明/定义? – VikramV

+0

嗨,我对你的代码感兴趣,顺便说一句,你为什么使用计时器? onOfflineResponse(requestData)和onTaskError(e.getMessage)函数在哪里?谢谢。 – NPE

+0

而不是为了随时查找GPS位置,每次您打电话时都会查找一段时间(在计时器中设置)。最后它在那个时候找到了最好的位置。 –

15

你说的是,如果GPS位置可用,你首先需要GPS位置,但是你所做的首先是从网络提供商那里获取位置,然后从GPS获得位置。如果两者都可用,这将从网络和GPS获得位置。你可以做的是,将这些案例写入if..else if区块。类似TO-

if(!isGPSEnabled && !isNetworkEnabled) { 

// Can't get location by any way 

} else { 

    if(isGPSEnabled) { 

    // get location from GPS 

    } else if(isNetworkEnabled) { 

    // get location from Network Provider 

    } 
} 

因此,这将首先从GPS获取位置(如果可用),否则它会尝试从网络提供商获取位置。

编辑

为了变得更好,我会发布一个片段。考虑它在try-catch

boolean gps_enabled = false; 
boolean network_enabled = false; 

LocationManager lm = (LocationManager) mCtx 
       .getSystemService(Context.LOCATION_SERVICE); 

gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); 
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

Location net_loc = null, gps_loc = null, finalLoc = null; 

if (gps_enabled) 
    gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
if (network_enabled) 
    net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

if (gps_loc != null && net_loc != null) { 

    //smaller the number more accurate result will 
    if (gps_loc.getAccuracy() > net_loc.getAccuracy()) 
     finalLoc = net_loc; 
    else 
     finalLoc = gps_loc; 

     // I used this just to get an idea (if both avail, its upto you which you want to take as I've taken location with more accuracy) 

} else { 

    if (gps_loc != null) { 
     finalLoc = gps_loc; 
    } else if (net_loc != null) { 
     finalLoc = net_loc; 
    } 
} 

现在你检查finalLocnull,如果不是那么return它。 您可以在返回所需位置(finalLoc)的函数中编写上述代码。我认为这可能会有所帮助。

+0

尽我所知,isGPSEnabled以及isNetworkEnabled都会告诉提供者是否启用。但是,有时可能会出现这样的情况,即使GPS提供商已启用,但我们无法通过该位置获得位置,在这种情况下,它应该使用另一个位置更新位置更新,即网络提供商。如何做到这一点? – 2013-11-26 09:57:21

+0

请参阅编辑。让我知道你是否还需要一些东西。谢谢。 – thegiga

+0

我已检查您的编辑。其中最令我怀疑的是lm.getLastKnownLocation。它可靠吗?如果我24小时前得到最后一次GPS定位,该怎么办?请问声明 - “gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);”返回'null'还是24小时前的位置? – 2013-11-26 14:17:48

5

推荐的方式做到这一点如前所述是使用LocationClient

首先,定义位置更新间隔值。根据您的需要进行调整。

private static final int MILLISECONDS_PER_SECOND = 1000; 
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS; 
private static final int FASTEST_INTERVAL_IN_SECONDS = 1; 
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS; 

有你Activity实施GooglePlayServicesClient.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListenerLocationListener

public class LocationActivity extends Activity implements 
GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {} 

然后,在onCreate()方法您Activity成立了LocationClient

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mLocationClient = new LocationClient(this, this, this); 

    mLocationRequest = LocationRequest.create(); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mLocationRequest.setInterval(UPDATE_INTERVAL); 
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 
} 

添加所需的方法,您Activity; onConnected()LocationClient连接时调用的方法。 onLocationChanged()是您可以检索最新位置的地方。

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    Log.w(TAG, "Location client connection failed"); 
} 

@Override 
public void onConnected(Bundle dataBundle) { 
    Log.d(TAG, "Location client connected"); 
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 
} 

@Override 
public void onDisconnected() { 
    Log.d(TAG, "Location client disconnected"); 
} 

@Override 
public void onLocationChanged(Location location) { 
    if (location != null) { 
     Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude())); 
    } else { 
     Log.d(TAG, "Updated location NULL"); 
    } 
}  

确保连接/断开LocationClient所以它只能使用备用电池时绝对必要的,因此GPS不无限期地运行。必须连接LocationClient才能从中获取数据。

public void onResume() { 
    super.onResume(); 
    mLocationClient.connect(); 
} 

public void onStop() { 
    if (mLocationClient.isConnected()) { 
     mLocationClient.removeLocationUpdates(this); 
    } 
    mLocationClient.disconnect(); 
    super.onStop(); 
} 

获取用户的位置。首先尝试使用LocationClient;如果失败,请回到LocationManager

public Location getLocation() { 
    if (mLocationClient != null && mLocationClient.isConnected()) { 
     return mLocationClient.getLastLocation(); 
    } else { 
     LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     if (locationManager != null) { 
      Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      if (lastKnownLocationGPS != null) { 
       return lastKnownLocationGPS; 
      } else { 
       return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      } 
     } else { 
      return null; 
     } 
    } 
} 
+0

事实上,它不是建议的方式。 '这个类已被弃用。 使用LocationServices.'请参阅https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html – levi

+0

'LocationManager','LocationClient'和'LocationServices'是非常不同的.' LocationManager'用于从Android系统获取更新.'LocationClient'取决于Google Play服务,已被弃用,并且根据我的经验,这其实在各方面都很糟糕(速度,准确性和电池使用情况)。 'LocationServices'也依赖于Google Play服务,并使用不同的范例来访问API。根据我的经验,它似乎是“LocationClient”的一个“固定”版本(我曾预料主要变化是用于访问服务的方法,因此可能涉及外部因素)。 –

+0

我知道它们之间的主要区别是我普遍应用(即不是基于我对它们的体验),因为'LocationManager'是唯一不会依赖Google Play服务的3个区域。这意味着您可以在没有Google Play的设备上使用它(

1

主类:

public class AndroidLocationActivity extends Activity { 

Button btnGPSShowLocation; 
Button btnNWShowLocation; 

AppLocationService appLocationService; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    appLocationService = new AppLocationService(
      AndroidLocationActivity.this); 

    btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation); 
    btnGPSShowLocation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 

      Location gpsLocation = appLocationService 
        .getLocation(LocationManager.GPS_PROVIDER); 

      if (gpsLocation != null) { 
       double latitude = gpsLocation.getLatitude(); 
       double longitude = gpsLocation.getLongitude(); 
       Toast.makeText(
         getApplicationContext(), 
         "Mobile Location (GPS): \nLatitude: " + latitude 
           + "\nLongitude: " + longitude, 
         Toast.LENGTH_LONG).show(); 
      } else { 
       showSettingsAlert("GPS"); 
      } 

     } 
    }); 

    btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation); 
    btnNWShowLocation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 

      Location nwLocation = appLocationService 
        .getLocation(LocationManager.NETWORK_PROVIDER); 

      if (nwLocation != null) { 
       double latitude = nwLocation.getLatitude(); 
       double longitude = nwLocation.getLongitude(); 
       Toast.makeText(
         getApplicationContext(), 
         "Mobile Location (NW): \nLatitude: " + latitude 
           + "\nLongitude: " + longitude, 
         Toast.LENGTH_LONG).show(); 

      } else { 
       showSettingsAlert("NETWORK"); 
      } 

     } 
    }); 

} 

public void showSettingsAlert(String provider) { 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
      AndroidLocationActivity.this); 

    alertDialog.setTitle(provider + " SETTINGS"); 

    alertDialog.setMessage(provider 
      + " is not enabled! Want to go to settings menu?"); 

    alertDialog.setPositiveButton("Settings", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        Intent intent = new Intent(
          Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        AndroidLocationActivity.this.startActivity(intent); 
       } 
      }); 

    alertDialog.setNegativeButton("Cancel", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 

    alertDialog.show(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 

} 

} 

下一个类:

public class AppLocationService extends Service implements LocationListener { 

protected LocationManager locationManager; 
Location location; 

private static final long MIN_DISTANCE_FOR_UPDATE = 10; 
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2; 

public AppLocationService(Context context) { 
    locationManager = (LocationManager) context 
      .getSystemService(LOCATION_SERVICE); 
} 

public Location getLocation(String provider) { 
    if (locationManager.isProviderEnabled(provider)) { 
     locationManager.requestLocationUpdates(provider, 
       MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this); 
     if (locationManager != null) { 
      location = locationManager.getLastKnownLocation(provider); 
      return location; 
     } 
    } 
    return null; 
} 

@Override 
public void onLocationChanged(Location location) { 
} 

@Override 
public void onProviderDisabled(String provider) { 
} 

@Override 
public void onProviderEnabled(String provider) { 
} 

@Override 
public void onStatusChanged(String provider, int status, Bundle extras) { 
} 

@Override 
public IBinder onBind(Intent arg0) { 
    return null; 
} 

} 

不要忘了在你的清单中添加。

<!-- to get location using GPS --> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

<!-- to get location using NetworkProvider --> 
<uses-permission android:name="android.permission.INTERNET" /> 
+0

我不喜欢不认为使用网络提供者需要“INTERNET”权限。我认为它实际上需要'ACCESS_COURSE_LOCATION'。 – trooper

2

使用谷歌显影剂已经与GPS传感器,磁强计的融合开发融合API,加速度计也使用WiFi或细胞位置来计算或估计位置的。它也能够在建筑物内精确地提供位置更新。

package com.example.ashis.gpslocation; 

import android.app.Activity; 
import android.location.Location; 
import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

/** 
* Location sample. 
* 
* Demonstrates use of the Location API to retrieve the last known location for a device. 
* This sample uses Google Play services (GoogleApiClient) but does not need to authenticate a user. 
* See https://github.com/googlesamples/android-google-accounts/tree/master/QuickStart if you are 
* also using APIs that need authentication. 
*/ 

public class MainActivity extends Activity implements LocationListener, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener { 

    private static final long ONE_MIN = 500; 
    private static final long TWO_MIN = 500; 
    private static final long FIVE_MIN = 500; 
    private static final long POLLING_FREQ = 1000 * 20; 
    private static final long FASTEST_UPDATE_FREQ = 1000 * 5; 
    private static final float MIN_ACCURACY = 1.0f; 
    private static final float MIN_LAST_READ_ACCURACY = 1; 

    private LocationRequest mLocationRequest; 
    private Location mBestReading; 
TextView tv; 
    private GoogleApiClient mGoogleApiClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if (!servicesAvailable()) { 
      finish(); 
     } 

     setContentView(R.layout.activity_main); 
tv= (TextView) findViewById(R.id.tv1); 
     mLocationRequest = LocationRequest.create(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(POLLING_FREQ); 
     mLocationRequest.setFastestInterval(FASTEST_UPDATE_FREQ); 

     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .build(); 


     if (mGoogleApiClient != null) { 
      mGoogleApiClient.connect(); 
     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     if (mGoogleApiClient != null) { 
      mGoogleApiClient.connect(); 
     } 
    } 

    @Override 
    protected void onPause() {d 
     super.onPause(); 

     if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.disconnect(); 
     } 
    } 


     tv.setText(location + ""); 
     // Determine whether new location is better than current best 
     // estimate 
     if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) { 
      mBestReading = location; 


      if (mBestReading.getAccuracy() < MIN_ACCURACY) { 
       LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
      } 
     } 
    } 

    @Override 
    public void onConnected(Bundle dataBundle) { 
     // Get first reading. Get additional location updates if necessary 
     if (servicesAvailable()) { 

      // Get best last location measurement meeting criteria 
      mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN); 

      if (null == mBestReading 
        || mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY 
        || mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) { 

       LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 

       //Schedule a runnable to unregister location listeners 

        @Override 
        public void run() { 
         LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, MainActivity.this); 

        } 

       }, ONE_MIN, TimeUnit.MILLISECONDS); 

      } 

     } 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 


    private Location bestLastKnownLocation(float minAccuracy, long minTime) { 
     Location bestResult = null; 
     float bestAccuracy = Float.MAX_VALUE; 
     long bestTime = Long.MIN_VALUE; 

     // Get the best most recent location currently available 
     Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     //tv.setText(mCurrentLocation+""); 
     if (mCurrentLocation != null) { 
      float accuracy = mCurrentLocation.getAccuracy(); 
      long time = mCurrentLocation.getTime(); 

      if (accuracy < bestAccuracy) { 
       bestResult = mCurrentLocation; 
       bestAccuracy = accuracy; 
       bestTime = time; 
      } 
     } 

     // Return best reading or null 
     if (bestAccuracy > minAccuracy || bestTime < minTime) { 
      return null; 
     } 
     else { 
      return bestResult; 
     } 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 

    } 

    private boolean servicesAvailable() { 
     int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 

     if (ConnectionResult.SUCCESS == resultCode) { 
      return true; 
     } 
     else { 
      GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show(); 
      return false; 
     } 
    } 
} 
+0

你好阿希斯,好的代码片段,但我执行代码片段后,一些移动设备**(Micromex,三星注4)**只能加载近30 ** [如果在家里] **第二不好。 – user2617214

+0

@ user26174你解决了问题吗?如果不让我知道,我会让你访问我的github.com帐户并获得工作代码。 – AshisParajuli

2

如果你想将后台服务中运行,并采取数据在前台使用下面的一个,它是测试和验证。

public class MyService extends Service 
     implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     com.google.android.gms.location.LocationListener { 


    private static final int ASHIS = 1234; 
    Intent intentForPendingIntent; 
    HandlerThread handlerThread; 
    Looper looper; 
    GoogleApiClient mGoogleApiClient; 
    private LocationRequest mLocationRrequest; 
    private static final int UPDATE_INTERVAL = 1000; 
    private static final int FASTEST_INTERVAL = 100; 
    private static final int DSIPLACEMENT_UPDATES = 1; 
    ; 
    private Handler handler1; 
    private Runnable runable1; 
    private Location mLastLocation; 
    private float waitingTime; 
    private int waiting2min; 
    private Location locationOld; 
    private double distance; 
    private float totalWaiting; 
    private float speed; 
    private long timeGpsUpdate; 
    private long timeOld; 
    private NotificationManager mNotificationManager; 
    Notification notification; 
    PendingIntent resultPendingIntent; 
    NotificationCompat.Builder mBuilder; 


    // Sets an ID for the notification 
    int mNotificationId = 001; 
    private static final String TAG = "BroadcastService"; 
    public static final String BROADCAST_ACTION = "speedExceeded"; 
    private final Handler handler = new Handler(); 
    Intent intentforBroadcast; 
    int counter = 0; 
    private Runnable sendUpdatesToUI; 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     Toast.makeText(MyService.this, "binder", Toast.LENGTH_SHORT).show(); 

     return null; 
    } 


    @Override 
    public void onCreate() { 
     showNotification(); 
     intentforBroadcast = new Intent(BROADCAST_ACTION); 

     Toast.makeText(MyService.this, "created", Toast.LENGTH_SHORT).show(); 

     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 
     createLocationRequest(); 
     mGoogleApiClient.connect(); 


    } 

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    private void showNotification() { 

     mBuilder = 
       (NotificationCompat.Builder) new NotificationCompat.Builder(this) 
         .setSmallIcon(R.drawable.ic_media_play) 
         .setContentTitle("Total Waiting Time") 
         .setContentText(totalWaiting+""); 


     Intent resultIntent = new Intent(this, trackingFusion.class); 

     // Because clicking the notification opens a new ("special") activity, there's 
     // no need to create an artificial back stack. 
     PendingIntent resultPendingIntent = 
       PendingIntent.getActivity(
         this, 
         0, 
         resultIntent, 
         PendingIntent.FLAG_UPDATE_CURRENT 
       ); 
     mBuilder.setContentIntent(resultPendingIntent); 
     NotificationManager mNotifyMgr = 
       (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     // Builds the notification and issues it. 

     mNotifyMgr.notify(mNotificationId, mBuilder.build()); 


     startForeground(001, mBuilder.getNotification()); 
    } 


    @Override 
    public void onLocationChanged(Location location) { 

     //handler.removeCallbacks(runable); 

     Toast.makeText(MyService.this, "speed" + speed, Toast.LENGTH_SHORT).show(); 
     timeGpsUpdate = location.getTime(); 
     float delta = (timeGpsUpdate - timeOld)/1000; 
     if (location.getAccuracy() < 100) { 
      speed = location.getSpeed(); 
      distance += mLastLocation.distanceTo(location); 
      Log.e("distance", "onLocationChanged: " + distance); 
      //mLastLocation = location; 
      //newLocation = mLastLocation; 

      Log.e("location:", location + ""); 


      //speed = (long) (distance/delta); 


      locationOld = location; 
      mLastLocation = location; 

      diaplayViews(); 
     } 

     diaplayViews(); 
    /*if (map != null) { 
     map.addMarker(new MarkerOptions() 
       .position(new LatLng(location.getLatitude(), location.getLongitude())) 
       .title("Hello world")); 


    }*/ 
    } 


    private void createLocationRequest() { 

     mLocationRrequest = new LocationRequest(); 

     mLocationRrequest.setInterval(UPDATE_INTERVAL); 
     mLocationRrequest.setFastestInterval(FASTEST_INTERVAL); 
     mLocationRrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRrequest.setSmallestDisplacement(DSIPLACEMENT_UPDATES); 

    } 


    private void methodToCalculateWaitingTime() { 


     if (handler1 != null) { 
      handler1.removeCallbacks(runable1); 

     } 


     Log.e("Here", "here1"); 
     handler1 = new Handler(Looper.getMainLooper()); 
     runable1 = new Runnable() { 
      public void run() { 

       Log.e("Here", "here2:" + mLastLocation.getSpeed()); 


       if (mLastLocation != null) { 
        diaplayViews(); 
        if ((mLastLocation.getSpeed() == 0.0)) { 

         increaseTime(); 

        } else { 
         if (waitingTime <= 120) { 
          waiting2min = 0; 

         } 
        } 
        handler1.postDelayed(this, 10000); 
       } else { 
        if (ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
         // TODO: Consider calling 
         // ActivityCompat#requestPermissions 
         // here to request the missing permissions, and then overriding 
         // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
         //           int[] grantResults) 
         // to handle the case where the user grants the permission. See the documentation 
         // for ActivityCompat#requestPermissions for more details. 
         return; 
        } 

        locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
        mLastLocation = locationOld; 

       } 
      } 
     }; 

     handler1.postDelayed(runable1, 10000); 


    } 

    private void diaplayViews() { 
     float price = (float) (14 + distance * 0.5); 

     //textDistance.setText(waitingTime);a 
    } 


    private void increaseTime() { 
     waiting2min = waiting2min + 10; 
     if (waiting2min >= 120) 

     { 
      if (waiting2min == 120) { 
       waitingTime = waitingTime + 2 * 60; 


      } else { 
       waitingTime = waitingTime + 10; 
      } 


      totalWaiting = waitingTime/60; 
      showNotification(); 
      Log.e("waiting Time", "increaseTime: " + totalWaiting); 
     } 


    } 

    @Override 
    public void onDestroy() { 
     Toast.makeText(MyService.this, "distroyed", Toast.LENGTH_SHORT).show(); 
     if (mGoogleApiClient.isConnected()) { 

      mGoogleApiClient.disconnect(); 
     } 
     mGoogleApiClient.disconnect(); 

    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.e("Connection_fusion", "connected"); 

     startLocationUpdates(); 


    } 


    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    private void startLocationUpdates() { 
     Location location = plotTheInitialMarkerAndGetInitialGps(); 
     if (location == null) { 
      plotTheInitialMarkerAndGetInitialGps(); 


     } else { 

      mLastLocation = location; 
      methodToCalculateWaitingTime(); 
     } 
    } 

    private Location plotTheInitialMarkerAndGetInitialGps() { 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return null; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRrequest, this); 
     locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if ((locationOld != null)) { 
      mLastLocation = locationOld; 

      timeOld = locationOld.getTime(); 
     } else { 
      startLocationUpdates(); 
     } 

     return mLastLocation; 
    } 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     onStart(intent, startId); 
     Toast.makeText(MyService.this, "start command", Toast.LENGTH_SHORT).show(); 

     sendUpdatesToUI = new Runnable() { 
      public void run() { 
       DisplayLoggingInfo(); 
       handler.postDelayed(this, 10000); // 5 seconds 
      } 
     }; 
     handler.postDelayed(sendUpdatesToUI, 10000); // 1 second 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 
     return START_NOT_STICKY; 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     sendUpdatesToUI = new Runnable() { 
      public void run() { 
       Log.e("sent", "sent"); 
       DisplayLoggingInfo(); 
       handler.postDelayed(this, 5000); // 5 seconds 
      } 
     }; 
     handler.postDelayed(sendUpdatesToUI, 1000); // 1 second 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 
     super.onStart(intent, startId); 
    } 

    private void DisplayLoggingInfo() { 
     Log.d(TAG, "entered DisplayLoggingInfo"); 
     intentforBroadcast.putExtra("distance", distance); 
     LocalBroadcastManager.getInstance(this).sendBroadcast(intentforBroadcast); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 

    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 

    } 
}