I have been trying various ways to call on my location data ranging from IP location API's to Flutter plugin's but have not been able to get accurate location data for any of them. Through all I have settled onto Geolocator. But I kept getting
I/flutter ( 5206): null
I/flutter ( 5206): GeolocationStatus.unknown
When calling it in my Init state as follows:
void initState() {
super.initState();
fetchData();
}
fetchData() async {
setState(() {
isLoading = true; //Data is loading
});
GeolocationStatus geolocationStatus =
await Geolocator().checkGeolocationPermissionStatus();
position = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
if (position != null) {
lastPosition = await Geolocator()
.getLastKnownPosition(desiredAccuracy: LocationAccuracy.high);
}
...
if (position != null)
print(position);
else
print(lastPosition);
print(geolocationStatus);
setState(() {
isLoading = false; //Data has loaded
});
}
After some research I decided to settle on permission_handler to try to check permissions. I declared PermissionStatus _status added the following lines to my fetchData() function:
PermissionHandler()
.checkPermissionStatus(PermissionGroup.location);
To which I get No permissions found in manifest for: 3
My manifest has the permissions to the best of my understanding. Manifest file: https://gist.github.com/Purukitto/640d1637c05bdb1b69cc4309947c45d5
From what I understand adding the permissions to the Manifest should add the permission option at least to the app, but after building and installing the app there are "No permissions" for my app(Screenshot attached).
What could be the problem. I have tried to mention all relevant things. Any insight will be really helpful.
This question is linked in the Flutter package permission_handler's ReadMe as an example of setting up the AndroidManifest.xml for asking permissions.
If you're having issues with the device asking the user for permissions, this may be your culprit.
To elaborate on rollcake's answer:
1. If you don't know what permissions you need yet, go to the Android Developer page to see the list and the syntax(es).
2. In your project, open: android/app/src/main/AndroidManifest.xml
3. Insert your permissions as shown in this example here:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.your.package">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:name="io.flutter.app.FlutterApplication"
...<and so on>...
Just a side note: There are different AndroidManifest.xml files in your project (...src/debug, ...src/profile, and ...src/main). Adding the permissions to the main version described above should work but if you're noticing inconsistent behavior make sure you're putting all of your permissions in the same AndroidManifest file.
Check for targetSdkVersion is 23 if so then check for runtime permission you can use checkSelfPermission() and requestPermissions() for android 6 and above
open android project in flutterProject
click manifests file
insert permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
1. Add them in AndroidMenifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="30"></uses-permission>
<uses-permission android:name="com.google.android.gms.permission.AD_ID"></uses-permission>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"></uses-permission>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"></uses-permission>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"></uses-permission>
2. Update permissions handler package :
Package link : https://pub.dev/packages/permission_handler
Related
I have been trying to use an react native ble librairie (react-native-ble-manager). In order to use this the user have to allow location permission (as explain in the documentation android.permission.ACCESS_COARSE_LOCATION and android.permission.ACCESS_FINE_LOCATION if android API >= 29.
I request the autorisation as their example with:
(PermissionsAndroid is from the react-native librairie) :
if (Platform.OS === 'android' && Platform.Version >= 23) {
PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("Permission is OK");
} else {
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("User accept");
} else {
console.log("User refuse");
}
});
}
});
}
On my device the pop-up ask me for the autorisation with only two choices :
Only when the application is running
Refuse
But with their example I have 3 choices the two others and "always authorise"
And for some reason I'm not able to scan peripheral if I don't always approve (I have been able to change to always for my application by going in the settings of it).
Part of my android manifest (android/app/src/main) (as you can see I have background_location)
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<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"/>
I'm sure I'm missing an obvious thing but I can't see what..
In advance thank you :)
For those having the same issue : my phone has android 11 so it can't be directly requested in the pop-up.
You have to indicate to your user how to change the permission
Source : https://developer.android.com/training/location/permissions
During the debugging process of React Native application on a physical device (Android) when I check for the location permission it's always blocked, even though I granted the permission in the settings. I have to note that I haven't been able to request the "ask for permission" window previously, so I couldn't block it in any way. Also, I tried to delete and let the app to be installed again.
Here's the code where I check for location permission (I tried others too). There I use react-native-permissions however, the behaviour is the same if I use PermissionsAndroid from react-native.
import {check, PERMISSIONS, request, RESULTS, openSettings} from "react-native-permissions";
async function checkPermissions() {
let response = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION); // <-- always blocked
let isPermissionsGranted = false;
if (response === RESULTS.GRANTED) {
isPermissionsGranted = true;
} else if (response === RESULTS.DENIED) {
response = request(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION, {
title: "FreeLine requires permission",
message: "FreeLine needs access to your location so you can see your position",
buttonPositive: "Ok",
buttonNegative: "Don't show my position",
});
if (response === RESULTS.GRANTED) {
isPermissionsGranted = true;
} else if (response === RESULTS.DENIED) {
await openSettings();
}
}
return isPermissionsGranted;
}
I haven't found any information that'd explain that. I thought that it's possible that during debugging I can't request for permission.
In the end, I found the root of the problem. The funniest thing it isn't connected with my code in any way. The problem was caused by the manifest, to be more precise by rules I included.
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-feature android:name="android.permission.BLUETOOTH" android:required="true"/>
<!-- Only foreground ble access -->
<uses-feature android:name="android.permission.ACCESS_FINE_LOCATION" android:required="true"/>
As you can see from the snippet above, I used use-feature. Here what the docs say about it:
Google Play uses the elements declared in your app manifest to filter your app from devices that do not meet its hardware and software feature requirements.
In addition to the rules above, I have to add uses-permission, like that:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I'm developing a little sdk that has to be included in projects via .aar file. In this sdk I have a method defined like below:
/**
* Sends an "open lock" request for the bike, with the ble name provided as param. Requires ACCESS_FINE_LOCATION and
* BLUETOOTH permission
*
* #param bikeBleName The BLE name of the searched bike, normally starts with 'BS' prefix
* #param listener Listener for the operation state, returns success or an error string with the detailed error
*/
#RequiresPermission(allOf = [Manifest.permission.BLUETOOTH, Manifest.permission.ACCESS_FINE_LOCATION])
override fun startRent(bikeBleName: String, bikeMode: BikeMode, listener: StartRentListener) {
GlobalScope.launch {
startRentManager.startRent(bikeBleName, bikeMode, listener)
}
}
As you can see, the method is annotated with #RequiresPermission(allOf = [Manifest.permission.BLUETOOTH, Manifest.permission.ACCESS_FINE_LOCATION]), however, if I call the method from my project MainActivity, Android Studio tells me that the method requires a permission check, but it doesn't tell me which permissions are required.
What I would like to obtain is Android Studio telling me "this method requires ACCESS_FINE_LOCATION and BLUETOOTH permissions", something similar to the screenshot below. How can I achieve that? Thanks
The manifest file of the library module is:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.zehus.bikeaccesssdk">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
</manifest>
Problem was that I placed
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.zehus.bikeaccesssdk">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
</manifest>
in the library module. I removed the permissions from the library manifest and now Android Studio is providing the correct hint.
I want to get the Longitude and Latitude of my device when the entry box named entLocation is focused. I am using Xamarin.Essential Geolocation to get the GPS location of my device I followed the documentation and tutorials and still I am unable to get the GPS Location. I have added permission below to my android manifest still nothing. I am getting an display alert on "Error3", Error3 is the exception when Unable to get location.
The error is "Java.Lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Activity.requestPermissions(java.lang.String[],int)' on a null object reference"
My questions:
1. What is my error in my code?
2. Can I get my gps location offline? If yes, how can I achieve that?
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
uses-feature android:name="android.hardware.location" android:required="false"
uses-feature android:name="android.hardware.location.gps" android:required="false"
uses-feature android:name="android.hardware.location.network" android:required="false"
private async void entLocation_FocusedAsync(object sender, FocusEventArgs e)
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
if (location != null)
{
entLocation.Text = location.Longitude.ToString() + "," + location.Latitude.ToString();
}
}
catch (FeatureNotSupportedException fnsEx)
{
await DisplayAlert("Error1", fnsEx.ToString(), "ok");
}
catch (PermissionException pEx)
{
await DisplayAlert("Error2", pEx.ToString(), "ok");
}
catch (Exception ex)
{
await DisplayAlert("Error3", ex.ToString(), "ok");
}
}
I am also working on my first Xamarin project that requires location permissions. A couple of things you should try that may help you get GPS location.
My suggestions
1) You need to grant additional permissions in AndroidManifest file. These are
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
2) Since Android 6.0 or above, you need to have runtime permissions. To acchieve that, you need to override OnStart() method in your MainActivity.cs. I referenced to Location permission for Android above 6.0 with Xamarin.Forms.Maps. Here is what I did
protected override void OnStart()
{
base.OnStart();
if(CheckSelfPermission(Manifest.Permission.AccessCoarseLocation) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation }, 0);
}
}
Important: My solution here is just temporarily handle granting permissions. Visual Studio would show an exception when you build and run the project first time. After you choose "allow" from "Allow access location?" prompt on the device, you would not get the exception when run the project again. I have not handled this issue yet.
My limits
As I said, the problem isn't completely solved. My answer is to help you temporarily solve location permissions issue and move on. And I don't know how to get location offline.
I am working on an app having feature of social login.
So I created a android-library project whose role is provide social login with g+,FB etc.My app is using this android-library project for social login.
But now I am facing issue describe below.
I am successfully logged in using g+.
But When I am trying to get signed in user email
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
I am getting below exception stack trace
W/System.err﹕ java.lang.SecurityException: Missing android.permission.GET_ACCOUNTS
W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1474)
W/System.err﹕ at android.os.Parcel.readException(Parcel.java:1427)
W/System.err﹕ at com.google.android.gms.plus.internal.zzd$zza$zza.getAccountName(Unknown Source)
I have added uses-permission tag in my android-library project.
Below is the android-libray manifest file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="login.social">
<application >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
</application>
</manifest>
Can anyone guide me what's wrong?
If this is a problem for Android version 6 (or higher) and you compile with Android SDK 23 and you already have double checked that GET_ACCOUNTS permission is in the Manifest then the problem might be new rules for Android's Runtime Permission.
From Android version 6 users must be asked for some permissions when the application is using these permissions for the first time (even if it is already in Manifest).
You can solve this problem like this:
Put this part of code
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.GET_ACCOUNTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.GET_ACCOUNTS},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
}
instead of
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
When user allow or disallow permission, method onRequestPermissionsResult will be called and then you can ask for email.
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Utils.showToast("Hello " + email, mContext);
} else {
// Permission Denied
Utils.showToast("GET_ACCOUNTS Denied", mContext);
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
If you want to know more about new rules for permissions I recommend you to read this article http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en
I think your manifest is malformed, try this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="login.social">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
</application>
</manifest>
Have a look to the android documentation about manifest for more info.
The manifest entries are wrong, you need to place the permissions and uses-permission outside the application tag