LocationManager.requestLocatoinUpdates() 不适用于 android 11 和 12
我正在尝试记录 LocationManager 每 5 秒提供的所有信息。因为我想要最新的信息,所以minTime和minDistance设置为0。 此代码在 android 9 和 10(API 28、29)中运行良好,但在 android 11 和 12(API 30、31)中停止运行。
是的,我同时授予了 ACCESS_COARSE/FINE_LOCATION 和 ACCESS_BACKGROUND_LOCATION 权限, 并且没有同时要求他们。 我不考虑使用 Fused Location Provider API。 (我只想要位置经理的信息)
我看到有些人遇到同样的情况,但我找不到任何解决方案。
我真的需要帮助。
I am trying to log all the information that LocationManager provides every 5 seconds. Because I want the latest information, minTime and minDistance are set 0.
This code worked well in android 9 and 10 (API 28, 29), however it stopped working on android 11 and 12 (API 30, 31).
Yes, I gave both ACCESS_COARSE/FINE_LOCATION and ACCESS_BACKGROUND_LOCATION permissions,
and didn't request them at the same time.
And I'm not considering on using Fused Location Provider API. (I only want information from Location Manager)
I see some people experiencing same situation but I can't find any solution.
I really need help. ????
- code (part where I use 'requestLocationUpdates')
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// get GPS information
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// get Network information
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
// Log.i(TAG, "GPS enabled: " + isGPSEnabled + " network enabled: " + isNetworkEnabled);
if (!isGPSEnabled && !isNetworkEnabled) {
lat = 0;
lon = 0;
} else {
this.isGetLocation = true;
// GPS
if (isGPSEnabled) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0, this);
Log.i(TAG, "Lat: " + lat + " Lon: " + lon);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// gpsTime = location.getTime();
if(location != null && location.getTime() > Calendar.getInstance().getTimeInMillis() - 5000) {
gpsUse = true;
}
if (location != null) {
lat = location.getLatitude();
lon = location.getLongitude();
}
}
}
if (isNetworkEnabled) {
Log.i(TAG, "get data from Network");
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
0,
0, this);
Log.i(TAG, "Lat: " + lat + " Lon: " + lon);
if (locationManager != null) {
location4 = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//networkTime = location4.getTime();
if(location4 != null && location4.getTime() > Calendar.getInstance().getTimeInMillis() - 5000) {
networkUse = true;
}
if (location4 != null) {
lat = location4.getLatitude();
lon = location4.getLongitude();
//Log.e("getCid", "" + TeleLocation.getCid());
//cellID = TeleLocation.getCid();
//lac = TeleLocation.getLac();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
- Mainactivity (permissions)
@Override
protected void onStart() {
super.onStart();
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(POWER_SERVICE);
boolean isWhiteListing = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
}
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, PERMISSION_REQUEST_CODE);
}
}
- manifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
- gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.HanyangHCI.crc_test"
minSdkVersion 15
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
customDebugtype {
debuggable true
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'net.sf.opencsv:opencsv:2.0'
implementation 'com.ssomai:android.scalablelayout:2.1.6'
//implementation 'com.opencsv:opencsv:3.9'
}
- MainActivity(onRequestPermissionsResult)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
// Log.i(TAG, " Permissions: " + permissions);
switch (requestCode){
case PERMISSION_REQUEST_CODE:{
Log.i(TAG, "onRequestPermissionsResult: 권한 지속 거부 반응");
IsFinishing = true;
// 위치 권한 거부시
if (grantResults.length!=4 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED){
IsFirstMessageOn = true;
Log.i(TAG, "onRequestPermissionsResult: 위치 권한 거부시");
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("데이터 수집을 위해서는 GPS 정보가 필요합니다. [설정 > 애플리케이션 > CRC_Test > 권한 > 위치]에서 허용으로 설정을 변경해주세요.");
builder.setTitle("위치 정보 권한 요청");
builder.setCancelable(false);
builder.setPositiveButton("확인", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ finishAndRemoveTask(); Log.i(TAG, "onClick: 화면종료!!!");}
else { finish();}
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
//저장공간 거부시
if (grantResults.length!=4 || grantResults[2] != PackageManager.PERMISSION_GRANTED || grantResults[3] != PackageManager.PERMISSION_GRANTED){
Log.i(TAG, "onRequestPermissionsResult: 저장공간 거부시");
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("데이터 저장을 위해서는 저장공간 접근이 필요합니다. [설정 > 애플리케이션 > CRC_Test > 권한 > 저장공간]에서 허용으로 설정을 변경해주세요.");
builder.setTitle("저장공간 권한 요청");
builder.setCancelable(false);
builder.setPositiveButton("확인", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ finishAndRemoveTask(); Log.i(TAG, "onClick: 화면종료!!!");}
else { finish();}
}
});
AlertDialog dialog = builder.create();
if(grantResults.length!=4 || grantResults[2] != PackageManager.PERMISSION_GRANTED || grantResults[3] != PackageManager.PERMISSION_GRANTED){
Log.i(TAG, "onRequestPermissionsResult: " + IsFirstMessageOn);
dialog.show();
}
}
return;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对我来说,从 Google Play 迁移到“Fused Location Provider API”解决了这个问题。
“Fused Location Provider API”也不适用于虚拟设备。
参考
https://developer.android.com/training/location
https://github.com/android/location-samples
For me, migrating to 'Fused Location Provider API' from Google Play solved the problem.
'Fused Location Provider API' also doesn't work on virtual devices.
References
https://developer.android.com/training/location
https://github.com/android/location-samples