如何在 Android 中使用 gps 获取当前位置(街道、城市等)

Posted

技术标签:

【中文标题】如何在 Android 中使用 gps 获取当前位置(街道、城市等)【英文标题】:How to get Current Location(Street,City, etc,..) using gps in Android 【发布时间】:2017-01-06 05:32:32 【问题描述】:

我想创建一个应用程序来跟踪安装我的应用程序的用户,所以我有一个跟踪代码,此代码运行良好,但它只会返回城市名称。但我需要完整的详细信息,如街道名称、城市等。

    public class GetCurrentLocation extends Activity
        implements OnClickListener 

    private LocationManager locationMangaer = null;
    private LocationListener locationListener = null;

    private Button btnGetLocation = null;
    private EditText editLocation = null;
    private ProgressBar pb = null;

    private static final String TAG = "Debug";
    private Boolean flag = false;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //if you want to lock screen for always Portrait mode
        setRequestedOrientation(ActivityInfo
                .SCREEN_ORIENTATION_PORTRAIT);

        pb = (ProgressBar) findViewById(R.id.progressBar1);
        pb.setVisibility(View.INVISIBLE);

        editLocation = (EditText) findViewById(R.id.editTextLocation);

        btnGetLocation = (Button) findViewById(R.id.btnLocation);
        btnGetLocation.setOnClickListener(this);

        locationMangaer = (LocationManager)
                getSystemService(Context.LOCATION_SERVICE);

    

    @Override
    public void onClick(View v) 
        flag = displayGpsStatus();
        if (flag) 

            Log.v(TAG, "onClick");

            editLocation.setText("Please!! move your device to" +
                    " see the changes in coordinates." + "\nWait..");

            pb.setVisibility(View.VISIBLE);
            locationListener = new MyLocationListener();

            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;
            
            locationMangaer.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);

         else 
            alertbox("Gps Status!!", "Your GPS is: OFF");
        

    

    /*----Method to Check GPS is enable or disable ----- */
    private Boolean displayGpsStatus() 
        ContentResolver contentResolver = getBaseContext()
                .getContentResolver();
        boolean gpsStatus = Settings.Secure
                .isLocationProviderEnabled(contentResolver,
                        LocationManager.GPS_PROVIDER);
        if (gpsStatus) 
            return true;

         else 
            return false;
        
    

    /*----------Method to create an AlertBox ------------- */
    protected void alertbox(String title, String mymessage) 
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Your Device's GPS is Disable")
                .setCancelable(false)
                .setTitle("** Gps Status **")
                .setPositiveButton("Gps On",
                        new DialogInterface.OnClickListener() 
                            public void onClick(DialogInterface dialog, int id) 
                                // finish the current activity
                                // AlertBoxAdvance.this.finish();
                                Intent myIntent = new Intent(
                                        Settings.ACTION_SECURITY_SETTINGS);
                                startActivity(myIntent);
                                dialog.cancel();
                            
                        )
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() 
                            public void onClick(DialogInterface dialog, int id) 
                                // cancel the dialog box
                                dialog.cancel();
                            
                        );
        AlertDialog alert = builder.create();
        alert.show();
    

    /*----------Listener class to get coordinates ------------- */
    private class MyLocationListener implements LocationListener 
        @Override
        public void onLocationChanged(Location loc) 

            editLocation.setText("");
            pb.setVisibility(View.INVISIBLE);
            Toast.makeText(getBaseContext(),"Location changed : Lat: " +
                            loc.getLatitude()+ " Lng: " + loc.getLongitude(),
                    Toast.LENGTH_SHORT).show();
            String longitude = "Longitude: " +loc.getLongitude();
            Log.v(TAG, longitude);
            String latitude = "Latitude: " +loc.getLatitude();
            Log.v(TAG, latitude);

    /*----------to get City-Name from coordinates ------------- */
            String cityName=null;
            Geocoder gcd = new Geocoder(getBaseContext(),
                    Locale.getDefault());
            List<Address>  addresses;
            try 
                addresses = gcd.getFromLocation(loc.getLatitude(), loc
                        .getLongitude(), 1);
                if (addresses.size() > 0)
                    System.out.println(addresses.get(0).getLocality());
                cityName=addresses.get(0).getLocality();
             catch (IOException e) 
                e.printStackTrace();
            

            String s = longitude+"\n"+latitude +
                    "\n\nMy Currrent City is: "+cityName;
            editLocation.setText(s);
        

        @Override
        public void onProviderDisabled(String provider) 
            // TODO Auto-generated method stub
        

        @Override
        public void onProviderEnabled(String provider) 
            // TODO Auto-generated method stub
        

        @Override
        public void onStatusChanged(String provider,
                                    int status, Bundle extras) 
            // TODO Auto-generated method stub
        
    

【问题讨论】:

【参考方案1】:

试试这个:

public void setCurrentLocation() 
        if (UtilityMethods.isGPSEnabled(mContext)) 
            if (Build.VERSION.SDK_INT >= 23 &&
                    ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 

                requestPermissions(LOCATION_PERMS, LOCATION_REQUEST);
                // return;
             else 
                getCurrentAddress();
            

         else 
            alertbox("Gps Status", "Your Device's GPS is Disable", mContext);
        
    

使用位置管理器

    public void getCurrentAddress() 
        // Get the location manager
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        if (locationManager != null) 

            try 

                if (Build.VERSION.SDK_INT >= 23 && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
                    // TODO: Consider calling
                    //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                    // 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 Activity#requestPermissions for more details.
                    return;
                
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
             catch (Exception ex) 
                Log.i("msg", "fail to request location update, ignore", ex);
            
            if (locationManager != null) 
                location = locationManager
                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            
            Geocoder gcd = new Geocoder(getBaseContext(),
                    Locale.getDefault());
            List<Address> addresses;
            try 
                addresses = gcd.getFromLocation(location.getLatitude(),
                        location.getLongitude(), 1);
                if (addresses.size() > 0) 
                    String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                    String locality = addresses.get(0).getLocality();
                    String subLocality = addresses.get(0).getSubLocality();
                    String state = addresses.get(0).getAdminArea();
                    String country = addresses.get(0).getCountryName();
                    String postalCode = addresses.get(0).getPostalCode();
                    String knownName = addresses.get(0).getFeatureName();
                    if (subLocality != null) 

                        currentLocation = locality + "," + subLocality;
                     else 

                        currentLocation = locality;
                    
                    current_locality = locality;
                

             catch (Exception e) 
                e.printStackTrace();
                Toast.makeText(HomeActivity.this, Constants.ToastConstatnts.ERROR_FETCHING_LOCATION, Toast.LENGTH_SHORT).show();
            
        
    

【讨论】:

我试过“地理编码器”,它不会给我当前位置的确切当前地址。它给了我所有附近位置的地址数组。我想获得确切的当前位置。我有我当前位置的经度和纬度。 非常有帮助。我用你的技术返回一个字符串,效果更好【参考方案2】:

使用fused Location Provider获取当前设备的经纬度。

借助经纬度,您可以获得城市名称和地址。

要获取完整的街道名称,请使用getMaxAddressLineIndex()。

在 onLocationChanged 中,检查您是否获取当前位置。

编辑:

String strAdd = "";

 @Override
    public void onLocationChanged(Location loc) 

        editLocation.setText("");
        pb.setVisibility(View.INVISIBLE);
        Toast.makeText(getBaseContext(),"Location changed : Lat: " +
                        loc.getLatitude()+ " Lng: " + loc.getLongitude(),
                Toast.LENGTH_SHORT).show();
        String longitude = "Longitude: " +loc.getLongitude();
        Log.v(TAG, longitude);
        String latitude = "Latitude: " +loc.getLatitude();
        Log.v(TAG, latitude);

   /*----------to get City-Name from coordinates ------------- */
        String cityName=null;


         Geocoder geocoder;
      List<Address> addresses;

    geocoder = new Geocoder(TabClubActivity.this, Locale.getDefault());

        try 

          addresses = geocoder.getFromLocation(latitude, longitude, 1); 


     if (!addresses.isEmpty()) 
            Address returnedAddress = addresses.get(0);
            StringBuilder strReturnedAddress = new StringBuilder("");

            for (int i = 0; i < returnedAddress.getMaxAddressLineIndex(); i++) 
                strReturnedAddress.append(returnedAddress.getAddressLine(i)).append(" ");
            
            strAdd = strReturnedAddress.toString();

            textview.setText(strAdd);

              Log.e("MyCurrentLoctionAddress", "" + strReturnedAddress.toString());

              cityName=addresses.get(0).getLocality();



         else 

    //      Log.e("MyCurrentLoctionAddress", "No Address returned!");

        

     catch (IOException e) 
        e.printStackTrace();
    

        String s = longitude+"\n"+latitude +
                "\n\nMy Currrent City is: "+cityName;
        editLocation.setText(s);
    

【讨论】:

@T.KarthikeyanT.Karthikeyan 在你的 onlocationchanged 中使用我的 try and catch 块 @T.KarthikeyanT.Karthikeyan 只需复制并粘贴 onLocationchanged()。我进行了更改。 addresses = geocoder.getFromLocation(latitude, longitude, 1); 中的错误 @T.KarthikeyanT.Karthikeyan 你没有得到纬度和经度。这就是您收到错误消息的原因。请按照此javapapers.com/android/android-location-fused-provider 获取经度和纬度。 @T.KarthikeyanT.Karthikeyan 你在 MyCurrentLoctionAddress.debug 中获得了什么价值并告诉我【参考方案3】:

我尝试了Geocoder,但结果不可靠。所以最好去附近搜索 googleapi 的结果。它直接提供城市名称。这是我的实现版本。

interface Api
String BASE_URL = "https://maps.googleapis.com";

@GET("/maps/api/place/nearbysearch/json")
   Call<List<ResultDO>> getPlaceDetailByLatLong(@Query("location") String type,@Query("radius") String radius,@Query("key")String key);

在主要活动或片段中。

Retrofit retrofit = new Retrofit.Builder() 
            .baseUrl(API.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
API service = retrofit.create(API.class);

service.getCityResults(types, input, location, radius, key).enqueue(new Callback<List<ResultDO>>() 
        @Override
       public void onResponse(Call<List<ResultDO>> call, Response<List<ResultDO>> response) 
            tvCity.setText(response.body().get(0).getVicinity());// first object gives me the city name
       

        @Override
       public void onFailure(Call<List<ResultDO>> call, Throwable t) 
       
);

【讨论】:

【参考方案4】:

您可以通过将地理位置(例如纬度、经度)转换为地址来获取地址(街道名称、城市、国家/地区等)。这个过程称为Reverse Geocodingthis doc。

您可以使用 FusedLocationProviderApi(),但它已被弃用 (here)。另一种方法是,您可以使用FusedLocationProviderClient() 从 LastKnownLocation 对象(包含纬度和经度)中获取 LastKnownLocation,因此我们可以使用 Geocoder 获取街道名称、城市、国家等地址。 The sample doc 同步执行。但在这里我正在使用AsyncTask 进行异步操作。希望对您有所帮助。

获取当前位置:

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.tasks.OnCompleteListener;

public class MainActivity extends AppCompatActivity
//before public class MainActivity extends AppCompatActivity implements LocationListener,...,...


private static final String TAG = "MainActivity";
public static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 101;
private FusedLocationProviderClient mFusedLocationClient;
private Location mGetedLocation;

private double currentLat, currentLng;

private void getLastLocation() 
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
            requestPermissions(new String[] Manifest.permission.ACCESS_FINE_LOCATION, MY_PERMISSIONS_REQUEST_FINE_LOCATION);
        
        return;
    
    mFusedLocationClient.getLastLocation()
            .addOnCompleteListener(this, new OnCompleteListener<Location>() 
                @Override
                public void onComplete(@NonNull Task<Location> task) 
                    if (task.isSuccessful() && task.getResult() != null) 

                        mGetedLocation = task.getResult();
                        //currentLat = mGetedLocation.getLatitude();
                        //currentLng = mGetedLocation.getLongitude();

                        //start reverse geocoding
                        //little different with the doc
                        (new GetAddressTask(this)).execute(mGetedLocation);

                    else
                        Log.e(TAG, "no location detected");
                        Log.w(TAG, "getLastLocation:exception", task.getException());
                    
                
            );


从 LastKnownLocation 获取地址

//sorry, I forgot where I got this asyncTask code. So I did not mention the source. 
//If anyone feels that making this code please comment.


private class GetAddressTask extends AsyncTask<Location, Void, String> 
    Context mContext;

    GetAddressTask(Context context) 
        super();
        mContext = context;
    

    @Override
    protected String doInBackground(Location... params) 
        Geocoder geocoder =
                new Geocoder(mContext, Locale.getDefault());
        // Get the current location from the input parameter list
        Location loc = params[0];
        // Create a list to contain the result address
        List<Address> addresses;
        try 
            addresses = geocoder.getFromLocation(loc.getLatitude(),
                    loc.getLongitude(), 1);
         catch (IOException e1) 
            Log.e("LocationSampleActivity",
                    "IO Exception in getFromLocation()");
            e1.printStackTrace();
            return ("IO Exception trying to get address");
         catch (IllegalArgumentException e2) 
            // Error message to post in the log
            String errorString = "Illegal arguments " +
                    Double.toString(loc.getLatitude()) +
                    " , " +
                    Double.toString(loc.getLongitude()) +
                    " passed to address service";
            Log.e("LocationSampleActivity", errorString);
            e2.printStackTrace();
            return errorString;
        
        // If the reverse geocode returned an address
        if (addresses != null && addresses.size() > 0) 
            Address address = addresses.get(0);
        /*
                    address.getLocality(),
                    address.getCountryName());
        */
            return address.getLocality();
         else 
            return "No address found";
        
    

    @Override
    protected void onPostExecute(String address) 
        if (address != null)
        mtextView.setText(address);//=============================> GOT THIS
    

【讨论】:

【参考方案5】:

在Activity Class中自定义方法:

  private void getTheUserPermission() 
        ActivityCompat.requestPermissions(this, new String[]
                Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_LOCATION);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        LocationGetter locationGetter = new LocationGetter(FreshMenuSearchActivity.this, REQUEST_LOCATION, locationManager);


        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 

            locationGetter.OnGPS();
         else 

            locationGetter.getLocation();
        
    

创建一个 UserDefined 类名 LocationGetter:-

public class LocationGetter 

    private int REQUEST_LOCATION;
    private FreshMenuSearchActivity mContext;
    private LocationManager locationManager;
    private Geocoder geocoder;

    public LocationGetter(FreshMenuSearchActivity mContext, int requestLocation, LocationManager locationManager) 
        this.mContext = mContext;
        this.locationManager = locationManager;
        this.REQUEST_LOCATION = requestLocation;
    


    public void getLocation() 

        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,

                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
            ActivityCompat.requestPermissions(mContext, new String[]
                    Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_LOCATION);
         else 
            Location LocationGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            Location LocationNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            Location LocationPassive = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

            if (LocationGps != null) 
                double lat = LocationGps.getLatitude();
                double longi = LocationGps.getLongitude();
                getTheAddress(lat, longi);
             else if (LocationNetwork != null) 
                double lat = LocationNetwork.getLatitude();
                double longi = LocationNetwork.getLongitude();
                getTheAddress(lat, longi);
             else if (LocationPassive != null) 
                double lat = LocationPassive.getLatitude();
                double longi = LocationPassive.getLongitude();
                getTheAddress(lat, longi);
             else 
                Toast.makeText(mContext, "Can't Get Your Location", Toast.LENGTH_SHORT).show();
            

        

    

    private void getTheAddress(double latitude, double longitude) 
        List<Address> addresses;
        geocoder = new Geocoder(mContext, Locale.getDefault());

        try 
            addresses = geocoder.getFromLocation(latitude, longitude, 1);
            String address = addresses.get(0).getAddressLine(0);
            String city = addresses.get(0).getLocality();
            String state = addresses.get(0).getAdminArea();
            String country = addresses.get(0).getCountryName();
            String postalCode = addresses.get(0).getPostalCode();
            String knownName = addresses.get(0).getFeatureName();
            Log.d("neel", address);
         catch (IOException e) 
            e.printStackTrace();
        


    

    public void OnGPS() 

        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

        builder.setMessage("Enable GPS").setCancelable(false).setPositiveButton("YES", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialog, int which) 
                mContext.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
            
        ).setNegativeButton("NO", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialog, int which) 

                dialog.cancel();
            
        );
        final AlertDialog alertDialog = builder.create();
        alertDialog.show();
    


【讨论】:

以上是关于如何在 Android 中使用 gps 获取当前位置(街道、城市等)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中使用 gps 获取当前位置(街道、城市等)

Android:如何使用 GPS 提供程序获取离线当前位置?

如何使用 GPS 获取我在 Android 中的当前位置?

在 Android 中使用 GPS 获取当前位置

如何使用 Google App 或 GPS 获取当前位置? [复制]

如何获取 Android GPS 位置