flutter-permission-handler icon indicating copy to clipboard operation
flutter-permission-handler copied to clipboard

How can i get ACCESS_FINE_LOCATION permission

Open BaroneX opened this issue 2 years ago • 6 comments

💬 Questions and Help

How can i get ACCESS_FINE_LOCATION permission? i want to get wifiname by wifi_info_flutter/network_info_plus plugin,but i can't get fine location permission.

BaroneX avatar Dec 02 '21 06:12 BaroneX

Hi @BaroneX,

Could you provide some more information? How are you requesting permissions (code snippet)? did you add the android.permission.ACCESS_FINE_LOCATION entry to your android/app/src/main/AndroidManifest.xml file? What is the behaviour you expect and which behaviour do you experience?

Answering these questions wil help us help you.

mvanbeusekom avatar Dec 02 '21 07:12 mvanbeusekom

I have add android.permission.ACCESS_FINE_LOCATION,android.permission.ACCESS_COARSE_LOCATION,android.permission.ACCESS_BACKGROUND_LOCATION in my android/app/src/main/AndroidManifest.xml,

PermissionWithService locationPermission = Permission.locationWhenInUse;

    var permissionStatus = await locationPermission.status;
    if (permissionStatus == PermissionStatus.denied) {
      permissionStatus = await locationPermission.request();

      if (permissionStatus == PermissionStatus.denied) {
        permissionStatus = await locationPermission.request();
        return false;
      }
    }

    if (permissionStatus == PermissionStatus.permanentlyDenied) {
      showLocationPersmiison = true;
    }

    bool isLocationServiceOn = await locationPermission.serviceStatus.isEnabled;

Through the code above, I got the location permission, but I couldn’t get the wifiName I want to get the precise location permission, so that I can get WifiName

BaroneX avatar Dec 02 '21 11:12 BaroneX

Hi @BaroneX, I copied your code snippet, and tested what you wanted.

When you request the locationWhenInUse permission, you request both the android.permission.ACCESS_FINE_LOCATION and android.permission.ACCESS_COARSE_LOCATION permissions.

I added a piece of code at the bottom of your code snippet which is able to get the WifiName of the network you're currently on. I did use the network_info_plus 2.1.1 package (so add that one to your pubspec.yaml), since the other package you mentioned isn't going to be updated anymore. Therefor I strongly advise you to use the network_info_plus one as well.

your code snippet (with a few changes) and my code added at the bottom will look like this:

PermissionWithService locationPermission = Permission.locationWhenInUse;

    var permissionStatus = await locationPermission.status;
    if (permissionStatus == PermissionStatus.denied) {
      permissionStatus = await locationPermission.request();

      if (permissionStatus == PermissionStatus.denied) {
        permissionStatus = await locationPermission.request();
      }
    }

    // Removed piece of code here, since the variable mentioned in it was not included

    if (permissionStatus == PermissionStatus.granted) {
      bool isLocationServiceOn = await locationPermission.serviceStatus.isEnabled;
      if (isLocationServiceOn){
        final info = NetworkInfo();
        var wifiName = await info.getWifiName();
        print('The wifi name is: $wifiName');
      } else {
        print('Location Service is not enabled');
      }
    }

This did output my wifi name in the console. If this doesn't work for you, can you try to type in your terminal flutter clean followed by flutter pub get and try to do it again? If it still does not work, can you send me your build.gradle and your AndroidManifest to see if there is something wrong there? Let me know if it worked, or if it didn't work so we can look into it a bit more!

JDDV avatar Dec 09 '21 15:12 JDDV

WX20211210-171916 my app set targetSdkVersion 31, so i needs to have the ACCESS_FINE_LOCATION permission,but the code request the android.permission.ACCESS_FINE_LOCATION or android.permission.ACCESS_COARSE_LOCATION permissions. when i get the ACCESS_COARSE_LOCATION permission, isLocationServiceOn is true but i can't get wifi name

BaroneX avatar Dec 10 '21 09:12 BaroneX

Hi @BaroneX, I tested my code snippet again and it works for me like it should work. On Android 11 (API 30) and lower you can request the location or locationWhenInUse permission and it will both request the ACCES_FINE_LOCATION and ACCESS_COARSE_LOCATION. When the user approves of the permission in the app, the Network name can be retrieved using the network_plus_info package.

On Android 12 however, they changed things up a bit. If you request the location permission, the user will get prompted with the question whether the user wants to use precise or approximate location. choosing approximate location here will result in failing retreiving the network name, since the ACCES_FINE_LOCATION won't be requested. Choosing here the precise location however will still result in retrieving the network name succesfully.

This is how I tested it:

  1. Navigate to folder you want the app to be
  2. Run flutter create <name_of_app> in that folder, this will create the standard flutter incremental counter app
  3. go into that folder (cd <name_of_app>) and run flutter pub add permission_handler and flutter pub add network_info_plus
  4. Copy paste the code snippet above here provided by me in the main.dart file in the _incrementCounter method above the setState().
  5. put in the manifest (src/main/AndroidManifest) the permission above the Application tag the permissions like this:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. If you run the program on a Android 12 SDK 31 device, also add in the first activity tag the line android:exported="true".
  2. Run the app and see how the network name is printed in the console when you click on the floating action button and approve of the permission that will be asked.

If this does not help you out, can you give me more information about your 'setup' ? I would like to know on what Android version you test it, and maybe the steps you took so I can try to reproduce the problem myself. Let me know the result!

JDDV avatar Dec 16 '21 09:12 JDDV

I was facing a similar problem. It turns out, another library "flutter_blue" had android:maxSdkVersion="30" for ACCESS_FINE_LOCATION. during the final apk compilation, AndroidManifest.xml had

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />

so the permission popup had only "approximate" location and once you grant it, SSID and BSSID gives ..

to grab the SSID and BSSID ACCESS_FINE_LOCATION (precise) permission is needed.

kakopappa avatar Jan 26 '22 07:01 kakopappa

choosing approximate location here will result in failing retreiving the network name, since the ACCES_FINE_LOCATION won't be requested. Choosing here the precise location however will still result in retrieving the network name succesfully.

  1. We show the selector to an end-user with call Permission.locationWhenInUse.request().
  2. End-user chooses approximate location.
  3. We test the result -- Permission.locationWhenInUse.status -- and receive PermissionStatus.granted.
  4. We try to get wifi name with network_info_plus plugin, it fails. The question is: how to determine programmatically the end-user has selected approximate location, but no precise location?

Right now a have this problem on iPhone 12...

kostov avatar Aug 17 '23 04:08 kostov

choosing approximate location here will result in failing retreiving the network name, since the ACCES_FINE_LOCATION won't be requested. Choosing here the precise location however will still result in retrieving the network name succesfully.

  1. We show the selector to an end-user with call Permission.locationWhenInUse.request().
  2. End-user chooses approximate location.
  3. We test the result -- Permission.locationWhenInUse.status -- and receive PermissionStatus.granted.
  4. We try to get wifi name with network_info_plus plugin, it fails. The question is: how to determine programmatically the end-user has selected approximate location, but no precise location?

Right now a have this problem on iPhone 12...

@kostov do you have “com.apple.developer.networking.wifi-info" capability in your profile?

kakopappa avatar Aug 17 '23 05:08 kakopappa

@kakopappa Which profile you mean? In case of precise location is chosen, network_info_plus works fine. (https://pub.dev/packages/network_info_plus requires just two keys in Info.plist file. It's certainly done.)

kostov avatar Aug 17 '23 05:08 kostov

Hi @kostov,

This is a different issue, the original poster is discussing an issue on Android not on iOS. Meaning this is not related to the issue you are facing.

Having a quick glance at the network_info_plus README, they mention the following:

iOS 12

To use .getWifiBSSID() and .getWifiName() on iOS >= 12, the Access WiFi information capability in XCode must be enabled. Otherwise, both methods will return null.

This means that for the .getWifiDSSID and .getWifiName to work you'd have to open Xcode and enable the "Access WiFi information" capability. Details on how to handle this can be found in Apple's documentation.

P.S. to open your project in Xcode, take the following steps:

  1. Make sure to build your project first using flutter build ios --no-codesign.
  2. Start Xcode.
  3. Select "Open a project or file".
  4. Navigate into the ios folder inside your project.
  5. Hit the "open" button.

mvanbeusekom avatar Aug 17 '23 06:08 mvanbeusekom

Some additional information to help debug the original issue. It is possible (as mentioned be @kakopappa) that other plugins override configuration made in the AndroidManifest.xml file. The Android build system will merge AndroidManifest.xml files from different plugins and the target application into one final AndroidManifest.xml file which is bundled in the final binary.

If you have listed all permissions in the AndroidManifest.xml file of your application and the "Precise location" permission still doesn't show up, it is very likely the android.permissions.ACCESS_FINE_LOCATION permission is removed during the build process. The Android build system creates a detailed report on how the final AndroidManifest.xml file is created and this report can be used to analyse which plugin causes the mistake. The report can be found on the following location in the root of your project: build/app/outputs/logs/manifest-merger-release-report.txt

I will be closing this issue as this is not related to the permission_handler and out of our hands.

mvanbeusekom avatar Aug 17 '23 06:08 mvanbeusekom

@mvanbeusekom "Access WiFi information" is added (I just add it and forgot). If it would be not, as I said to kakopappa, it would be impossible the network_info_plus can work at all (.getWifiDSSID and .getWifiName).

In case of precise location is chosen, network_info_plus works fine.

And look at https://github.com/Baseflow/flutter-permission-handler/issues/984 :)

kostov avatar Aug 17 '23 07:08 kostov

Aha I think I understand now, what you are asking for is the option to validate if the user allowed precise or approximate permission so you can make further decisions on the return value. Is this correct?

mvanbeusekom avatar Aug 17 '23 07:08 mvanbeusekom

@mvanbeusekom Yes.

kostov avatar Aug 17 '23 08:08 kostov