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

其他回答

其中一些人现在已经过时了,所以我回答说,

FusedLocationProviderClient fusedLocationProviderClient; //set global variable
Location currentLocation;//set global var
private boolean mLocationPermissionGranted; //set global var
 fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getContext()); //write this oncreate
        fetchLastLocation();  // call the funct for current location
//here is the function
private void fetchLastLocation() {

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(getActivity(),new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
        return;
    }else {
        mLocationPermissionGranted=true;
    }
    Task<Location> task= fusedLocationProviderClient.getLastLocation();
    task.addOnSuccessListener(new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            if(location != null){
                currentLocation =location;
               Toast.makeText(getContext(), currentLocation.getLatitude()+"" +
                        " "+currentLocation.getLongitude(), 
                   Toast.LENGTH_SHORT).show();
//if you want to show in google maps
                SupportMapFragment supportMapFragment =(SupportMapFragment)
                        getChildFragmentManager().findFragmentById(R.id.map);
                supportMapFragment.getMapAsync(MapsFragment.this);
            }
        }
    });


}

要获取并显示用户的当前位置,还可以使用MyLocationOverlay。假设您的活动中有一个mapView字段。要显示用户位置,只需执行以下操作:

myLocationOverlay = new MyLocationOverlay(this, mapView);
myLocationOverlay.enableMyLocation();
mapView.getOverlays().add(myLocationOverlay);

这将从GPS或网络获取当前位置。如果两者都失败,enableMyLocation()将返回false。

至于该区域周围事物的位置,ItemizedOverlay应该可以做到这一点。

我希望我没有误解你的问题。祝你好运

实际上,我们可以使用两个提供商(GPS和网络)。他们只是分享一个公共听众:

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, (float) 10.0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 90 * 1000, (float) 10.0, listener);

这是必要的,因为总是需要及时调用OnLocationChanged()方法。

public static Location getBestLocation(Context ctxt) {
    Location gpslocation = getLocationByProvider(
        LocationManager.GPS_PROVIDER, ctxt);
    Location networkLocation = getLocationByProvider(
        LocationManager.NETWORK_PROVIDER, ctxt);
    Location fetchedlocation = null;
    // if we have only one location available, the choice is easy
    if (gpslocation != null) {
        Log.i("New Location Receiver", "GPS Location available.");
        fetchedlocation = gpslocation;
    } else {
        Log.i("New Location Receiver",
            "No GPS Location available. Fetching Network location lat="
                + networkLocation.getLatitude() + " lon ="
                + networkLocation.getLongitude());
        fetchedlocation = networkLocation;
    }
    return fetchedlocation;
}

/**
 * get the last known location from a specific provider (network/gps)
 */
private static Location getLocationByProvider(String provider, Context ctxt) {
    Location location = null;
    // if (!isProviderSupported(provider)) {
    // return null;
    // }
    LocationManager locationManager = (LocationManager) ctxt
            .getSystemService(Context.LOCATION_SERVICE);
    try {
        if (locationManager.isProviderEnabled(provider)) {
            location = locationManager.getLastKnownLocation(provider);
        }
    } catch (IllegalArgumentException e) {
        Log.i("New Location Receiver", "Cannot access Provider " + provider);
    }
    return location;
}

在android系统中获取位置更新需要很多东西,需要大量的bolierplate代码。

你需要照顾好

Google Play服务可用性检查,更新Google play服务,如果它是旧的或不可用GoogleApiClient的对话框创建及其连接、断开等回调。停止并释放用于位置更新的资源处理位置权限方案检查位置服务是否打开或关闭获取最新位置也不是那么容易如果在一定时间后未找到位置,则回退到最后一个已知位置

我已经创建了Android EasyLocation(小型Android库),它将处理所有这些事情,您可以专注于业务逻辑。

您只需要扩展EasyLocationActivity

requestSingleLocationFix(easyLocationRequest);

or

requestLocationUpdates(easyLocationRequest);

点击此处查看示例应用程序和所需步骤https://github.com/akhgupta/Android-EasyLocation