Android定位
创建一个新项目
1、在AndroidManifest中添加以下权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="cn.yang.scanwifilist">
<!--使用网络-->
<uses-permission android:name="android.permission.INTERNET" />
<!--网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--位置信息-->
<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" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ScanWifiList"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2、activity_main.xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/loctian_btn_gps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="GPS" />
<Button
android:id="@+id/loctian_btn_network"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="网络" />
<Button
android:id="@+id/loctian_btn_passive"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="其它应用" />
<TextView
android:id="@+id/loctian_btn_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="缓存地址" />
<TextView
android:id="@+id/loctian_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="实时地址" />
</LinearLayout>
</ScrollView>
3、MainActivity.java中代码
package cn.yang.androidtest;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Button btnGps;
private Button btnNetwotk;
private Button btnPassive;
private TextView tv;
private TextView tv1;
private LocationManager locationManager;
//private String[] location={LocationManager.GPS_PROVIDER,LocationManager.NETWORK_PROVIDER,LocationManager.PASSIVE_PROVIDER};
private final LocationListener listener = new LocationListener() {
@Override
public void onLocationChanged(@NonNull Location l) {
StringBuilder txt = new StringBuilder();
txt.append("LocationListener:" + l.toString() + "\n");
txt.append("最新的定位\n");
txt.append("经度:" + String.valueOf(l.getLongitude()) + "\n");
txt.append("纬度:" + String.valueOf(l.getLatitude()) + "\n");
txt.append("高度:" + String.valueOf(l.getAltitude()) + "\n");
txt.append("速度:" + String.valueOf(l.getSpeed()) + "\n");
txt.append("地址:" + getAddress(l.getLongitude(), l.getLatitude()));
tv1.setText(txt);
}
@Override
public void onLocationChanged(@NonNull List<Location> locations) {
LocationListener.super.onLocationChanged(locations);
Log.i("onLocationChanged", locations.toString());
}
@Override
public void onFlushComplete(int requestCode) {
LocationListener.super.onFlushComplete(requestCode);
Log.i("onFlushComplete", String.valueOf(requestCode));
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
LocationListener.super.onStatusChanged(provider, status, extras);
Log.i("onStatusChanged", provider + "--" + String.valueOf(status) + "---" + extras.toString());
}
@Override
public void onProviderEnabled(@NonNull String provider) {
LocationListener.super.onProviderEnabled(provider);
Log.i("onProviderEnabled", provider);
}
@Override
public void onProviderDisabled(@NonNull String provider) {
LocationListener.super.onProviderDisabled(provider);
Log.i("onProviderDisabled", provider);
}
};
;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gps);
btnGps = (Button) findViewById(R.id.loctian_btn_gps);
btnNetwotk = (Button) findViewById(R.id.loctian_btn_network);
btnPassive = (Button) findViewById(R.id.loctian_btn_passive);
tv = (TextView) findViewById(R.id.loctian_btn_tv);
tv1 = (TextView) findViewById(R.id.loctian_tv);
//GPS定位
//String gps = LocationManager.GPS_PROVIDER;
//网络定位
//String network = LocationManager.NETWORK_PROVIDER;
//使用其它应用的定位
//String passive = LocationManager.PASSIVE_PROVIDER;
//定位
btnGps.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
InitLocation(LocationManager.GPS_PROVIDER);
}
});
btnNetwotk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
InitLocation(LocationManager.NETWORK_PROVIDER);
}
});
btnPassive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
InitLocation(LocationManager.PASSIVE_PROVIDER);
}
});
}
//获取定位信息
public void InitLocation(String provider) {
//初始化位置服务
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(listener);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
//动态权限检查
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 101);
Toast.makeText(MainActivity.this, "权限已获取", Toast.LENGTH_LONG).show();
}
// 取最后已知位置,即缓存中的位置
Location l = locationManager.getLastKnownLocation(provider);
//开启监听之前一定要先移除监听,不管是否添加监听,否则后续实时更新会受干扰
locationManager.removeUpdates(listener);
if (l != null) {
StringBuilder txt = new StringBuilder();
txt.append("缓存中的定位\n");
txt.append("定位方式:" + provider + "\n");
txt.append("经度:" + String.valueOf(l.getLongitude()) + "\n");
txt.append("纬度:" + String.valueOf(l.getLatitude()) + "\n");
txt.append("高度:" + String.valueOf(l.getAltitude()) + "\n");
txt.append("速度:" + String.valueOf(l.getSpeed()) + "\n");
txt.append("地址:" + getAddress(l.getLongitude(), l.getLatitude()));
tv.setText(txt);
}
// 产生位置改变事件的条件设定为距离改变10米,时间间隔为2秒,设定监听位置变化
// 开始监听
locationManager.requestLocationUpdates(provider, 2000, 10, listener);
Toast.makeText(MainActivity.this, "定位方式:" + provider, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "开启权限", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainActivity.this.startActivity(intent);
}
}
//根据经纬度获取地址
public String getAddress(double lnt, double lat) {
Geocoder geocoder = new Geocoder(MainActivity.this);
boolean falg = geocoder.isPresent();
StringBuilder stringBuilder = new StringBuilder();
try {
//根据经纬度获取地理位置信息---这里会获取最近的几组地址信息,具体几组由最后一个参数决定
List<Address> addresses = geocoder.getFromLocation(lat, lnt, 1);
if (addresses.size() > 0) {
Address address = addresses.get(0);
stringBuilder.append("国家:" + address.getCountryName() + "\n");//国家
stringBuilder.append("省份" + address.getAdminArea() + "\n");//省份
stringBuilder.append("城市:" + address.getLocality() + "\n");//市
stringBuilder.append("周边地区:" + address.getFeatureName() + "\n");//周边地区
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
//每一组地址里面还会有许多地址。这里我取的前2个地址。xxx街道-xxx位置
if (i == 0) {
stringBuilder.append(address.getAddressLine(i));
}
if (i == 1) {
stringBuilder.append(address.getAddressLine(i));
break;
}
}
}
} catch (Exception e) {
Log.d("获取经纬度地址异常", "");
return "详细地址获取失败";
}
return stringBuilder.toString();
}
}