Location: Implement settings request (#2216)
For some applications that require GPS function, detect and remind the GPS to check in, such as Google Maps Co-authored-by: Marvin W <git@larma.de>
This commit is contained in:
parent
235622d79c
commit
df7a1b9991
20 changed files with 1209 additions and 12 deletions
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
<<<<<<< HEAD:play-services-base-core/src/main/java/org/microg/gms/DummyService.java
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -12,16 +13,25 @@
|
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
=======
|
||||
* SPDX-FileCopyrightText: 2017 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
>>>>>>> 2e4d3ae4 (Location: Implement settings request (#2216)):play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsStatusCodes.java
|
||||
*/
|
||||
|
||||
package org.microg.gms;
|
||||
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||
import com.google.android.gms.common.internal.GetServiceRequest;
|
||||
import com.google.android.gms.common.internal.IGmsCallbacks;
|
||||
|
||||
<<<<<<< HEAD:play-services-base-core/src/main/java/org/microg/gms/DummyService.java
|
||||
import org.microg.gms.common.GmsService;
|
||||
|
||||
public class DummyService extends BaseService {
|
||||
|
|
@ -32,5 +42,34 @@ public class DummyService extends BaseService {
|
|||
@Override
|
||||
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
|
||||
callback.onPostInitComplete(CommonStatusCodes.ERROR, null, null);
|
||||
=======
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Location settings specific status codes, for use in {@link Status#getStatusCode()}
|
||||
*/
|
||||
@PublicApi
|
||||
public class LocationSettingsStatusCodes extends CommonStatusCodes {
|
||||
/**
|
||||
* Location settings can't be changed to meet the requirements, no dialog pops up
|
||||
*/
|
||||
public static final int SETTINGS_CHANGE_UNAVAILABLE = 8502;
|
||||
|
||||
@NonNull
|
||||
@Hide
|
||||
public static String getStatusCodeString(int statusCode) {
|
||||
switch (statusCode) {
|
||||
case SETTINGS_CHANGE_UNAVAILABLE:
|
||||
return "SETTINGS_CHANGE_UNAVAILABLE";
|
||||
case 8500:
|
||||
case 8501:
|
||||
case 8503:
|
||||
case 8505:
|
||||
return "INTERNAL_LOCATION_SETTINGS_STATUS_CODE";
|
||||
default:
|
||||
return CommonStatusCodes.getStatusCodeString(statusCode);
|
||||
}
|
||||
>>>>>>> 2e4d3ae4 (Location: Implement settings request (#2216)):play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsStatusCodes.java
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
play-services-location/build.gradle
Normal file
43
play-services-location/build.gradle
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
android {
|
||||
namespace "com.google.android.gms.location"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
buildFeatures {
|
||||
aidl = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
apply from: '../gradle/publish-android.gradle'
|
||||
|
||||
description = 'microG implementation of play-services-location'
|
||||
|
||||
dependencies {
|
||||
// Dependencies from play-services-location:21.0.1
|
||||
api project(':play-services-base')
|
||||
api project(':play-services-basement')
|
||||
api project(':play-services-tasks')
|
||||
|
||||
annotationProcessor project(':safe-parcel-processor')
|
||||
}
|
||||
84
play-services-location/core/build.gradle
Normal file
84
play-services-location/core/build.gradle
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
api project(':play-services-location')
|
||||
implementation project(':play-services-base-core')
|
||||
implementation project(':play-services-location-core-base')
|
||||
|
||||
implementation "androidx.core:core-ktx:$coreVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-service:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion"
|
||||
implementation "androidx.preference:preference-ktx:$preferenceVersion"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion"
|
||||
|
||||
implementation "com.android.volley:volley:$volleyVersion"
|
||||
|
||||
compileOnly project(':play-services-maps')
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "org.microg.gms.location.core"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
buildConfigField "String", "ICHNAEA_KEY", "\"${localProperties.get("ichnaea.key", "")}\""
|
||||
buildConfigField "String", "FORCE_SHOW_BACKGROUND_PERMISSION", "\"\""
|
||||
buildConfigField "boolean", "SHOW_NOTIFICATION_WHEN_NOT_PERMITTED", "false"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'MissingTranslation', 'GetLocales'
|
||||
}
|
||||
|
||||
flavorDimensions = ['target']
|
||||
productFlavors {
|
||||
"default" {
|
||||
dimension 'target'
|
||||
}
|
||||
"huawei" {
|
||||
dimension 'target'
|
||||
buildConfigField "boolean", "SHOW_NOTIFICATION_WHEN_NOT_PERMITTED", "true"
|
||||
}
|
||||
"huaweilh" {
|
||||
dimension 'target'
|
||||
buildConfigField "String", "FORCE_SHOW_BACKGROUND_PERMISSION", "\"com.huawei.permission.sec.MDM.v2\""
|
||||
buildConfigField "boolean", "SHOW_NOTIFICATION_WHEN_NOT_PERMITTED", "true"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
huawei.java.srcDirs += 'src/huawei/kotlin'
|
||||
huaweilh.java.srcDirs += huawei.java.srcDirs
|
||||
huaweilh.res.srcDirs += huawei.res.srcDirs
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = 1.8
|
||||
}
|
||||
}
|
||||
62
play-services-location/core/src/main/AndroidManifest.xml
Normal file
62
play-services-location/core/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ SPDX-FileCopyrightText: 2020 microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<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_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.BODY_SENSORS" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.UPDATE_DEVICE_STATS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission
|
||||
android:name="android.permission.UPDATE_APP_OPS_STATS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WATCH_APPOPS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<application>
|
||||
|
||||
<activity
|
||||
android:name="org.microg.gms.location.settings.LocationSettingsCheckerActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false"
|
||||
android:process=":ui"
|
||||
android:theme="@style/AlertThemeSelector">
|
||||
<intent-filter android:priority="-1">
|
||||
<action android:name="com.google.android.gms.location.settings.CHECK_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.microg.gms.location.manager.AskPermissionActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:process=":ui"
|
||||
android:theme="@style/Theme.Translucent"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name="org.microg.gms.location.manager.LocationManagerService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.location.internal.GoogleLocationManagerService.START" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
android:name="org.microg.gms.location.reporting.ReportingAndroidService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.location.reporting.service.START" />
|
||||
<action android:name="com.google.android.gms.location.reporting.service.START" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
@ -8,7 +8,6 @@ package org.microg.gms.location.manager
|
|||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.FLAG_MUTABLE
|
||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
|
@ -17,6 +16,7 @@ import android.location.Location
|
|||
import android.os.*
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.util.Log
|
||||
import androidx.core.app.PendingIntentCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.location.LocationListenerCompat
|
||||
|
|
@ -146,7 +146,7 @@ class LocationManager(private val context: Context, override val lifecycle: Life
|
|||
}
|
||||
val intent = Intent(context, LocationManagerService::class.java)
|
||||
intent.action = LocationManagerService.ACTION_REPORT_LOCATION
|
||||
coarsePendingIntent = PendingIntent.getService(context, 0, intent, (if (SDK_INT >= 31) FLAG_MUTABLE else 0) or FLAG_UPDATE_CURRENT)
|
||||
coarsePendingIntent = PendingIntentCompat.getService(context, 0, intent, FLAG_UPDATE_CURRENT, true)
|
||||
lastLocationCapsule.start()
|
||||
requestManager.start()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,16 +7,22 @@ package org.microg.gms.location.manager
|
|||
|
||||
import android.Manifest.permission.*
|
||||
import android.app.PendingIntent
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
import android.location.Location
|
||||
import android.location.LocationManager.GPS_PROVIDER
|
||||
import android.location.LocationManager.NETWORK_PROVIDER
|
||||
import android.os.Binder
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.IBinder
|
||||
import android.os.Parcel
|
||||
import android.os.SystemClock
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import androidx.core.app.PendingIntentCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
|
@ -25,13 +31,14 @@ import com.google.android.gms.common.api.CommonStatusCodes
|
|||
import com.google.android.gms.common.api.Status
|
||||
import com.google.android.gms.common.api.internal.IStatusCallback
|
||||
import com.google.android.gms.common.internal.ICancelToken
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer
|
||||
import com.google.android.gms.location.*
|
||||
import com.google.android.gms.location.internal.*
|
||||
import com.google.android.gms.location.internal.DeviceOrientationRequestUpdateData.REMOVE_UPDATES
|
||||
import com.google.android.gms.location.internal.DeviceOrientationRequestUpdateData.REQUEST_UPDATES
|
||||
import kotlinx.coroutines.*
|
||||
import org.microg.gms.common.NonCancelToken
|
||||
import org.microg.gms.location.hasNetworkLocationServiceBuiltIn
|
||||
import org.microg.gms.location.settings.*
|
||||
import org.microg.gms.utils.warnOnTransactionIssues
|
||||
|
||||
class LocationManagerInstance(
|
||||
|
|
@ -209,17 +216,36 @@ class LocationManagerInstance(
|
|||
}
|
||||
|
||||
override fun requestLocationSettingsDialog(settingsRequest: LocationSettingsRequest?, callback: ISettingsCallbacks?, packageName: String?) {
|
||||
Log.d(TAG, "requestLocationSettingsDialog by ${getClientIdentity().packageName}")
|
||||
Log.d(TAG, "requestLocationSettingsDialog by ${getClientIdentity().packageName} $settingsRequest")
|
||||
val clientIdentity = getClientIdentity()
|
||||
lifecycleScope.launchWhenStarted {
|
||||
val locationManager = context.getSystemService<android.location.LocationManager>()
|
||||
val gpsPresent = locationManager?.allProviders?.contains(GPS_PROVIDER) == true
|
||||
val networkPresent = locationManager?.allProviders?.contains(NETWORK_PROVIDER) == true || context.hasNetworkLocationServiceBuiltIn()
|
||||
val gpsUsable = gpsPresent && locationManager?.isProviderEnabled(GPS_PROVIDER) == true &&
|
||||
context.packageManager.checkPermission(ACCESS_FINE_LOCATION, clientIdentity.packageName) == PERMISSION_GRANTED
|
||||
val networkUsable = networkPresent && locationManager?.isProviderEnabled(NETWORK_PROVIDER) == true &&
|
||||
context.packageManager.checkPermission(ACCESS_COARSE_LOCATION, clientIdentity.packageName) == PERMISSION_GRANTED
|
||||
runCatching { callback?.onLocationSettingsResult(LocationSettingsResult(LocationSettingsStates(gpsUsable, networkUsable, false, gpsPresent, networkPresent, true), Status.SUCCESS)) }
|
||||
val states = context.getDetailedLocationSettingsStates()
|
||||
val requests = settingsRequest?.requests?.map {
|
||||
it.priority to (if (it.granularity == Granularity.GRANULARITY_PERMISSION_LEVEL) context.granularityFromPermission(clientIdentity) else it.granularity)
|
||||
}.orEmpty()
|
||||
val gpsRequested = requests.any { it.first == Priority.PRIORITY_HIGH_ACCURACY && it.second == Granularity.GRANULARITY_FINE }
|
||||
val networkLocationRequested = requests.any { it.first <= Priority.PRIORITY_LOW_POWER && it.second >= Granularity.GRANULARITY_COARSE }
|
||||
val bleRequested = settingsRequest?.needBle == true
|
||||
val statusCode = when {
|
||||
gpsRequested && states.gpsPresent && !states.gpsUsable -> CommonStatusCodes.RESOLUTION_REQUIRED
|
||||
networkLocationRequested && states.networkLocationPresent && !states.networkLocationUsable -> CommonStatusCodes.RESOLUTION_REQUIRED
|
||||
bleRequested && states.blePresent && !states.bleUsable -> CommonStatusCodes.RESOLUTION_REQUIRED
|
||||
gpsRequested && !states.gpsPresent -> LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE
|
||||
networkLocationRequested && !states.networkLocationPresent -> LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE
|
||||
bleRequested && !states.blePresent -> LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE
|
||||
else -> CommonStatusCodes.SUCCESS
|
||||
}
|
||||
|
||||
val resolution = if (statusCode == CommonStatusCodes.RESOLUTION_REQUIRED) {
|
||||
val intent = Intent(ACTION_LOCATION_SETTINGS_CHECKER)
|
||||
intent.setPackage(context.packageName)
|
||||
intent.putExtra(EXTRA_ORIGINAL_PACKAGE_NAME, clientIdentity.packageName)
|
||||
intent.putExtra(EXTRA_SETTINGS_REQUEST, SafeParcelableSerializer.serializeToBytes(settingsRequest))
|
||||
PendingIntentCompat.getActivity(context, clientIdentity.packageName.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT, true)
|
||||
} else null
|
||||
val status = Status(statusCode, LocationSettingsStatusCodes.getStatusCodeString(statusCode), resolution)
|
||||
Log.d(TAG, "requestLocationSettingsDialog by ${getClientIdentity().packageName} returns $status")
|
||||
runCatching { callback?.onLocationSettingsResult(LocationSettingsResult(status, states.toApi())) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2024 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.location.settings
|
||||
|
||||
import android.Manifest.permission.*
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager.*
|
||||
import android.location.LocationManager
|
||||
import android.location.LocationManager.GPS_PROVIDER
|
||||
import android.location.LocationManager.NETWORK_PROVIDER
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.provider.Settings
|
||||
import androidx.core.content.getSystemService
|
||||
import com.google.android.gms.location.LocationSettingsStates
|
||||
import org.microg.gms.location.hasNetworkLocationServiceBuiltIn
|
||||
|
||||
data class DetailedLocationSettingsStates(
|
||||
val gpsSystemFeature: Boolean,
|
||||
val networkLocationSystemFeature: Boolean,
|
||||
val bluetoothLeSystemFeature: Boolean,
|
||||
val gpsProviderEnabled: Boolean,
|
||||
val networkLocationProviderEnabled: Boolean,
|
||||
val networkLocationProviderBuiltIn: Boolean,
|
||||
val fineLocationPermission: Boolean,
|
||||
val coarseLocationPermission: Boolean,
|
||||
val backgroundLocationPermission: Boolean,
|
||||
val blePresent: Boolean,
|
||||
val bleEnabled: Boolean,
|
||||
val bleScanAlways: Boolean,
|
||||
val airplaneMode: Boolean,
|
||||
) {
|
||||
val gpsPresent: Boolean
|
||||
get() = gpsSystemFeature
|
||||
val networkLocationPresent: Boolean
|
||||
get() = networkLocationSystemFeature || networkLocationProviderBuiltIn
|
||||
val gpsUsable: Boolean
|
||||
get() = gpsProviderEnabled && fineLocationPermission && backgroundLocationPermission
|
||||
val networkLocationUsable: Boolean
|
||||
get() = (networkLocationProviderEnabled || networkLocationProviderBuiltIn) && coarseLocationPermission && backgroundLocationPermission
|
||||
val bleUsable: Boolean
|
||||
get() = blePresent && (bleEnabled || (bleScanAlways && !airplaneMode))
|
||||
|
||||
fun toApi() = LocationSettingsStates(gpsUsable, networkLocationUsable, bleUsable, gpsPresent, networkLocationPresent, blePresent)
|
||||
}
|
||||
|
||||
fun Context.getDetailedLocationSettingsStates(): DetailedLocationSettingsStates {
|
||||
val bluetoothLeSystemFeature = packageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE)
|
||||
val locationManager = getSystemService<LocationManager>()
|
||||
val bluetoothManager = if (bluetoothLeSystemFeature) getSystemService<BluetoothManager>() else null
|
||||
val bleAdapter = bluetoothManager?.adapter
|
||||
|
||||
return DetailedLocationSettingsStates(
|
||||
gpsSystemFeature = packageManager.hasSystemFeature(FEATURE_LOCATION_GPS),
|
||||
networkLocationSystemFeature = packageManager.hasSystemFeature(FEATURE_LOCATION_NETWORK),
|
||||
bluetoothLeSystemFeature = bluetoothLeSystemFeature,
|
||||
gpsProviderEnabled = locationManager?.isProviderEnabled(GPS_PROVIDER) == true,
|
||||
networkLocationProviderEnabled = locationManager?.isProviderEnabled(NETWORK_PROVIDER) == true,
|
||||
networkLocationProviderBuiltIn = hasNetworkLocationServiceBuiltIn(),
|
||||
fineLocationPermission = packageManager.checkPermission(ACCESS_FINE_LOCATION, packageName) == PERMISSION_GRANTED,
|
||||
coarseLocationPermission = packageManager.checkPermission(ACCESS_COARSE_LOCATION, packageName) == PERMISSION_GRANTED,
|
||||
backgroundLocationPermission = if (SDK_INT < 29) true else
|
||||
packageManager.checkPermission(ACCESS_BACKGROUND_LOCATION, packageName) == PERMISSION_GRANTED,
|
||||
blePresent = bleAdapter != null,
|
||||
bleEnabled = bleAdapter?.isEnabled == true,
|
||||
bleScanAlways = Settings.Global.getInt(contentResolver, "ble_scan_always_enabled", 0) == 1,
|
||||
airplaneMode = Settings.Global.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.location.settings
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.location.LocationManager
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.widget.TextView
|
||||
import org.microg.gms.location.core.R
|
||||
|
||||
const val ACTION_LOCATION_SETTINGS_CHECKER = "com.google.android.gms.location.settings.CHECK_SETTINGS"
|
||||
|
||||
private const val REQUEST_CODE_LOCATION = 120
|
||||
const val EXTRA_ORIGINAL_PACKAGE_NAME = "originalPackageName"
|
||||
const val EXTRA_SETTINGS_REQUEST = "locationSettingsRequests"
|
||||
|
||||
class LocationSettingsCheckerActivity : Activity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_location_setting_checker)
|
||||
|
||||
findViewById<TextView>(R.id.location_setting_checker_sure).setOnClickListener {
|
||||
// TODO: We also should handle permissions, Airplane Mode and BLE here.
|
||||
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
|
||||
startActivityForResult(intent, REQUEST_CODE_LOCATION)
|
||||
}
|
||||
findViewById<TextView>(R.id.location_setting_checker_cancel).setOnClickListener {
|
||||
checkerBack(RESULT_CANCELED)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == REQUEST_CODE_LOCATION && isLocationEnabled(this)) {
|
||||
checkerBack(RESULT_OK)
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
checkerBack(RESULT_CANCELED)
|
||||
}
|
||||
|
||||
private fun checkerBack(resultCode: Int) {
|
||||
setResult(resultCode)
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun isLocationEnabled(context: Context): Boolean {
|
||||
val locationManager = context.getSystemService(LOCATION_SERVICE) as LocationManager
|
||||
return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) || locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#2a2931" />
|
||||
<corners android:radius="20dp" />
|
||||
</shape>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/location_settings_dialog_message_title_to_continue"
|
||||
android:textColor="#e4e1e5"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:text="@string/location_settings_dialog_message_details_start_paragraph"
|
||||
android:textColor="#e4e1e5"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:text="@string/location_settings_dialog_message_location_services_gps_and_nlp"
|
||||
android:textColor="#e4e1e5"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:text="@string/location_settings_dialog_message_gls_consent"
|
||||
android:textColor="#e4e1e5"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:text="@string/location_settings_dialog_message_details_end_paragraph"
|
||||
android:textColor="#e4e1e5"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/location_setting_checker_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/location_settings_dialog_btn_cancel"
|
||||
android:textColor="#c0c1fa"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/location_setting_checker_sure"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="30dp"
|
||||
android:text="@string/location_settings_dialog_btn_sure"
|
||||
android:textColor="#c0c1fa"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="pref_location_wifi_mls_enabled_summary">从 Mozilla 位置服务获取基于 Wi-Fi 的位置信息</string>
|
||||
<string name="pref_location_wifi_learning_enabled_summary">使用 GPS时,在本地存储 Wi-Fi 网络的位置信息</string>
|
||||
<string name="location_app_last_access_at">最后访问于<xliff:g example="Yesterday, 02:20 PM">%1$s</xliff:g></string>
|
||||
<string name="pref_location_cell_mls_enabled_title">向 Mozilla 发出请求</string>
|
||||
<string name="pref_location_cell_learning_enabled_summary">使用 GPS时,在本地存储移动网络的位置信息</string>
|
||||
<string name="fragment_location_apps_title">可访问位置信息的应用</string>
|
||||
<string name="pref_location_app_force_coarse_summary">无视应用的位置权限级别,总是向其提供大致的位置信息。</string>
|
||||
<string name="pref_location_cell_learning_enabled_title">从 GPS 处学习</string>
|
||||
<string name="pref_location_wifi_learning_enabled_title">从 GPS 处学习</string>
|
||||
<string name="pref_location_wifi_moving_enabled_summary">当连接到受支持的热点网络时,从上游热点直接获取 Wi-Fi 位置信息</string>
|
||||
<string name="prefcat_location_cell_title">基于移动网络的位置信息</string>
|
||||
<string name="pref_location_wifi_mls_enabled_title">向 Mozilla 发出请求</string>
|
||||
<string name="pref_location_wifi_moving_enabled_title">向热点发出请求</string>
|
||||
<string name="pref_location_app_force_coarse_title">总是提供大致的位置</string>
|
||||
<string name="pref_geocoder_nominatim_enabled_title">使用 Nominatim</string>
|
||||
<string name="service_name_location">位置信息</string>
|
||||
<string name="prefcat_location_apps_title">最近访问</string>
|
||||
<string name="pref_geocoder_nominatim_enabled_summary">使用 OpenStreetMap Nominatim 服务解析地址</string>
|
||||
<string name="prefcat_location_wifi_title">基于 Wi-Fi 的位置信息</string>
|
||||
<string name="prefcat_geocoder_title">地址解析器</string>
|
||||
<string name="pref_location_cell_mls_enabled_summary">从 Mozilla 位置服务获取移动网络信号塔位置</string>
|
||||
|
||||
<string name="location_settings_dialog_message_title_to_continue">要继续,请开启设备位置信息功能\n(使用位置信息服务)</string>
|
||||
<string name="location_settings_dialog_message_details_start_paragraph">您的设备将需要:</string>
|
||||
<string name="location_settings_dialog_message_location_services_gps_and_nlp">使用GPS、WLAN、移动网络和传感器</string>
|
||||
<string name="location_settings_dialog_message_gls_consent">使用位置信息服务;在提供该服务的过程中,可能会定期收集位置数据,并以匿名方式使用这类数据,从而提高位置信息的精准度并改善基于地理位置的服务。</string>
|
||||
<string name="location_settings_dialog_message_details_end_paragraph">有关详细信息,请访问 位置信息设置。</string>
|
||||
<string name="location_settings_dialog_btn_cancel">不用了</string>
|
||||
<string name="location_settings_dialog_btn_sure">确定</string>
|
||||
|
||||
</resources>
|
||||
39
play-services-location/core/src/main/res/values/strings.xml
Normal file
39
play-services-location/core/src/main/res/values/strings.xml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="service_name_location">Location</string>
|
||||
<string name="prefcat_location_apps_title">Recent access</string>
|
||||
<string name="prefcat_location_wifi_title">Wi-Fi location</string>
|
||||
<string name="prefcat_location_cell_title">Mobile network location</string>
|
||||
<string name="prefcat_geocoder_title">Address resolver</string>
|
||||
<string name="pref_location_wifi_mls_enabled_title">Request from Mozilla</string>
|
||||
<string name="pref_location_wifi_mls_enabled_summary">Fetch Wi-Fi-based location from Mozilla Location Service.</string>
|
||||
<string name="pref_location_wifi_moving_enabled_title">Request from Hotspot</string>
|
||||
<string name="pref_location_wifi_moving_enabled_summary">Fetch Wi-Fi location directly from supported hotspots when connected.</string>
|
||||
<string name="pref_location_wifi_learning_enabled_title">Remember from GPS</string>
|
||||
<string name="pref_location_wifi_learning_enabled_summary">Store Wi-Fi locations locally when GPS is used.</string>
|
||||
<string name="pref_location_cell_mls_enabled_title">Request from Mozilla</string>
|
||||
<string name="pref_location_cell_mls_enabled_summary">Fetch mobile network cell tower locations from Mozilla Location Service.</string>
|
||||
<string name="pref_location_cell_learning_enabled_title">Remember from GPS</string>
|
||||
<string name="pref_location_cell_learning_enabled_summary">Store mobile network locations locally when GPS is used.</string>
|
||||
<string name="pref_geocoder_nominatim_enabled_title">Use Nominatim</string>
|
||||
<string name="pref_geocoder_nominatim_enabled_summary">Resolve addresses using OpenStreetMap Nominatim.</string>
|
||||
|
||||
<string name="fragment_location_apps_title">Apps with location access</string>
|
||||
<string name="location_app_last_access_at">Last access: <xliff:g example="Yesterday, 02:20 PM">%1$s</xliff:g></string>
|
||||
|
||||
<string name="pref_location_app_force_coarse_title">Force coarse location</string>
|
||||
<string name="pref_location_app_force_coarse_summary">Always return coarse locations to this app, ignoring its permission level.</string>
|
||||
|
||||
<string name="location_settings_dialog_message_title_to_continue">To continue, turn on device location, which uses location service</string>
|
||||
<string name="location_settings_dialog_message_details_start_paragraph">Your device will need to:</string>
|
||||
<string name="location_settings_dialog_message_location_services_gps_and_nlp">Use GPS, Wi‑Fi, cell networks, and sensors</string>
|
||||
<string name="location_settings_dialog_message_gls_consent">Use location service; as part of this service, may collect location data periodically and use this data in an anonymous way to improve location accuracy and location-based services.</string>
|
||||
<string name="location_settings_dialog_message_details_end_paragraph">For details, go to the location settings.</string>
|
||||
<string name="location_settings_dialog_btn_cancel">No,thanks</string>
|
||||
<string name="location_settings_dialog_btn_sure">OK</string>
|
||||
|
||||
</resources>
|
||||
10
play-services-location/core/src/main/res/values/styles.xml
Normal file
10
play-services-location/core/src/main/res/values/styles.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="AlertThemeSelector" parent="Theme.AppCompat.Light.Dialog.Alert">
|
||||
<item name="android:windowBackground">@drawable/custom_dialog_background</item>
|
||||
<item name="android:windowMinWidthMajor">85%</item>
|
||||
<item name="android:windowMinWidthMinor">85%</item>
|
||||
<item name="android:windowCloseOnTouchOutside">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.google.android.gms.location.internal;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.api.internal.IStatusCallback;
|
||||
import com.google.android.gms.common.internal.ICancelToken;
|
||||
import com.google.android.gms.location.internal.DeviceOrientationRequestUpdateData;
|
||||
import com.google.android.gms.location.internal.IFusedLocationProviderCallback;
|
||||
import com.google.android.gms.location.internal.IGeofencerCallbacks;
|
||||
import com.google.android.gms.location.internal.ILocationStatusCallback;
|
||||
import com.google.android.gms.location.internal.ISettingsCallbacks;
|
||||
import com.google.android.gms.location.internal.LocationReceiver;
|
||||
import com.google.android.gms.location.internal.LocationRequestInternal;
|
||||
import com.google.android.gms.location.internal.LocationRequestUpdateData;
|
||||
import com.google.android.gms.location.internal.ParcelableGeofence;
|
||||
import com.google.android.gms.location.ActivityRecognitionResult;
|
||||
import com.google.android.gms.location.ActivityRecognitionRequest;
|
||||
import com.google.android.gms.location.ActivityTransitionRequest;
|
||||
import com.google.android.gms.location.CurrentLocationRequest;
|
||||
import com.google.android.gms.location.GeofencingRequest;
|
||||
import com.google.android.gms.location.GestureRequest;
|
||||
import com.google.android.gms.location.ILocationListener;
|
||||
import com.google.android.gms.location.LastLocationRequest;
|
||||
import com.google.android.gms.location.LocationAvailability;
|
||||
import com.google.android.gms.location.LocationAvailabilityRequest;
|
||||
import com.google.android.gms.location.LocationRequest;
|
||||
import com.google.android.gms.location.LocationSettingsRequest;
|
||||
import com.google.android.gms.location.LocationStatus;
|
||||
import com.google.android.gms.location.SleepSegmentRequest;
|
||||
|
||||
interface IGoogleLocationManagerService {
|
||||
|
||||
// current
|
||||
|
||||
void addGeofences(in GeofencingRequest geofencingRequest, in PendingIntent pendingIntent, IGeofencerCallbacks callbacks) = 56;
|
||||
void removeGeofencesByIntent(in PendingIntent pendingIntent, IGeofencerCallbacks callbacks, String packageName) = 1;
|
||||
void removeGeofencesById(in String[] geofenceRequestIds, IGeofencerCallbacks callbacks, String packageName) = 2;
|
||||
|
||||
void removeActivityTransitionUpdates(in PendingIntent pendingIntent, IStatusCallback callback) = 72;
|
||||
void removeActivityUpdates(in PendingIntent callbackIntent) = 5;
|
||||
void requestActivityTransitionUpdates(in ActivityTransitionRequest request, in PendingIntent pendingIntent, IStatusCallback callback) = 71;
|
||||
void requestActivityUpdates(long detectionIntervalMillis, boolean triggerUpdates, in PendingIntent callbackIntent) = 4;
|
||||
void requestActivityUpdatesWithCallback(in ActivityRecognitionRequest request, in PendingIntent pendingIntent, IStatusCallback callback) = 69;
|
||||
|
||||
Location getLastLocation() = 6;
|
||||
void getLastLocationWithRequest(in LastLocationRequest request, ILocationStatusCallback callback) = 81;
|
||||
void getLastLocationWithReceiver(in LastLocationRequest request, in LocationReceiver receiver) = 89;
|
||||
|
||||
ICancelToken getCurrentLocation(in CurrentLocationRequest request, ILocationStatusCallback callback) = 86;
|
||||
ICancelToken getCurrentLocationWithReceiver(in CurrentLocationRequest request, in LocationReceiver receiver) = 91;
|
||||
|
||||
void requestLocationUpdatesWithCallback(in LocationReceiver receiver, in LocationRequest request, IStatusCallback callback) = 87;
|
||||
void removeLocationUpdatesWithCallback(in LocationReceiver receiver, IStatusCallback callback) = 88;
|
||||
void updateLocationRequest(in LocationRequestUpdateData locationRequestUpdateData) = 58;
|
||||
|
||||
void flushLocations(IFusedLocationProviderCallback callback) = 66;
|
||||
|
||||
LocationAvailability getLocationAvailabilityWithPackage(String packageName) = 33;
|
||||
void getLocationAvailabilityWithReceiver(in LocationAvailabilityRequest request, in LocationReceiver receiver) = 90;
|
||||
|
||||
void setMockMode(boolean mockMode) = 11;
|
||||
void setMockLocation(in Location mockLocation) = 12;
|
||||
void setMockModeWithCallback(boolean mockMode, IStatusCallback callback) = 83;
|
||||
void setMockLocationWithCallback(in Location mockLocation, IStatusCallback callback) = 84;
|
||||
|
||||
void removeSleepSegmentUpdates(in PendingIntent pendingIntent, IStatusCallback callback) = 68;
|
||||
void requestSleepSegmentUpdates(in PendingIntent pendingIntent, in SleepSegmentRequest request, IStatusCallback callback) = 78;
|
||||
|
||||
void requestLocationSettingsDialog(in LocationSettingsRequest settingsRequest, ISettingsCallbacks callback, String packageName) = 62;
|
||||
|
||||
void updateDeviceOrientationRequest(in DeviceOrientationRequestUpdateData request) = 74;
|
||||
|
||||
// deprecated
|
||||
|
||||
void addGeofencesList(in List<ParcelableGeofence> geofences, in PendingIntent pendingIntent, IGeofencerCallbacks callbacks, String packageName) = 0;
|
||||
void removeAllGeofences(IGeofencerCallbacks callbacks, String packageName) = 3;
|
||||
|
||||
ActivityRecognitionResult getLastActivity(String packageName) = 63;
|
||||
|
||||
Location getLastLocationWithPackage(String packageName) = 20;
|
||||
Location getLastLocationWith(String s) = 79;
|
||||
|
||||
void requestLocationUpdatesWithListener(in LocationRequest request, ILocationListener listener) = 7;
|
||||
void requestLocationUpdatesWithPackage(in LocationRequest request, ILocationListener listener, String packageName) = 19;
|
||||
void requestLocationUpdatesWithIntent(in LocationRequest request, in PendingIntent callbackIntent) = 8;
|
||||
void requestLocationUpdatesInternalWithListener(in LocationRequestInternal request, ILocationListener listener) = 51;
|
||||
void requestLocationUpdatesInternalWithIntent(in LocationRequestInternal request, in PendingIntent callbackIntent) = 52;
|
||||
void removeLocationUpdatesWithListener(ILocationListener listener) = 9;
|
||||
void removeLocationUpdatesWithIntent(in PendingIntent callbackIntent) = 10;
|
||||
|
||||
// unsupported
|
||||
|
||||
// void iglms14(in LatLngBounds var1, int var2, in PlaceFilter var3, in PlacesParams var4, IPlacesCallbacks var5) = 13;
|
||||
// void iglms15(String var1, in PlacesParams var2, IPlacesCallbacks var3) = 14;
|
||||
// void iglms16(in LatLng var1, in PlaceFilter var2, in PlacesParams var3, IPlacesCallbacks var4) = 15;
|
||||
// void iglms17(in PlaceFilter var1, in PlacesParams var2, IPlacesCallbacks var3) = 16;
|
||||
// void iglms18(in PlaceRequest var1, in PlacesParams var2, in PendingIntent var3) = 17;
|
||||
// void iglms19(in PlacesParams var1, in PendingIntent var2) = 18;
|
||||
|
||||
// void iglms25(in PlaceReport var1, in PlacesParams var2) = 24;
|
||||
// void injectLocation(in Location mockLocation, int injectionType) = 25;
|
||||
|
||||
// void iglms42(String var1, in PlacesParams var2, IPlacesCallbacks var3) = 41;
|
||||
|
||||
// void iglms46(in UserAddedPlace var1, in PlacesParams var2, IPlacesCallbacks var3) = 45;
|
||||
// void iglms47(in LatLngBounds var1, int var2, String var3, in PlaceFilter var4, in PlacesParams var5, IPlacesCallbacks var6) = 46;
|
||||
// void iglms48(in NearbyAlertRequest var1, in PlacesParams var2, in PendingIntent var3) = 47;
|
||||
// void iglms49(in PlacesParams var1, in PendingIntent var2) = 48;
|
||||
// void iglms50(in UserDataType var1, in LatLngBounds var2, in List var3, in PlacesParams var4, IPlacesCallbacks var5) = 49;
|
||||
// IBinder iglms51() = 50;
|
||||
|
||||
// IBinder iglms54() = 53;
|
||||
// void iglms55(String var1, in LatLngBounds var2, in AutocompleteFilter var3, in PlacesParams var4, IPlacesCallbacks var5) = 54;
|
||||
|
||||
// void iglms58(in List var1, in PlacesParams var2, IPlacesCallbacks var3) = 57;
|
||||
|
||||
// Status requestGestureUpdates(in GestureRequest request, in PendingIntent pendingIntent) = 59;
|
||||
// Status iglms61(in PendingIntent pendingIntent) = 60;
|
||||
|
||||
// void iglms65(in PendingIntent pendingIntent, IStatusCallback callback) = 64;
|
||||
// void iglms66(in PendingIntent pendingIntent, IStatusCallback callback) = 65;
|
||||
|
||||
// void iglms68(in PendingIntent pendingIntent, IStatusCallback callback) = 67;
|
||||
|
||||
// void iglms71(IStatusCallback callback) = 70;
|
||||
|
||||
// void removeGeofences(in RemoveGeofencingRequest request, IGeofencerCallbacks callback) = 73;
|
||||
// void iglms76(in PendingIntent pendingIntent) = 75;
|
||||
// boolean setActivityRecognitionMode(int mode) = 76;
|
||||
// int getActivityRecognitionMode() = 77;
|
||||
|
||||
// void injectLocatinWithCallback(in Location mockLocation, int injectionType, IStatusCallback callback) = 85;
|
||||
|
||||
// void isGoogleLocationAccuracyEnabled(in IBooleanStatusCallback callback) = 94;
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Specifies the types of location services the client is interested in using. Settings will be checked for optimal functionality
|
||||
* of all requested services. Use {@link LocationSettingsRequest.Builder} to construct this object.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class LocationSettingsRequest extends AbstractSafeParcelable {
|
||||
@Field(1000)
|
||||
private int versionCode = 2;
|
||||
|
||||
@Field(value = 1, subClass = LocationRequest.class)
|
||||
@Hide
|
||||
public final List<LocationRequest> requests;
|
||||
|
||||
@Field(2)
|
||||
@Hide
|
||||
public final boolean alwaysShow;
|
||||
|
||||
@Field(3)
|
||||
@Hide
|
||||
public final boolean needBle;
|
||||
|
||||
@Field(5)
|
||||
@Hide
|
||||
@Nullable
|
||||
public final LocationSettingsConfiguration configuration;
|
||||
|
||||
@Constructor
|
||||
LocationSettingsRequest(@Param(1) List<LocationRequest> requests, @Param(2) boolean alwaysShow, @Param(3) boolean needBle, @Param(5) @Nullable LocationSettingsConfiguration configuration) {
|
||||
this.requests = requests;
|
||||
this.alwaysShow = alwaysShow;
|
||||
this.needBle = needBle;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder that builds {@link LocationSettingsRequest}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private List<LocationRequest> requests = new ArrayList<LocationRequest>();
|
||||
private boolean alwaysShow = false;
|
||||
private boolean needBle = false;
|
||||
|
||||
/**
|
||||
* Adds a collection of {@link LocationRequest}s that the client is interested in. Settings
|
||||
* will be checked for optimal performance of all {@link LocationRequest}s.
|
||||
*/
|
||||
public Builder addAllLocationRequests(Collection<LocationRequest> requests) {
|
||||
this.requests.addAll(requests);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one {@link LocationRequest} that the client is interested in. Settings will be
|
||||
* checked for optimal performance of all {@link LocationRequest}s.
|
||||
*/
|
||||
public Builder addLocationRequest(LocationRequest request) {
|
||||
requests.add(request);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LocationSettingsRequest that can be used with SettingsApi.
|
||||
*/
|
||||
public LocationSettingsRequest build() {
|
||||
return new LocationSettingsRequest(requests, alwaysShow, needBle, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not location is required by the calling app in order to continue. Set this to
|
||||
* true if location is required to continue and false if having location provides better
|
||||
* results, but is not required. This changes the wording/appearance of the dialog
|
||||
* accordingly.
|
||||
*/
|
||||
public Builder setAlwaysShow(boolean show) {
|
||||
alwaysShow = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the client wants BLE scan to be enabled. When this flag is set to true, if
|
||||
* the platform supports BLE scan mode and Bluetooth is off, the dialog will prompt the
|
||||
* user to enable BLE scan. If the platform doesn't support BLE scan mode, the dialog will
|
||||
* prompt to enable Bluetooth.
|
||||
*/
|
||||
public Builder setNeedBle(boolean needBle) {
|
||||
this.needBle = needBle;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Hide
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("LocationSettingsRequest")
|
||||
.value(requests)
|
||||
.field("alwaysShow", alwaysShow)
|
||||
.field("needBle", needBle)
|
||||
.end();
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<LocationSettingsRequest> CREATOR = findCreator(LocationSettingsRequest.class);
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.ResolvableApiException;
|
||||
import com.google.android.gms.common.api.Response;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Successful response of checking settings via {@link SettingsApi#checkLocationSettings(GoogleApiClient, LocationSettingsRequest)}.
|
||||
* <p>
|
||||
* If a {@link Task} with this response type fails, it will receive a {@link ResolvableApiException} which may be able to resolve the failure.
|
||||
* See {@link SettingsClient} for more details.
|
||||
* <p>
|
||||
* The current location settings states can be accessed via {@link #getLocationSettingsStates()}. See {@link LocationSettingsStates} for more details.
|
||||
*/
|
||||
public class LocationSettingsResponse extends Response<LocationSettingsResult> {
|
||||
/**
|
||||
* Retrieves the location settings states.
|
||||
*/
|
||||
@Nullable
|
||||
public LocationSettingsStates getLocationSettingsStates() {
|
||||
return getResult().getLocationSettingsStates();
|
||||
}
|
||||
|
||||
@Hide
|
||||
public LocationSettingsResponse(@NonNull LocationSettingsResult result) {
|
||||
super(result);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.Result;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Result of checking settings via {@link SettingsApi#checkLocationSettings(GoogleApiClient, LocationSettingsRequest)},
|
||||
* indicates whether a dialog should be shown to ask the user's consent to change their
|
||||
* settings.
|
||||
* <p>
|
||||
* The method {@link #getStatus()} can be used to confirm if the request was successful. If the current location settings don't
|
||||
* satisfy the app's requirements and the user has permission to change the settings, the app could use
|
||||
* {@link Status#startResolutionForResult(Activity, int)} to start an intent to show a dialog, asking for user's consent to
|
||||
* change the settings.
|
||||
* <p>
|
||||
* The current location settings states can be accessed via {@link #getLocationSettingsStates()}. See
|
||||
* {@link LocationSettingsStates} for more details.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class LocationSettingsResult extends AbstractSafeParcelable implements Result {
|
||||
|
||||
@Field(1000)
|
||||
int versionCode = 1;
|
||||
|
||||
@Field(1)
|
||||
@NonNull
|
||||
private final Status status;
|
||||
|
||||
@Field(2)
|
||||
@Nullable
|
||||
private final LocationSettingsStates settings;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the location settings states.
|
||||
*/
|
||||
@Nullable
|
||||
public LocationSettingsStates getLocationSettingsStates() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Hide
|
||||
@Constructor
|
||||
public LocationSettingsResult(@Param(1) @NonNull Status status, @Param(2) @Nullable LocationSettingsStates settings) {
|
||||
this.settings = settings;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Hide
|
||||
public LocationSettingsResult(@NonNull Status status) {
|
||||
this(status, null);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<LocationSettingsResult> CREATOR = findCreator(LocationSettingsResult.class);
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Stores the current states of all location-related settings.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class LocationSettingsStates extends AbstractSafeParcelable {
|
||||
|
||||
@Field(1000)
|
||||
int versionCode = 2;
|
||||
|
||||
@Field(1)
|
||||
private final boolean gpsUsable;
|
||||
|
||||
@Field(2)
|
||||
private final boolean networkLocationUsable;
|
||||
|
||||
@Field(3)
|
||||
private final boolean bleUsable;
|
||||
|
||||
@Field(4)
|
||||
private final boolean gpsPresent;
|
||||
|
||||
@Field(5)
|
||||
private final boolean networkLocationPresent;
|
||||
|
||||
@Field(6)
|
||||
private final boolean blePresent;
|
||||
|
||||
/**
|
||||
* Whether BLE is present on the device.
|
||||
*/
|
||||
public boolean isBlePresent() {
|
||||
return blePresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether BLE is enabled and is usable by the app.
|
||||
*/
|
||||
public boolean isBleUsable() {
|
||||
return bleUsable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether GPS provider is present on the device.
|
||||
*/
|
||||
public boolean isGpsPresent() {
|
||||
return gpsPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether GPS provider is enabled and is usable by the app.
|
||||
*/
|
||||
public boolean isGpsUsable() {
|
||||
return gpsUsable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether location is present on the device.
|
||||
* <p>
|
||||
* This method returns true when either GPS or network location provider is present.
|
||||
*/
|
||||
public boolean isLocationPresent() {
|
||||
return isGpsPresent() || isNetworkLocationPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether location is enabled and is usable by the app.
|
||||
* <p>
|
||||
* This method returns true when either GPS or network location provider is usable.
|
||||
*/
|
||||
public boolean isLocationUsable() {
|
||||
return isGpsUsable() || isNetworkLocationUsable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether network location provider is present on the device.
|
||||
*/
|
||||
public boolean isNetworkLocationPresent() {
|
||||
return networkLocationPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether network location provider is enabled and usable by the app.
|
||||
*/
|
||||
public boolean isNetworkLocationUsable() {
|
||||
return networkLocationUsable;
|
||||
}
|
||||
|
||||
@Constructor
|
||||
public LocationSettingsStates(@Param(1) boolean gpsUsable, @Param(2) boolean networkLocationUsable, @Param(3) boolean bleUsable, @Param(4) boolean gpsPresent, @Param(5) boolean networkLocationPresent, @Param(6) boolean blePresent) {
|
||||
this.gpsUsable = gpsUsable;
|
||||
this.networkLocationUsable = networkLocationUsable;
|
||||
this.bleUsable = bleUsable;
|
||||
this.gpsPresent = gpsPresent;
|
||||
this.networkLocationPresent = networkLocationPresent;
|
||||
this.blePresent = blePresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the location settings states from the intent extras. When the location settings dialog finishes, you can use this
|
||||
* method to retrieve the current location settings states from the intent in your
|
||||
* {@link Activity#onActivityResult(int, int, Intent)}.
|
||||
*/
|
||||
public static LocationSettingsStates fromIntent(Intent intent) {
|
||||
byte[] bytes = intent.getByteArrayExtra(EXTRA_NAME);
|
||||
if (bytes == null) return null;
|
||||
return SafeParcelableSerializer.deserializeFromBytes(bytes, CREATOR);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<LocationSettingsStates> CREATOR = findCreator(LocationSettingsStates.class);
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
private static final String EXTRA_NAME = "com.google.android.gms.location.LOCATION_SETTINGS_STATES";
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import android.location.LocationManager;
|
||||
import android.provider.Settings;
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.HasApiKey;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
/**
|
||||
* The main entry point for interacting with the location settings-enabler APIs.
|
||||
* <p>
|
||||
* This API makes it easy for an app to ensure that the device's system settings are properly configured for the app's
|
||||
* location needs.
|
||||
*/
|
||||
public interface SettingsClient extends HasApiKey<Api.ApiOptions.NoOptions> {
|
||||
/**
|
||||
* Checks if the relevant system settings are enabled on the device to carry out the desired location requests.
|
||||
*
|
||||
* @param locationSettingsRequest an object that contains all the location requirements that the client is interested in.
|
||||
*/
|
||||
Task<LocationSettingsResponse> checkLocationSettings(LocationSettingsRequest locationSettingsRequest);
|
||||
|
||||
/**
|
||||
* Returns true if the Google Location Accuracy setting is currently enabled. This setting is required for Fused Location
|
||||
* Provider APIs to be able to generate network (wifi, cell, etc) based locations. If Google Play services is chosen as the
|
||||
* platform {@link LocationManager#NETWORK_PROVIDER} (this is the case on all GMS compliant devices, which constitute the
|
||||
* vast majority of the Android ecosystem), then this setting is also required for the platform
|
||||
* {@link LocationManager#NETWORK_PROVIDER} to be enabled.
|
||||
* <p>
|
||||
* On Android P and above devices, the Google Location Accuracy setting may be found under location settings. Below
|
||||
* Android P, Google Location Accuracy is tied to the device location mode - it will be enabled if the device is in
|
||||
* {@link Settings.Secure#LOCATION_MODE_BATTERY_SAVING} or {@link Settings.Secure#LOCATION_MODE_HIGH_ACCURACY}, and
|
||||
* disabled in {@link Settings.Secure#LOCATION_MODE_SENSORS_ONLY}.
|
||||
*/
|
||||
Task<Boolean> isGoogleLocationAccuracyEnabled();
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.location;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.GoogleApi;
|
||||
import com.google.android.gms.location.*;
|
||||
import com.google.android.gms.location.internal.ISettingsCallbacks;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.gms.tasks.TaskCompletionSource;
|
||||
import com.google.android.gms.tasks.Tasks;
|
||||
import org.microg.gms.common.api.PendingGoogleApiCall;
|
||||
|
||||
public class SettingsClientImpl extends GoogleApi<Api.ApiOptions.NoOptions> implements SettingsClient {
|
||||
public SettingsClientImpl(Context context) {
|
||||
super(context, LocationServices.API);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task<LocationSettingsResponse> checkLocationSettings(LocationSettingsRequest locationSettingsRequest) {
|
||||
return scheduleTask((PendingGoogleApiCall<LocationSettingsResponse, LocationClientImpl>) (client, completionSource) -> client.getServiceInterface().requestLocationSettingsDialog(locationSettingsRequest, new ISettingsCallbacks.Stub() {
|
||||
@Override
|
||||
public void onLocationSettingsResult(LocationSettingsResult result) {
|
||||
completionSource.setResult(new LocationSettingsResponse(result));
|
||||
}
|
||||
}, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task<Boolean> isGoogleLocationAccuracyEnabled() {
|
||||
return Tasks.forResult(true); // TODO
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue