'LocationManager.requestLocatoinUpdates() is not working on android 11 and 12
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;
}
}
}
Solution 1:[1]
For me, migrating to 'Fused Location Provider API' from Google Play solved the problem.
- Android recommends using 'Fused Location Provider API' rather than 'Location Manager'
- They both provides same location information, but one thing, we are not able to know what the provider is. (from GPS or Network)
'Fused Location Provider API' also doesn't work on virtual devices.
- but it works on real devices
- I tested on LG VELVET (API 31)
References
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Yeji Woo |
