Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:从最佳可用提供商处获取当前位置_Android - Fatal编程技术网

Android:从最佳可用提供商处获取当前位置

Android:从最佳可用提供商处获取当前位置,android,Android,我有一些Android代码,需要快速从GPS、网络或任何可用的位置获取最佳可用位置。准确度不如速度重要 获得最佳可用位置肯定是一项真正的标准任务。但是我找不到任何代码来演示它。Android位置代码要求你指定标准,注册更新,然后等待——如果你有详细的标准并且不介意等待,这是很好的 但我的应用程序需要更像地图应用程序在第一次找到你时那样工作——从任何可用的提供商那里工作,只需检查位置是否完全过时或为空 我已经尝试使用自己的代码来实现这一点,但遇到了问题。(如果有什么区别的话,上传是在IntentS

我有一些Android代码,需要快速从GPS、网络或任何可用的位置获取最佳可用位置。准确度不如速度重要

获得最佳可用位置肯定是一项真正的标准任务。但是我找不到任何代码来演示它。Android位置代码要求你指定标准,注册更新,然后等待——如果你有详细的标准并且不介意等待,这是很好的

但我的应用程序需要更像地图应用程序在第一次找到你时那样工作——从任何可用的提供商那里工作,只需检查位置是否完全过时或为空

我已经尝试使用自己的代码来实现这一点,但遇到了问题。(如果有什么区别的话,上传是在IntentService内部进行的。我已经包含了所有的信息代码。)这个代码有什么问题

@Override
protected void onHandleIntent(Intent arg0) {
    testProviders();
    doUpload();
}
private boolean doUpload() {
       int j = 0;
       // check if we have accurate location data yet - wait up to 30 seconds
       while (j < 30) {
           if ((latString == "") || (lonString == "")) {
               Log.d(LOG_TAG, "latlng null");
               Thread.sleep(1000);
               j++;
       } else {
                Log.d(LOG_TAG, "found lat " + latString + " and lon " + lonString);
            break;
       }
       //do the upload here anyway, with or without location data
       //[code removed for brevity]
}
public boolean testProviders() {
    Log.e(LOG_TAG, "testProviders");
    String location_context = Context.LOCATION_SERVICE;
    locationmanager = (LocationManager) getSystemService(location_context);
    List<String> providers = locationmanager.getProviders(true);
    for (String provider : providers) {
        Log.e(LOG_TAG, "registering provider " + provider);
        listener = new LocationListener() {
            public void onLocationChanged(Location location) {
                // keep checking the location - until we have
                // what we need
                //if (!checkLoc(location)) {
                Log.e(LOG_TAG, "onLocationChanged");
                locationDetermined = checkLoc(location);
                //}
            }
            public void onProviderDisabled(String provider) {
            }
            public void onProviderEnabled(String provider) {
            }
            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
            }
        };
        locationmanager.requestLocationUpdates(provider, 0,
                0, listener);
    }
    Log.e(LOG_TAG, "getting updates");
    return true;
}
private boolean checkLoc(Location location) {
    float tempAccuracy = location.getAccuracy();
    int locAccuracy = (int) tempAccuracy;
    Log.d(LOG_TAG, "locAccuracy = " + locAccuracy);
    if ((locAccuracy != 0) && (locAccuracy < LOCATION_ACCURACY)) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        latString = latitude.toString();
        lonString = longitude.toString();
        return true;
    }
    return false;
}
public void removeListeners() {
    // Log.e(LOG_TAG, "removeListeners");
    if ((locationmanager != null) && (listener != null)) {
        locationmanager.removeUpdates(listener);
    }
    locationmanager = null;
    // Log.d(LOG_TAG, "Removed " + listener.toString());
}
@Override
public void onDestroy() {
    super.onDestroy();
    removeListeners();
}
似乎暗示网络供应商确实有一些位置信息,毕竟,我只是不明白


有人能帮忙吗?我认为工作示例代码将是Android/StackOverflow社区的有用资源。

生产代码中的Thread.sleep()是一种严重的代码气味。如果你发现你必须这样做,你可能在做一些不应该这样做的事情。在这种情况下,我认为这是你的问题的根源——你不能让Android回去处理这个线程的消息队列来发送它找到的任何位置更新。我怀疑
IntentService
对您的场景不起作用。

您肯定是在努力做到这一点。下面是我正在开发的一个新应用程序的一些片段。它用于让所有提供商能够在无成本的情况下返回高精度

如果未启用任何提供程序,将显示一个对话框,提示用户打开其位置设置。如果用户点击ok,实际上会触发一个意向,将其发送到手机上的设置。如果有已启用的提供商,则应用程序将从任何已启用的提供商获取最新的。对于我的应用程序,我只需要知道用户所在的一般区域,最后一个已知位置很可能是他们的家乡

如果启用了提供程序,循环也会尽快请求位置更新。这是我的应用程序的理想选择,但您可以更改此选项以节省电池电量,并修改应用程序的参数

这段代码中的优化(Android应用程序上的示例并未真正显示)是所有启用的提供者都同时启动。所有提供程序将在上返回单独的更新。在我的应用程序中,当其中一个提供商以足够高的精度返回位置后,我删除位置侦听器

开始位置更新:

void getCurrentLocation() {
    List<String> providers = locationManager.getProviders(criteria, true);
    if (providers != null) {
        Location newestLocation = null;
        for (String provider : providers) {
            Location location = locationManager.getLastKnownLocation(provider);
            if (location != null) {
                if (newestLocation == null) {
                    newestLocation = location;
                } else {
                    if (location.getTime() > newestLocation.getTime()) {
                        newestLocation = location;
                    }
                }
                locationManager.requestLocationUpdates(provider, 0, 0, this);
            }
        }
    } else {
        LocationDialogFragment dialog = new LocationDialogFragment();
        dialog.show(getSupportFragmentManager(),
            LocationDialogFragment.class.getName());
    }
}

谢谢我想我会在正常活动中这样做,然后将lat/lon传递给IntentService。我仍然非常喜欢一个如何检查所有LocationProviders并选择最佳位置的示例-如果有人有任何示例代码,请发布它。。。如果没有,我将尝试破解某些东西并将其发布到这里。@commonware-您建议我如何在不使用Thread.sleep()的情况下实现以下内容?“持续检查位置更新30秒;如果到那时还没有找到最新的位置,请放弃并使用虚拟值。”Thread.sleep可以用于生产代码中有无数个原因(尽管我在这里不一定要说)。也许我的代码示例可以帮到很好的解决方案!只有一件事需要指出。这可能是由于API中的更改,但是条件
(providers!=null)
必须是
(privers.size()>0)
,因为
getProviders(Criteria,boolean)
方法从不返回
null
,相反,它可以返回一个大小为0的列表。我想我记得当我测试这个时并不准确,但我想我们必须看文档。无论如何,每个人都应该知道Google Play服务库中的FusedLocationProvider比旧的location类优越得多。但实现方式却大不相同。这项技术有点过时。你能告诉我们你是如何建立“标准”对象的。。。我还需要一个大概的位置(城市精度)
void getCurrentLocation() {
    List<String> providers = locationManager.getProviders(criteria, true);
    if (providers != null) {
        Location newestLocation = null;
        for (String provider : providers) {
            Location location = locationManager.getLastKnownLocation(provider);
            if (location != null) {
                if (newestLocation == null) {
                    newestLocation = location;
                } else {
                    if (location.getTime() > newestLocation.getTime()) {
                        newestLocation = location;
                    }
                }
                locationManager.requestLocationUpdates(provider, 0, 0, this);
            }
        }
    } else {
        LocationDialogFragment dialog = new LocationDialogFragment();
        dialog.show(getSupportFragmentManager(),
            LocationDialogFragment.class.getName());
    }
}
@Override
public void onLocationChanged(Location location) {
    float bestAccuracy = -1f;
    if (location.getAccuracy() != 0.0f
        && (location.getAccuracy() < bestAccuracy) || bestAccuracy == -1f) {
        if (location.getAccuracy() < Const.MIN_ACCURACY) {
            locationManager.removeUpdates(this);
        }
    }
    bestAccuracy = location.getAccuracy();
}
public class LocationDialogFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.location_dialog_message)
                .setPositiveButton(R.string.location_dialog_positive_button,
                    new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent settingsIntent = new Intent(
                                    Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivity(settingsIntent);
                        }
                    })
                .setNegativeButton(R.string.location_dialog_negative_button,
                    new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(getActivity(),
                                R.string.no_location_message, Toast.LENGTH_LONG)
                                    .show();
                        }
                    });
        return builder.create();
    }
}