位置定位LocationManager
简单的获取当前位置对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//提供位置定位服务的位置管理器对象,中枢控制系统
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//位置提供器,也就是实际上来定位的对象,这里选择的是GPS定位
String locationProvider = LocationManager.NETWORK_PROVIDER;
//开始定位,获取包含上次记录的位置数据的位置对象
Location location = locationManager.getLastKnownLocation(locationProvider);
//获取纬度
Double latitude = location.getLatitude();
//获取经度
Double longitude = location.getLongitude();
Log.e("Latitude", String.valueOf(latitude));
Log.e("Longitude", String.valueOf(longitude));
}
高精度定位执行时,会出现getLastKnownLocation获取不到对象,抛出NullException。使用getProvider方法获取手机上的位置提供器,可以看到高精度定位下,有三种位置提供器可供使用
其实从这个方法名可以知道他是获取上次记录下的位置信息,如果是新设备,或者恢复工厂设置的手机,就会报出异常,这里用的模拟器还没记录过位置信息,所以一直报空异常
根据 getLastKnownLocation()返回null的解决这个,发现可以使用requestLocationUpdates方法注册位置更新
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//提供位置定位服务的位置管理器对象,中枢控制系统
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//位置提供器,也就是实际上来定位的对象,这里选择的是GPS定位
String locationProvider = LocationManager.PASSIVE_PROVIDER;
//获取手机中开启的位置提供器
List<String> providers = locationManager.getProviders(true);
//开始定位,获取当前位置对象
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;
}
Location location = locationManager.getLastKnownLocation(locationProvider);
while (location == null) {
//每1s监听一次位置信息,如果位置距离改变超过1m。就执行onLocationChanged方法
//如果第一次打开没有显示位置信息,可以退出程序重新进入,就会显示
locationManager.requestLocationUpdates("gps", 1000,1,new locationListener());
}
//获取纬度
Double latitude = location.getLatitude();
//获取经度
Double longitude = location.getLongitude();
Log.e("Latitude", String.valueOf(latitude));
Log.e("Longitude", String.valueOf(longitude));
}
locationListener.java
位置监听器
可以理解为,先开启监听器监听位置信息,位置更改后记录有了位置数据,然后就可以使用getLastKnownLocation获取上一次的位置数据,所以
public class locationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
Log.e("位置提供器:", "启用");
}
@Override
public void onProviderDisabled(String provider) {
}
}
反向编码经纬度获得可理解地理位置
1、注册为高德地图开放平台的开发者
2、在控制台添加新key,选择Web服务,获取key,才可以使用高德地图的api
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
MainActivity.java
异步处理回调函数返回的相应地址数据,进行UI展示
public class MainActivity extends Activity {
TextView textview;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what == 1){
textview = findViewById(R.id.textview0);
textview.setText(msg.obj.toString());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
httputils.requestHttp("116.310003", "39.991957", new callback2showcontent() {
@Override
public void showJSON(String response) {
//这个方法还是在子线程中,想要处理UI操作,异步线程
Message message = new Message();
message.what = 1;
message.obj = response;
handler.sendMessage(message);
}
});
Toast.makeText(this,"successful", Toast.LENGTH_LONG);
}
}
httputils.java
封装的http请求
public class httputils {
private static URL url;
public static void requestHttp(final String latitude, final String longitude, final callback2showcontent func){
new Thread(new Runnable() {
HttpResponse response;
String returnResutJSON;
@Override
public void run() {
StringBuilder stringbuilder = new StringBuilder("https://restapi.amap.com/v3/geocode/regeo?output=JSON&key=<你的web服务key>&radius=1000&extensions=all");
stringbuilder.append("&location=" + latitude + "," + longitude);
try {
url = new URL(stringbuilder.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpClient httpclient = new DefaultHttpClient();
HttpGet get = new HttpGet(url.toString());
try {
//http相应数据
response = httpclient.execute(get);
} catch (IOException e) {
e.printStackTrace();
}
if(response.getStatusLine().getStatusCode() == 200){
try {
returnResutJSON = EntityUtils.toString(response.getEntity());
func.showJSON(returnResutJSON);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
使用高德地图显示位置
需要使用第三方平台的API接口,来返回具体位置,这里我使用的是高德地图API
1、注册为高德地图开放平台的开发者
2、在控制台创建应用,然后获取API key(keytool -list -v -keystore <.keystore文件的路径>
)可见说明https://lbs.amap.com/faq/top/hot-questions/249
3、在android studio的编辑器的文件配置
https://lbs.amap.com/api/android-sdk/guide/create-project/android-studio-create-project
1、将jar包放入libs目录,然后右键add as library
2、获取密钥,默认密码android
keytool -list -keystore C:\Users\xxxx\.android\debug.keystore -v
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="<你的密钥>"/>
......
</application>
<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
activity_layout.xml
地图容器控件
<com.amap.api.maps.MapView
android:id="@+id/mapview"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
MainActivity.java
private MapView mapview = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//引用地图控件
mapview = (MapView)findViewById(R.id.mapview);
//创建地图
mapview.onCreate(savedInstanceState);
}
展示结果
定位自己所在位置
public class MainActivity extends Activity {
private MapView mapview = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//引用地图控件
mapview = (MapView)findViewById(R.id.mapview);
//创建地图
mapview.onCreate(savedInstanceState);
//地图管理器:显示地图
AMap amap = mapview.getMap();
/*
显示当前自己的位置
*/
//初始化蓝点对象
MyLocationStyle mylocation = new MyLocationStyle();
//定位时间间隔
mylocation.interval(1000);
//将配置好的蓝点对象由管理器进行设置
amap.setMyLocationStyle(mylocation);
//设置默认定位按钮
// amap.getUiSettings().setMyLocationButtonEnabled(true);
//启动定位蓝点
amap.setMyLocationEnabled(true);
}