Android上的LocationManager API似乎对一个只需要偶尔粗略估计用户位置的应用程序来说有点麻烦。
我正在开发的应用程序本身并不是一个定位应用程序,但它确实需要获取用户的位置,以便显示附近企业的列表。它不需要担心用户是否在移动或类似的事情。
以下是我想做的:
向用户显示附近位置的列表。预加载用户的位置,以便在“活动X”中需要它时,它将可用。我并不特别关心更新的准确性或频率。只要不太远,只要抓住一个位置就足够了。也许如果我想变得更漂亮,我会每隔几分钟左右更新一次位置,但这不是一个很大的优先事项。适用于任何具有GPS或网络位置提供商的设备。
这似乎并不难,但在我看来,我必须组建两个不同的位置提供商(GPS和NETWORK),并管理每个提供商的生命周期。不仅如此,我还必须在多个活动中复制相同的代码以满足#2。过去,我曾尝试使用getBestProvider()将解决方案简化为仅使用一个位置提供程序,但这似乎只提供了最好的“理论”提供程序,而不是实际会为您提供最佳结果的提供程序。
有没有更简单的方法来实现这一点?
地理定位的简单和最佳方式。
LocationManager lm = null;
boolean network_enabled;
if (lm == null)
lm = (LocationManager) Kikit.this.getSystemService(Context.LOCATION_SERVICE);
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
dialog = ProgressDialog.show(Kikit.this, "", "Fetching location...", true);
final Handler handler = new Handler();
timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run()
{
Log.e("counter value","value "+counter);
if(counter<=8)
{
try
{
counter++;
if (network_enabled) {
lm = (LocationManager) Kikit.this.getSystemService(Context.LOCATION_SERVICE);
Log.e("in network_enabled..","in network_enabled");
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener()
{
public void onLocationChanged(Location location)
{
if(attempt == false)
{
attempt = true;
Log.e("in location listener..","in location listener..");
longi = location.getLongitude();
lati = location.getLatitude();
Data.longi = "" + longi;
Data.lati = "" + lati;
Log.e("longitude : ",""+longi);
Log.e("latitude : ",""+lati);
if(faceboo_name.equals(""))
{
if(dialog!=null){
dialog.cancel();}
timer.cancel();
timer.purge();
Data.homepage_resume = true;
lm = null;
Intent intent = new Intent();
intent.setClass(Kikit.this,MainActivity.class);
startActivity(intent);
finish();
}
else
{
isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent)
{
if(dialog!=null)
dialog.cancel();
Showdata();
}
else
{
error_view.setText(Data.internet_error_msg);
error_view.setVisibility(0);
error_gone();
}
}
}
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
public void onProviderEnabled(String provider) {
//Toast.makeText(getApplicationContext(), "Location enabled", Toast.LENGTH_LONG).show();
}
public void onProviderDisabled(String provider) {
}
};
// Register the listener with the Location Manager to receive
// location updates
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100000, 10,locationListener);
} else{
//Toast.makeText(getApplicationContext(), "No Internet Connection.", 2000).show();
buildAlertMessageNoGps();
}
} catch (Exception e) {
// TODO
// Auto-generated
// catch
// block
}
}
else
{
timer.purge();
timer.cancel();
if(attempt == false)
{
attempt = true;
String locationProvider = LocationManager.NETWORK_PROVIDER;
// Or use LocationManager.GPS_PROVIDER
try {
Location lastKnownLocation = lm.getLastKnownLocation(locationProvider);
longi = lastKnownLocation.getLongitude();
lati = lastKnownLocation.getLatitude();
Data.longi = "" + longi;
Data.lati = "" + lati;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("exception in loc fetch", e.toString());
}
Log.e("longitude of last known location : ",""+longi);
Log.e("latitude of last known location : ",""+lati);
if(Data.fb_access_token == "")
{
if(dialog!=null){
dialog.cancel();}
timer.cancel();
timer.purge();
Data.homepage_resume = true;
Intent intent = new Intent();
intent.setClass(Kikit.this,MainActivity.class);
startActivity(intent);
finish();
}
else
{
isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent)
{
if(dialog!=null){
dialog.cancel();}
Showdata();
}
else
{
error_view.setText(Data.internet_error_msg);
error_view.setVisibility(0);
error_gone();
}
}
}
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 2000);
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your WiFi & mobile network location is disabled , do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id)
{
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
setting_page = true;
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
dialog.cancel();
finish();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
在android系统中获取位置更新需要很多东西,需要大量的bolierplate代码。
你需要照顾好
Google Play服务可用性检查,更新Google play服务,如果它是旧的或不可用GoogleApiClient的对话框创建及其连接、断开等回调。停止并释放用于位置更新的资源处理位置权限方案检查位置服务是否打开或关闭获取最新位置也不是那么容易如果在一定时间后未找到位置,则回退到最后一个已知位置
我已经创建了Android EasyLocation(小型Android库),它将处理所有这些事情,您可以专注于业务逻辑。
您只需要扩展EasyLocationActivity
requestSingleLocationFix(easyLocationRequest);
or
requestLocationUpdates(easyLocationRequest);
点击此处查看示例应用程序和所需步骤https://github.com/akhgupta/Android-EasyLocation
你可以一直使用LocationManager.getLastKnownLocation(),但就像它说的那样,它可能已经过时了。
获取一般位置的一个简单方法是注册网络(通常很快)。
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 1000, 1000, this);
然后做
locationManager.removeUpdates(this);
在侦听器的onLocationChanged()方法中。
实际上,我们可以使用两个提供商(GPS和网络)。他们只是分享一个公共听众:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, (float) 10.0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 90 * 1000, (float) 10.0, listener);
这是必要的,因为总是需要及时调用OnLocationChanged()方法。