最近做一个关于 手机定位的功能,自己记录一下,一来加深记忆,二来希望能给大家一点思路,代码亲测有效。
直接贴代码:
清单文件要加的权限,代码中还有动态权限申请
<!--定位权限--> <uses-permission android:name="android.permission.ACCESS_FIND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
布局不在给出只有一个button和一个textView
public class MainActivity extends AppCompatActivity {private Button getLocation; private TextView myLocation; private double latitudeGps; private double longitudeGps; private double latitudeNet; private double longitudeNet; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); setListener(); }private void setListener() {getLocation.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View view) {myLocation.setText("您现在的位置经度是:"+longitudeGps+"维度是:"+latitudeGps); }}); }private void initView() {getLocation = (Button) findViewById(R.id.getLocation_btn); myLocation = (TextView) findViewById(R.id.myLocation_tv); getMyLocation(); }public void getMyLocation() {//要加动态权限,清单文件也要加权限 //被拒绝情况 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED) {//申请 ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 0); initLocation(); } else {initLocation(); }}//加载本地位置 private void initLocation() {LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(false); criteria.setPowerRequirement(Criteria.POWER_LOW); // 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 // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; }Location locationGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); Location locationNet = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (locationGps!=null){latitudeGps = locationGps.getLatitude(); longitudeGps = locationGps.getLongitude(); choseLocationType(); }else if (locationNet!=null){latitudeNet = locationNet.getLatitude(); longitudeNet = locationGps.getLongitude(); choseLocationType(); }else {Toast.makeText(MainActivity.this,"获取位置失败,请检查网络",Toast.LENGTH_SHORT).show(); }LocationListener locationListener = new LocationListener() {@Override public void onLocationChanged(Location location) {}@Override public void onStatusChanged(String s, int i, Bundle bundle) {}@Override public void onProviderEnabled(String s) {}@Override public void onProviderDisabled(String s) {}}; //更新(间隔自己定义) locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,10,1000,locationListener); }private void choseLocationType() {if (latitudeNet>0&&latitudeGps<=0){latitudeGps=latitudeNet; }else if (longitudeNet>0&&longitudeGps<=0){longitudeGps=longitudeNet; }} }
请注意以下几点:
一:第一次打开app可能获取到为0.0,关闭app再代开就可以,以后都正常,因为这里用了getLastKnowLocation 获得最后一次的
二:本文是获取经纬度,如果您还需要获取具体位置,可以尝试一下Goolge的location包提供的Geocoder类,他可以把经纬度转成具体位置还可以把具体位置转为经纬度,但鉴于Google服务的稳定性,您可以考虑一下借助百度的服务来获取具体位置信息。
三:关于Criteria类,这里引用一位大神的翻译我就直接贴过来了
在使用android lcoation的时候,可能不希望自己去硬性的选择是GPS服务还是NETWORK服务,可能是我们考虑的因素有很多,自己很难决定,Android SDK提供了一个类Criteria,直译为标准。
在使用android lcoation的时候,可能不希望自己去硬性的
public String getBestProvider (Criteria criteria, boolean enabledOnly)
Since: API Level 1
Returns the name of the provider that best meets the given criteria. Only providers that are permitted to be accessed by the calling activity will be returned. If several providers meet the criteria, the one with the best accuracy is returned. If no provider meets the criteria, the criteria are loosened in the following sequence:
//翻译:返回满足给定的criteria(标准)的最佳provider,(前面一篇文章提到过两种重要provider的区别)。只有当provider权限允许的时候才会返回,如果几个provider均满足criteria设定的标准,最贴近标准的provider将会被返回。如果没有provider满足,标准将按照下面的序列放宽松。
power requirement
accuracy
bearing
speed
altitude
选择是GPS服务还是NETWORK服务,可能是我们考虑的因素有很多,自己很难决定,Android SDK提供了一个类Criteria,直译为标准。