LocationManager.requestLocatoinUpdates() 不适用于 android 11 和 12

发布于 2025-01-20 08:16:02 字数 340 浏览 1 评论 0原文

我正在尝试记录 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

客…行舟 2025-01-27 08:16:02
  • 对我来说,从 Google Play 迁移到“Fused Location Provider API”解决了这个问题。

    • Android 建议使用“Fused Location Provider API”而不是“位置管理器”
    • 它们都提供相同的位置信息,但有一件事,我们无法知道提供商是什么。 (来自 GPS 或网络)
  • “Fused Location Provider API”也不适用于虚拟设备。

    • 但它可以在真实设备上运行
    • 我在 LG VELVET (API 31) 上进行了测试
  • 真实设备

    参考

    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.

    • 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

    https://developer.android.com/training/location

    https://github.com/android/location-samples

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文