简单的位置定位
设备位置定位的方式有两种:GPS定位和网络定位。
1.GPS准确度高但耗电多,
2.网络定位耗电少但准确度低
下面介绍Android中最简单的获得手机地理位置的方法:
1.添加权限
<!-- provider的权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 仅网络定位的权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2.获取定位管理对象
//定义数据
//定位都要通过LocationManager这个类实现
private LocationManager locationManager;
private String provider; //是否为网络位置控制器或GPS定位
//当前可用的位置控制器
List<String> list;
//实例化
//获取定位服务管理对象
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//获取当前可用的位置控制器
list = locationManager.getProviders(true);
3.选择GPS定位还是选择网络定位,最好选择GPS。
//检查是否打开了GPS或网络定位
if (list.contains(LocationManager.GPS_PROVIDER)) {
//是否为GPS位置控制器
provider = LocationManager.GPS_PROVIDER;
textView.append("GPS位置控制器" + "\n");
} else if (list.contains(LocationManager.NETWORK_PROVIDER)) {
//是否为网络位置控制器
provider = LocationManager.NETWORK_PROVIDER;
textView.append("网络位置控制器" + "\n");
} else {
Toast.makeText(this, "请检查网络或GPS是否打开", Toast.LENGTH_LONG).show();
return;
}
4.获取地理位置
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
//获取当前位置,这里只用到了经纬度
String string = " 纬度为:" + location.getLatitude() + ",经度为:"
+ location.getLongitude();
Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
textView.append(string + "\n");
}
5.绑定监听事件,如果位置改变就回调相应的方法
//绑定定位事件,监听位置是否改变
//第一个参数为控制器类型第二个参数为监听位置变化的时间间隔(单位:毫秒)
//第三个参数为位置变化的间隔(单位:米)第四个参数为位置监听器
locationManager.requestLocationUpdates(provider, 2000, 2,
locationListener);
执行上面的代码前还要创建一个监听对象:
LocationListener locationListener = new LocationListener() {
@Override
//状态改变的回调方法
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
@Override
//提供者(网络或GPS)被打开的回调方法
public void onProviderEnabled(String arg0) {
}
@Override
//提供者(网络或GPS)被关闭的回调方法
public void onProviderDisabled(String arg0) {
}
@Override
//经纬度改变的回调方法,基本都是使用这个回调方法
public void onLocationChanged(Location arg0) {
// 更新当前经纬度
// Toast.makeText(MainActivity.this, "" + arg0.toString(), Toast.LENGTH_SHORT).show();
textView.append("经度:" + arg0.getLongitude() + ",纬度:" + arg0.getLatitude() + "\n");
}
};
上面就是最简单的定位的功能代码。但是实际中会报错!因为权限的请求问题!还有API的等级问题!
这里就需要多加几行代码:
if (Build.VERSION.SDK_INT >= 23) {
//如果用户并没有同意该权限
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//申请权限
// requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
} else {
//有权限直接获取地理位置
}
} else {//低版本手机,直接获取位置信息
}
实际上,上面代码方法里面不写东西也是可以的,但是如果没有上面的代码,编译就不通过!
下面是一个简单请求地理位置的程序:
效果:
这里已经打开GPS定位功能了,所以默认显示的GPS定位,否则只能显示网络定位!
1.添加权限
<!-- provider的权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 仅网络定位的权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2.布局设置
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getLocation"
android:text="获取我所在的位置的经纬度" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="bandLocationListener"
android:text="一直监听位置" />
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
3.代码设计
package fuxi.location;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//定位都要通过LocationManager这个类实现
private LocationManager locationManager;
private String provider; //是否为网络位置控制器
//当前可用的位置控制器
List<String> list;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.tv);
//获取定位服务
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//获取当前可用的位置控制器
list = locationManager.getProviders(true);
//检查是否打开了GPS或网络定位
if (list.contains(LocationManager.GPS_PROVIDER)) {
//是否为GPS位置控制器
provider = LocationManager.GPS_PROVIDER;
textView.append("GPS位置控制器" + "\n");
} else if (list.contains(LocationManager.NETWORK_PROVIDER)) {
//是否为网络位置控制器
provider = LocationManager.NETWORK_PROVIDER;
textView.append("网络位置控制器" + "\n");
} else {
Toast.makeText(this, "请检查网络或GPS是否打开", Toast.LENGTH_LONG).show();
return;
}
}
//获得我所在的位置的经纬度
public void getLocation(View view) {
if (Build.VERSION.SDK_INT >= 23) {
//如果用户并没有同意该权限
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//申请权限
}
} else {//低版本手机,直接获取位置信息
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
//获取当前位置,这里只用到了经纬度
String string = " 纬度为:" + location.getLatitude() + ",经度为:"
+ location.getLongitude();
Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
textView.append(string + "\n");
}
}
//位置的监听
public void bandLocationListener(View view) {
//绑定定位事件,监听位置是否改变
//第一个参数为控制器类型第二个参数为监听位置变化的时间间隔(单位:毫秒)
//第三个参数为位置变化的间隔(单位:米)第四个参数为位置监听器
locationManager.requestLocationUpdates(provider, 2000, 2,
locationListener);
if (Build.VERSION.SDK_INT >= 23) {
//如果用户并没有同意该权限
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//申请权限
// requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
} else {
//有权限直接获取地理位置
}
} else {//低版本手机,直接获取位置信息
}
}
LocationListener locationListener = new LocationListener() {
@Override
//状态改变的回调方法
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
@Override
//提供者(网络或GPS)被打开的回调方法
public void onProviderEnabled(String arg0) {
}
@Override
//提供者(网络或GPS)被关闭的回调方法
public void onProviderDisabled(String arg0) {
}
@Override
//经纬度改变的回调方法,基本都是使用这个回调方法
public void onLocationChanged(Location arg0) {
// 更新当前经纬度
// Toast.makeText(MainActivity.this, "" + arg0.toString(), Toast.LENGTH_SHORT).show();
textView.append("经度:" + arg0.getLongitude() + ",纬度:" + arg0.getLatitude() + "\n");
}
};
//关闭时解除监听器
@Override
protected void onDestroy() {
super.onDestroy();
if (locationManager != null) {
if (Build.VERSION.SDK_INT >= 23) {
//如果用户并没有同意该权限
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//申请权限
}
}
locationManager.removeUpdates(locationListener);
}
}
}
上面程序在真机上面跑,是可以看到经纬度的实际变化的。
当然这里只是最简单的位置的请求,可以把请求的位置放到百度地图上。
但是使用百度的地图的SDK,可以很方便的请求到位置并且显示到地图上面,这个另作总结。