I have a flutter app, that uses the location library, found here
I import with
import 'package:location/location.dart';
and later call with
location.onLocationChanged().listen((Map<String,double> currentLocation) {
print("LocationListener " + currentLocation.toString());
}
This works fine when run on an avd phone emulator, and also on a real phone. I get periodic updates with new gps locations coming through.
However, I want to get this working on an Android Wear 2 device/watch.
If I try it in either an emulator or actual android watch (Huawei watch 2), the stream never seems to trigger. I'm also trying to update the location via the emulator, which again works with a phone, but doesn't work with a watch.
The adv device I'm trying is Android Wear Round API 26.
The actual device is
Wear OS By Google 1.6, Google Play Services 14.3.67, android o.s 8.0
Location is enabled on the phone. It's possible the avd watch location is expecting it from a phone, but the actual watch device isn't, as it can work standalone, and things like Google Maps work fine with it GPS wise.
Does Android Wear 2 treat GPS/listeners different in anyway that I should be aware of, and any way to get that working ?
I've got this working finally as I hadn't realised permissions requirements had changed, as per here.
So I've added one of these...
<!--<uses-permission android:name="android.hardware.location.gps" />-->
<uses-permission android:name="android.hardware.location" />
location permission seems to work, but you can add gps specifically if that is required.
Related
I have implemented Companion device pairing and it works great for most devices without requiring any location permission or location services enabled. However, we found for example Xiaomi Redmi Note 10 Pro (Android 11) where the BLE scan timeouts when Location services are disabled.
Do I still need to implement requiring Location services enabled before the scan or this is undesirable behavior? I hoped it is not needed anymore with this system-level BLE scan.
If so, is there a way how to distinguish which device needs it? I don't want to force all people when it is not needed (for example my Pixel 5)
In my opinion the Companion Device feature was implemented and designed in a rush. You could expect bugs like the "Location services" must be turned on and the Companion Device pairing dialog doesn't warn when it is not enabled. Until Xiaomi or Google fixes this bug, you will need to have workarounds in your app, for example telling the user to first enable Location services if you think that will be needed.
I am also facing issues with applying a scan filter. It is completely a nightmare.
I have started with this:
val filter = ScanFilter.Builder().apply {
setManufacturerData(SOME_INDEX, byteArrayOf(1))
setDeviceName(SOME_NAME)
setServiceUuid(ParcelUuid.fromString(SOME_UUID))
}.build()
Finally, I have only this:
ScanFilter.Builder().apply {
setManufacturerData(SOME_INDEX, byteArrayOf(1))
}.build()
Because setServiceUuid() is not working for example on all tested Huawei phones and Sony Xperia X.
And setDeviceName() is not working for example on Samsung S10e. Finally I have found solution for name filtering by applying directly:
BluetoothLeDeviceFilter.Builder()
.setNamePattern(Pattern.compile(SOME_NAME))
.setScanFilter(filter)
I use the Code A to set the enabled status of WiFi, it works well when I use Android Emulator with both API 26 and API 23 in Android Studio 3.1.3 , and none of prompt window display!
But I get a prompt window "An App is requesting permission to use WLAN. Allow?" in real mobile phone with Android 5.1 when I run the code A.
How can I make the prompt window not to display in real mobile phone? Thanks!
BTW,the real mobile phone is Samsung SM-J5008 with Android 5.1
Prompt Window
I have set the permissions
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Code A
fun setWiFi(aWiFiDef: WiFiDef): Unit{
val wifiManager =mContext.applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
wifiManager.isWifiEnabled=aWiFiDef.status
}
Android 5.1 does not have such runtime permission, so I assume, that this is a wrongly implemented permission request rational, which is shown even though the app does not need to. You wrote, that you tested with API level 26 and 23, which is Android 6.0 and higher, so these versions already have runtime permissions. Maybe you haven't seen this issue, because you haven't tested on devices below Android 6.0...
Please check if you somewhere call AppCompat.shouldShowRequestPermissionRationale() and if it is surrounded by SDK level checks or at least with a checkSelfPermission as described here: https://developer.android.com/training/permissions/requesting. Test your code in an emulator with Android 5.1 and Android 6.0. Then you should be able to reproduce that issue also on real phones.
You also need to add this to your manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
According to the website below: *App on Marshmallow needs ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission and Location services should be enabled to get wifi scan results. Google probably sees scanning for wifi as a security concern, and wanted to add the location permissions as well.
I would recommend following the blog post below if you are having trouble after adding the ACCESS_COARSE_LOCATION permission to your manifest.
https://www.intentfilter.com/2016/08/programatically-connecting-to-wifi.html
EDIT
For the people down voting, please include a comment explaining why. Was my answer flat out wrong? Did I overlook somthing?
Some more information on google's geolocation service:
Google maintains a huge database for its geolocation service ("Access coarse location" permission). It consists of:
Wifi access point mappings: Wifi MAC address resolve to a geolocation
Cell tower mapping: Cell tower ID's resolve to a geolocation
So it is very possible that this user didn't include this permission and is getting this dialog box.
Yesterday I updated my Samsung Galaxy S5 Neo to the new Android Version 6.0.1. Since then the beacons won't be detected anymore. It does connect the Beacon Service, Updates the scan perios, etc. but it doesn't find any beacons.
Bluetooth is activated and the Beacon scanner of the Beacon Manifacturer still works fine (finds all the beacons). But not my app... It all worked before the new Android Update.
A few things to check:
Verify Location is enabled in Settings -> Location. This must be set to High Accuracy or Battery Saving. If set to Device Only, it won't work. Starting with Android 6, Location must be enabled to do bluetooth scans.
Make sure your app has been granted location permission. Check Settings -> Apps -> Your App -> Permissions, and verify the Location slider is set to on. Starting with Android 6, each app must dynamically request location access at runtime. If your app doesn't have code to do this, you'll need to add it. (Although it is possible to override in settings as described here.)
Make sure your app's manifest declares either FINE_LOCATION or COARSE_LOCATION in its declared permissions.
If the above don't help check LogCat (not just filtering on your application) for bluetooth errors.
See here for more info on the above.
I developed a custom watch face (Android Wear 5), works perfectly during testing. Uploaded to Google Play and download to test, but it does not show up in the Android Wear app, nor the paired watch itself (running Android Wear 5.0.1)!
I uploaded the mobile apk (similar to my other Android Wear apps), and also have the same permissions for both mobile and wear.
Anybody encountered similar problem? Here's the Watch Face if anybody wanted to test it out: https://play.google.com/store/apps/details?id=com.virtualgs.retrowatch
Are you sure you received an update to your watch face already? You will only see the new watch faces after an update.
If you do have an updated watch, try going to the Android Wear app on your phone, Settings -> Resync apps.
EDIT:
I looked into the logcat of the watch and I saw an attempt to install your watch package:
I/WearablePkgInstaller( 582): Sending install intent to PackageInstaller Intent { act=com.google.android.clockwork.packagemanager.INSTALL_PACKAGE dat=content://com.google.android.clockwork.home.provider/host/com.virtualgs.retrowatch/wearable/com.virtualgs.retrowatch/apk typ=vnd.android.cursor.item/wearable_apk pkg=com.google.android.clockwork.packageinstaller (has extras) }
W/WearablePkgInstaller( 1859): Wearable com.virtualgs.retrowatch has a permission "android.permission.PROVIDE_BACKGROUND" that is not granted in the host application.
You forgot to add PROVIDE_BACKGROUND permission to you phone app (wearable permission set has to be subset of the phone permission set). Remember, that you also need wake lock permission, in case you didn't add it.
EDIT2:
You are declaring wrong permission for providing background. This is the correct one:
com.google.android.permission.PROVIDE_BACKGROUND
can anybody explain me what is this error ? I am getting only for android 4 + and not for below:
E/AndroidRuntime(891): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.getaddress/com.example.getaddress.MainActivity}: java.lang.IllegalArgumentException: requested provider network doesn't exisit
It appears that the NETWORK_PROVIDER location provider is not accessible in Android 4+ emulators without Google APIs (well actually I have not tested on all of them ,see below). The real devices I have tested on are OK with it (but they all have Google services on them, it would be interesting to test with custom, clean Android versions, maybe with Kindles?).
It is not a question on enabling/disabling the provider in the device settings, it is simply not there in the emulator.
Symptom
Basically this code:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,mLocListener);
will cause the following exception:
java.lang.IllegalArgumentException: provider doesn't exisit: null
on all Android 4+ naked emulators (as opposed to Google-bound emulators)
note: the typo in "exisit" is in the actual log line.
Diagnostic
Getting a list of all location providers on the target device with the following:
List<String> providers = locationManager.getAllProviders();
I can see that the network provider is present on
physical devices
android 2.3.3 emulator (no Google APIs)
android level 17 (4.2) emulator (with Google APIs)
But not on
android level 15 (4.0.3) emulator with Google APIs
android 4.2 emulator (no Google APIs)
My guess is that for non-technical reasons, Google has not allowed the network location service in AOSP and limited its usage to the Google-bound versions of the OS from 4.2 (?).
What I don't know if whether or not there is a replacement network location service on non-Google devices (such as Kindle).
Probable impact on your app
I would not expect this to have any impact on most smartphones and tablets. However it can
somewhat impair your ability to test
be a compatibility issue for users that use custom/non-Google versions of Android (once again, Kindle?)
How to detect
A simple test such as:
locationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER)
can tell you painlessly if the network provider is present on the device. Note that if it is present, but the user has not activated it, your LocationListener will receive an onProviderDisabled callback following the location request.