前言
在开发 Android 位置相关应用时,可以从 GPS(全球定位系统)、passive、network 获取用户位置。通过 GPS 能获得最精确的信息。
LocationProvider 是位置源的意思,用来提供定位信息。
常用的 LocationProvider
方法名 |
描述 |
passive |
被动定位方式,即利用其他应用程序使用定位更新了定位信息,系统会保存下来,该应用接收到消息后直接读取即可 |
gps |
通过手机里面的 GPS 芯片利用卫星获取定位信息 |
network |
通过网络获取定位信息。通常利用手机基站和 WIFI节点的地址来大致定位 |
LocationManager:该类提供系统定位服务访问功能。
LocationManager 提供的常用的方法
方法名 |
描述 |
list getAllProviders() |
获取所有的 LocationProvider 列表 |
Location getLastKnowLocation(String provider) |
根据 LocationProvider 获取最近一次已知的 Location |
LocationProvider getProvider(String name) |
根据名称来获取 LocationProvider |
void requestLocationUpdates (String provider, long minTime, float minDistance, PendingIntent intent) |
通过指定的 LocationProvider 周期性地获取定位信息,并通过 intent 启动相应的组件 |
void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) |
通过指定的 LocationProvider 周期性地获取定位信息,并触发 listener 所对应的触发器 |
LocationProvider:定位组件的抽象表示,通过该类可以获取该定位组件的相关信息。
LocationProvider 提供的常用方法
方法名 |
描述 |
int getAccuracy() |
返回 LocationProvider 的精度 |
String getName() |
返回 LocationProvider 的名称 |
int getPowerRequirement() |
获取 LocationProvider 的电源需求 |
Location:该类表示特定时间地理位置信息,位置由经度、纬度、UTC时间戳以及可选的高度、速度、方向等组成。
Location 提供的常用方法
方法名 |
描述 |
float getAccuracy() |
获取定位信息的精度 |
double getAltitude() |
获取定位信息的高度 |
float getBearing() |
获取定位信息的方向 |
double getLatitude() |
获取定位信息的纬度 |
double getLongitude() |
获取定位信息的经度 |
String getProvider() |
获取提供该定位信息的 LocationProvider |
float getSpeed() |
获取定位信息的速度 |
举例说明:获取所有可用的 Location Provider
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//获取显示 LocationProvider 名称的 TextView 组件
TextView textView = findViewById(R.id.text2);
//获取 location 服务
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
//获取系统所有的 LocationProvider 名称
List<String> providerNames = locationManager.getAllProviders();
//使用 StringBuilder 保存数据
StringBuilder stringBuilder = new StringBuilder();
//遍历获取到的全部 Locationprovider 名称
for(Iterator<String> iterator = providerNames.iterator(); iterator.hasNext(); ) {
stringBuilder.append(iterator.next() + "\n");
}
//显示 LocationProvider 名称
textView.setText(stringBuilder.toString());
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="可用LocationProvider:"
android:layout_marginTop="100dp"
android:textSize="40dp"
android:id="@+id/text1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text2"
android:textSize="35dp"
android:layout_marginLeft="20dp"
android:layout_below="@+id/text1"
/>
</RelativeLayout>
结果
举例说明:获取动态定位信息
public class MainActivity extends Activity {
//获取系统的 LocationManager 对象
private LocationManager locationManager;
//定义显示 LocationProvider 的 TextView 组件
private TextView provider;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
provider = findViewById(R.id.provider);
//检测用户是否打开GPS
if (!isGpsAble(locationManager)) {
Toast.makeText(MainActivity.this, "请打开GPS", Toast.LENGTH_SHORT).show();
openGPS2();
}
//检测用户是否允许定位
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//提供开启定位的指导界面
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
} else {
//获取GPS信息
startLocation();
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//用户同意权限
if (requestCode == 200) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
startLocation();
else //用户拒绝之后,当然我们也可以弹出一个窗口,直接跳转到系统设置页面
Toast.makeText(MainActivity.this,
"请手动开启权限", Toast.LENGTH_LONG).show();
}
}
//禁止权限检查
@SuppressLint("MissingPermission")
private void startLocation(){
//从GPS获取最近的定位信息
Location lc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//更新信息
updateShow(lc);
//2秒获取一次、位置间隔1米
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, new LocationListener() {
//GPS信息变化则更新
@Override
public void onLocationChanged(Location location) {
updateShow(location);
}
//位置状态发生改变时更新
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
//定位提供者启动时触发
@Override
public void onProviderEnabled(String provider) {
}
//定位提供者关闭时触发
@Override
public void onProviderDisabled(String provider) {
}
});
}
//更新GPS数据
@SuppressLint("SetTextI18n")
private void updateShow(Location location) {
if (location != null) {
String string = "当前的位置信息:"
+ "\n经度:" + location.getLongitude()
+ "\n纬度:" + location.getLatitude()
+ "\n高度:" + location.getAltitude()
+ "\n速度:" + location.getSpeed()
+ "\n方向:" + location.getBearing()
+ "\n定位精度:" + location.getAccuracy();
provider.setText(string);
} else provider.setText("没有获取GPS信息");
}
//返回 GPS 状态
private boolean isGpsAble(LocationManager lm) {
return lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
//打开设置页面
private void openGPS2() {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, 0);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:textStyle="bold"
android:layout_marginTop="100dp"
android:layout_marginLeft="20dp"
android:textSize="20sp"
android:padding="5dp"
android:id="@+id/provider"
/>
</RelativeLayout>
结果