合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
Android SDK为开发者提供了一套获取设备位置信息的解决方案,主要面向有一定 Android 编程经验和了解面向对象编程的开发者。
融合定位返回的位置信息默认使用WGS-84坐标系。
- <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_BACKGROUND_LOCATION" />
- // Android SDK<=28 所需权限动态申请
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
- Log.i(TAG, "android sdk <= 28 Q");
- if (ActivityCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
- && ActivityCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- String[] strings =
- {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
- ActivityCompat.requestPermissions(this, strings, 1);
- }
- } else {
- // Android SDK>28 所需权限动态申请,需添加“android.permission.ACCESS_BACKGROUND_LOCATION”权限
- if (ActivityCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
- && ActivityCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
- && ActivityCompat.checkSelfPermission(this,
- "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
- String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
- android.Manifest.permission.ACCESS_COARSE_LOCATION,
- "android.permission.ACCESS_BACKGROUND_LOCATION"};
- ActivityCompat.requestPermissions(this, strings, 2);
- }
- }
- // Android SDK<=28 所需权限动态申请
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
- Log.i(TAG, "android sdk <= 28 Q")
- if (ActivityCompat.checkSelfPermission(
- this,
- Manifest.permission.ACCESS_FINE_LOCATION
- ) != PackageManager.PERMISSION_GRANTED
- && ActivityCompat.checkSelfPermission(
- this,
- Manifest.permission.ACCESS_COARSE_LOCATION
- ) != PackageManager.PERMISSION_GRANTED
- ) {
- val strings = arrayOf(
- Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.ACCESS_COARSE_LOCATION
- )
- ActivityCompat.requestPermissions(this, strings, 1)
- }
- } else {
- // Android SDK > 28 所需权限动态申请,需添加“android.permission.ACCESS_BACKGROUND_LOCATION”权限。
- if (ActivityCompat.checkSelfPermission(
- this,
- Manifest.permission.ACCESS_FINE_LOCATION
- ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
- this,
- Manifest.permission.ACCESS_COARSE_LOCATION
- ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
- this,
- "android.permission.ACCESS_BACKGROUND_LOCATION"
- ) != PackageManager.PERMISSION_GRANTED
- ) {
- val strings = arrayOf(
- Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.ACCESS_COARSE_LOCATION,
- "android.permission.ACCESS_BACKGROUND_LOCATION"
- )
- ActivityCompat.requestPermissions(this, strings, 2)
- }
- }
定位设置状态会直接影响定位服务的定位结果,例如位置开关处于关闭状态时,将无法获取到位置信息。因此,建议您在持续获取位置信息之前,检查设备定位开关状态。
- SettingsClient settingsClient = LocationServices.getSettingsClient(this);
- var settingsClient = LocationServices.getSettingsClient(this)
- LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
- LocationRequest mLocationRequest = new LocationRequest();
- builder.addLocationRequest(mLocationRequest);
- LocationSettingsRequest locationSettingsRequest = builder.build();
- // 检查设备定位设置
- settingsClient.checkLocationSettings(locationSettingsRequest)
- // 检查设备定位设置接口调用成功监听
- .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
- @Override
- public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
- LocationSettingsStates locationSettingsStates =
- locationSettingsResponse.getLocationSettingsStates();
- StringBuilder stringBuilder = new StringBuilder();
- // 定位开关是否打开
- stringBuilder.append(",\nisLocationUsable=")
- .append(locationSettingsStates.isLocationUsable());
- // HMS Core是否可用
- stringBuilder.append(",\nisHMSLocationUsable=")
- .append(locationSettingsStates.isHMSLocationUsable());
- Log.i(TAG, "checkLocationSetting onComplete:" + stringBuilder.toString());
- }
- })
- // 检查设备定位设置接口失败监听回调
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.i(TAG, "checkLocationSetting onFailure:" + e.getMessage());
- }
- });
- val builder = LocationSettingsRequest.Builder()
- var mLocationRequest = LocationRequest()
-
- builder.addLocationRequest(mLocationRequest)
- val locationSettingsRequest = builder.build()
- // 检查设备定位设置
- settingsClient.checkLocationSettings(locationSettingsRequest)
- // 检查设备定位设置接口调用成功监听
- .addOnSuccessListener(OnSuccessListener { locationSettingsResponse ->
- val locationSettingsStates = locationSettingsResponse.locationSettingsStates
- val stringBuilder = StringBuilder()
- // 定位开关是否打开
- stringBuilder.append("isLocationUsable=")
- .append(locationSettingsStates.isLocationUsable)
- // HMS Core是否可用
- stringBuilder.append(",\nisHMSLocationUsable=")
- .append(locationSettingsStates.isHMSLocationUsable)
- Log.i(TAG, "checkLocationSetting onComplete:$stringBuilder")
- })
- // 检查设备定位设置接口失败监听回调
- .addOnFailureListener(OnFailureListener { e ->
- Log.i(TAG, "checkLocationSetting onFailure:" + e.message)
- })
在非华为手机上仅返回定位开关状态,开发者可以依据返回状态,提示用户打开开关;在华为设备上,可以拉起位置开关弹窗,方便用户快速打开定位开关。
请在主线程中声明FusedLocationProviderClient类对象,传入Context或Activity类型参数。
- // 声明fusedLocationProviderClient对象
- private FusedLocationProviderClient fusedLocationProviderClient;
- // 实例化fusedLocationProviderClient对象
- fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
- // 定位交互接入对象
- private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
- // 实例化fusedLocationProviderClient对象
- fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
Location SDK提供了单次定位、持续定位、后台定位能力,开发者可以根据自己的应用场景选择合适的定位模式。不同定位模式设置方式如下:
- LocationRequest mLocationRequest = new LocationRequest();
- // 设置定位类型
- mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
- // 设置回调次数为1
- mLocationRequest.setNumUpdates(1);
- val mLocationRequest = LocationRequest()
- // 设置定位类型
- mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
- // 设置回调次数为1
- mLocationRequest.numUpdates = 1
- LocationRequest mLocationRequest = new LocationRequest();
- // 设置位置更新的间隔(单位:毫秒)
- mLocationRequest.setInterval(10000);
- // 设置定位类型
- mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
- val mLocationRequest = LocationRequest()
- // 设置位置更新的间隔(单位:毫秒)
- mLocationRequest.interval = 10000
- // 设置定位类型
- mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
方法名 | 参数说明 | 返回值说明 | 方法效果 | 默认值 |
|---|---|---|---|---|
setPriority(int priority) | 如果请求GNSS位置,则值为100;如请求网络位置,则值为102或104;如不需要主动请求位置,仅需被动接收位置,则值为105。如果请求高精度位置信息,则值为200。 | LocationRequest对象 | 设置定位类型。 | PRIORITY_BALANCED_POWER_ACCURACY |
setInterval(long millis) | 假如值为50000,则位置请求每隔50秒回调一次结果。 | LocationRequest对象 | 设置请求位置回调的时间间隔。 | 3600000 |
setNumUpdates(int numUpdates) | 假如值为3时,则只回调3次结果给客户端。 | LocationRequest对象 | 设置请求位置的回调次数。 | Integer.MAX_VALUE |
setFastestInterval(long millis) | 如果有其他应用发起位置请求,满足fastestInterval周期后,同样会上报位置。 | LocationRequest对象 | 设置请求位置回调的最快时间间隔。 | 600000 |
isFastestIntervalExplicitlySet() | null | boolean | 是否使用最快时间间隔。 | 如果使用最快时间间隔,则返回true,否则返回false。 |
setExpirationTime(long millis) | 假如200秒后位置回调需要停止,则该参数值应为SystemClock.elapsedRealtime() + 200000。 | LocationRequest对象 | 设置请求到期时间。 | Long.MAX_VALUE |
setExpirationDuration(long millis) | 该参数与expirationTime的区别为,该参数不需要考虑开机启动时间。假如200秒后位置回调需要停止,则该参数值应为200000。 | LocationRequest对象 | 设置请求到期时间段。 | Long.MAX_VALUE |
setSmallestDisplacement(float smallestDisplacement) | 两次回调位置之间的距离满足该参数的值,则进行位置回调。 | LocationRequest对象 | 设置位置更新的最小位移。 | 0 |
setMaxWaitTime(long millis) | 单位:毫秒。 生效时,位置更新会以maxWaitTime的时间为更新周期,在满足位置更新时间后,会将周期内的位置一次性返回给应用。 | LocationRequest对象 | 设置设置位置更新的最长等待时间。 | 0 |
setNeedAddress(boolean needAddress) | needAddress为布尔型,true需要返回地址信息,false不需要。 | LocationRequest对象 | 设置是否需要返回地址信息。 | false |
setLanguage(String language) | 格式为:两个字母(例如:en表示英文)。使用ISO 639-1国际标准,默认为空。当前仅支持en和zh。 | LocationRequest对象 | 设置语言。 | 默认为空。 |
setCountryCode(String countryCode) | 格式为:两个字母,使用ISO 3166-1国际标准,默认为空。当前仅支持EN和CN。 | LocationRequest对象 | 设置国家。 | 默认为空。 |
- <service
- android:name="com.huawei.location.service.BackGroundService"
- android:foregroundServiceType="location" />
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- Notification.Builder builder;
- Notification mNotification;
- int notificationId = 1;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- NotificationManager notificationManager =
- (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
- String channelId = context.getPackageName();
- NotificationChannel notificationChannel =
- new NotificationChannel(channelId, "LOCATION", NotificationManager.IMPORTANCE_LOW);
- notificationManager.createNotificationChannel(notificationChannel);
- builder = new Notification.Builder(context, channelId);
- } else {
- builder = new Notification.Builder(context);
- }
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- mNotification = builder.build();
- } else {
- mNotification = builder.getNotification();
- }
- fusedLocationProviderClient.enableBackgroundLocation(notificationId,mNotification);
- val builder: Notification.Builder
- val mNotification: Notification
- var notificationId = 1
- builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val notificationManager =
- context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
- val channelId = context.packageName
- val notificationChannel =
- NotificationChannel(channelId, "LOCATION", NotificationManager.IMPORTANCE_LOW)
- notificationManager.createNotificationChannel(notificationChannel)
- Notification.Builder(context, channelId)
- } else {
- Notification.Builder(context)
- }
- mNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- builder.build()
- } else {
- builder.notification
- }
- fusedLocationProviderClient.enableBackgroundLocation(notificationId,mNotification)
- LocationCallback mLocationCallback;
- mLocationCallback = new LocationCallback() {
- @Override
- public void onLocationResult(LocationResult locationResult) {
- if (locationResult != null) {
- // TODO: 处理位置回调结果
- }
- }
- };
- val mLocationCallback: LocationCallback
- mLocationCallback = object : LocationCallback() {
- override fun onLocationResult(locationResult: LocationResult) {
- if (locationResult != null) {
- // TODO: 处理位置回调结果
- }
- }
- }
- fusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- // TODO: 接口调用成功的处理
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- // TODO: 接口调用失败的处理
- }
- });
- fusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
- .addOnSuccessListener {
- // TODO: 接口调用成功的处理
- }
- .addOnFailureListener {
- // TODO: 接口调用失败的处理
- }
如果接口调用成功,获取位置信息失败,请参见在手机或华为平板上集成Location SDK,接口调用成功,为什么无法获取到位置信息?。
- fusedLocationProviderClient.disableBackgroundLocation();
- fusedLocationProviderClient.disableBackgroundLocation()
- // 注意:停止位置更新时,mLocationCallback必须与requestLocationUpdates方法中的LocationCallback参数为同一对象。
- fusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
- // 停止位置更新成功监听回调
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- // TODO: 停止位置更新成功的处理
- }
- })
- // 停止位置更新失败监听回调
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- // TODO:停止位置更新失败的处理
- }
- });
- // 注意:停止位置更新时,mLocationCallback必须与requestLocationUpdates方法中的LocationCallback参数为同一对象。
- fusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
- // 停止位置更新成功监听回调
- .addOnSuccessListener {
- // TODO:停止位置更新成功的处理
- }
- // 停止位置更新失败监听回调
- .addOnFailureListener {
- // TODO:停止位置更新失败的处理
- }
- // 获取最后的已知位置
- Task<Location> task = fusedLocationProviderClient.getLastLocation()
- // 获取最后的已知位置成功监听回调
- .addOnSuccessListener(new OnSuccessListener<Location>() {
- @Override
- public void onSuccess(Location location) {
- if (location == null) {
- return;
- }
- // TODO:成功时Location对象处理逻辑
- }
- })
- // 获取最后的已知位置失败监听回调
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- // TODO:接口调用失败处理
- }
- });
- val lastLocation =
- fusedLocationProviderClient.lastLocation
- lastLocation.addOnSuccessListener(OnSuccessListener { location ->
- if (location == null) {
- return@OnSuccessListener
- }
- // TODO:成功时Location对象处理逻辑
- return@OnSuccessListener
- })
- // 获取最后的已知位置失败监听回调
- .addOnFailureListener {
- // TODO:接口调用失败处理
- }
getLastLocation()方法是从系统缓存中获取位置信息的。如果获取的位置信息为null,则可能是系统缓存已经被清除;此时先调用requestLocationUpdates()方法获取位置信息以刷新缓存,再调用getLastLocation()方法即可以获取到位置信息。
具体操作:打开(如果没有发现“开发人员选项”,请执行如下操作:,连续点击“版本号”7次,“开发人员选项”会出现在“系统与更新”页面,再重复上述操作),代码开发步骤如下:
- <uses-permission
- android:name="android.permission.ACCESS_MOCK_LOCATION"
- tools:ignore="MockLocation,ProtectedPermissions" />
- // 设置mock模式,参数传入ture:模拟模式;false:正常状态
- boolean mockFlag = true;
- fusedLocationProviderClient.setMockMode(mockFlag).addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "setMockMode onSuccess");
- }
- }).addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.i(TAG, "setMockMode onFailure:" + e.getMessage());
- }
- });
- // 设置mock模式,参数传入ture:模拟模式;false:正常状态
- val mockFlag = true
- fusedLocationProviderClient.setMockMode(mockFlag)
- .addOnSuccessListener { Log.i(TAG, "setMockMode onSuccess") }
- .addOnFailureListener { e ->
- Log.i(TAG,"setMockMode onFailure:" + e.message)
- }
- // 设置模拟位置信息
- final Location mockLocation = new Location(LocationManager.GPS_PROVIDER);
- mockLocation.setLongitude(118.76);
- mockLocation.setLatitude(31.98);
- fusedLocationProviderClient.setMockLocation(mockLocation)
- // 设置模拟位置信息成功监听回调
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "setMockLocation onSuccess");
- }
- })
- // 设置模拟位置信息失败监听回调
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(Exception e) {
- Log.i(TAG, "setMockLocation onFailure:" + e.getMessage());
- }
- });
- // 设置模拟位置信息
- val mockLocation = Location(LocationManager.GPS_PROVIDER)
- mockLocation.longitude = 118.76
- mockLocation.latitude = 31.98
- fusedLocationProviderClient.setMockLocation(mockLocation)
- // 设置模拟位置信息成功监听回调
- .addOnSuccessListener {
- Log.i(
- TAG,
- "setMockLocation onSuccess"
- )
- }
- // 设置模拟位置信息失败监听回调
- .addOnFailureListener { e ->
- Log.i(
- TAG,
- "setMockLocation onFailure:" + e.message
- )
- }