通過Android自帶的工具實現當前定位 + 2步搞定getBestProvider返回null的問題
今天用Android自帶的LocationManager和Location類實現定位,然而中間卻出了點問題,那就是getBestProvider在真機上測試返回null值。查閱了很多方法都沒有效果,於是我自己靈機一動想出了較好的解決辦法。
基本代碼如下
import .... //導入包就不寫了
public class MainActivity extends AppCompatActivity {
//設置權限用的
private static final int BAIDU_READ_PHONE_STATE = 100;//定位權限請求
private static final int PRIVATE_CODE = 1315;//開啓GPS權限
private static final String perms[] = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.INTERNET
};
//監聽類實現動態獲取當前位置
private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Toast.makeText(MainActivity.this, "long= " + location.getLongitude() + " latitude= " + location.getLatitude(), Toast.LENGTH_LONG).show();
//根據個人需要添加動態獲取位置的代碼塊
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
...
getMyLocation(this);//獲取當前位置的方法
}
public void getMyLocation(Context context){
LocationManager lm = (LocationManager)context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
// 檢查是否有相關定位權限
if(!checkPermission(context)){
Toast.makeText(context, "請打開權限", Toast.LENGTH_SHORT).show();
return;
}
//定位要求
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗
List<String> provider = lm.getProviders(true); // 獲取GPS信息
// String provider = lm.getBestProvider(criteria,true); // 獲取GPS信息
Location location = null;
int i = 0;
do {
location = lm.getLastKnownLocation(provider.get(i));
lm.requestLocationUpdates(provider.get(i), 1000, 0,
locationListener);
i++;
}while(location == null && i<provider.size());
if(i == provider.size()){
new AlertDialog.Builder(MainActivity.this).setTitle("WRONG").setMessage("請打開gps或者網絡")
.setCancelable(false).setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
return;
}
}).create().show();
}
//打印結果
Toast.makeText(context, "long= " + location.getLongitude() + " latitude= " + location.getLatitude(), Toast.LENGTH_LONG).show();
}
}
注意了,在getMyLocation方法中,我註釋掉了一句代碼,那就是:
// String provider = lm.getBestProvider(criteria,true); // 獲取GPS信息
爲什麼要註釋掉這句話呢,我測試過在大部分情況下getBestProvider方法返回的都是"gps"(也就是說provider的值爲"gps")然而gps不總是那麼靠譜,有時候會“掛掉”,因此我在這裏選擇了另一種方法,那就是遍歷所有可用的Provider之後當location的值不爲null時結束遍歷,代碼如下:
List<String> provider = lm.getProviders(true); // 獲取GPS信息
Location location = null;
int i = 0;
do {
location = lm.getLastKnownLocation(provider.get(i));
lm.requestLocationUpdates(provider.get(i), 1000, 0,
locationListener);
}while(location == null && i<provider.size());
最後放上檢查權限的代碼
public boolean checkPermission(Context context){
LocationManager lm = (LocationManager)context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
boolean ok = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(ok){
//如果sdk版本大於23也就是android6.0版本以上就要手動添加權限
if(Build.VERSION.SDK_INT>=23){
if(ContextCompat.checkSelfPermission(context,perms[0])!=PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,perms,BAIDU_READ_PHONE_STATE);
}else{
return true;
}
//其他版本的android 就不需要添加權限直接返回true;
}else{
return true;
}
}else{
Toast.makeText(this, "系統檢測到未開啓GPS定位服務,請開啓", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, PRIVATE_CODE);
return false;
}
return true;
}
——————————————結束語————————————————
有問題歡迎大家在留言區留言