Как правильно добавлять и запускать геозоны?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как правильно добавлять и запускать геозоны?

Сообщение Anonymous »


Я могу успешно добавить геозону, но она никогда не сработает на физическом устройстве. Они запускаются на эмуляторе, но никогда на моих телефонах.

Я слежу за Android Docs, но не могу заставить его активироваться на реальном устройстве. У меня есть нормальное и фоновое местоположение, в моем манифесте есть получатель. Функция onReceived вызывается при использовании эмулятора, но никогда на физическом устройстве. У меня тоже нет режима экономии заряда. Я потратил на это неделю... Что-нибудь очевидное, что я мог пропустить?

Обновление: Упрощенная версия того, что я делаю

пакет com.plutoapps.permissions импортировать android.Manifest импортировать android.annotation.SuppressLint импортировать android.app.NotificationChannel импортировать android.app.NotificationManager импортировать android.app.PendingIntent импортировать android.content.BroadcastReceiver импортировать android.content.Context импортировать android.content.ContextWrapper импортировать android.content.Intent импортировать android.content.pm.PackageManager импортировать android.os.Build импортировать android.os.Bundle импортировать android.util.Log импортировать android.widget.Toast импортировать androidx.activity.ComponentActivity импортировать androidx.activity.compose.rememberLauncherForActivityResult импортировать androidx.activity.compose.setContent импортировать androidx.activity.result.contract.ActivityResultContracts импортировать androidx.compose.foundation.layout.Arrangement импортировать androidx.compose.foundation.layout.Column импортировать androidx.compose.foundation.layout.fillMaxSize импортировать androidx.compose.foundation.layout.padding импортировать androidx.compose.material3.Button импортировать androidx.compose.material3.Scaffold импортировать androidx.compose.material3.Text импортировать androidx.compose.runtime.Composable импортировать androidx.compose.runtime.LaunchedEffect импортировать androidx.compose.runtime.getValue импортировать androidx.compose.runtime.mutableStateOf импортировать androidx.compose.runtime.remember импортировать androidx.compose.runtime.setValue импортировать androidx.compose.ui.Alignment импортировать androidx.compose.ui.Modifier импортировать androidx.compose.ui.platform.LocalContext импортировать androidx.core.app.NotificationCompat импортировать androidx.core.content.ContextCompat импортировать com.google.android.gms.location.FusedLocationProviderClient импортировать com.google.android.gms.location.Geofence импортировать com.google.android.gms.location.GeofenceStatusCodes импортировать com.google.android.gms.location.GeofencingClient импортировать com.google.android.gms.location.GeofencingEvent импортировать com.google.android.gms.location.GeofencingRequest импортировать com.google.android.gms.location.LocationServices импортировать com.google.android.gms.location.Priority импортировать com.plutoapps.permissions.ui.theme.PermissionsTheme const val TAG = "GeofenceApp" класс MainActivity : ComponentActivity() { частный lateinit var FusedClient: FusedLocationProviderClient частный lateinit var geofencingClient: GeofencingClient переопределить fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) FusedClient = LocationServices.getFusedLocationProviderClient(это) geofencingClient = LocationServices.getGeofencingClient(this) val geofencePendingIntent: PendingIntent от lazy { val Intent = Intent(this, GeofenceBroadcastReceiver::class.java) PendingIntent.getBroadcast(это, 0, намерение, PendingIntent.FLAG_MUTABLE) } setContent { Тема разрешений { // Поверхностный контейнер, использующий цвет фона из темы РазрешенияПриложение( FusedClient = FusedClient, geofencingClient = geofencingClient, geofencePendingIntent = geofencePendingIntent ) } } } } @SuppressLint("MissingPermission") @Композитный веселое приложение PermissionsApp( модификатор: Модификатор = Модификатор, плавленыйКлиент: FusedLocationProviderClient, geofencingClient: GeofencingClient, геозонаПедингИнтент: Ожидающее намерение ) { контекст val = LocalContext.current val listOfPermissions = listOfNotNull( Манифест.разрешение.ACCESS_FINE_LOCATION, если (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) Manifest.permission.POST_NOTIFICATIONS else null, ) var areAllPermissionsGranted, помните { mutableStateOf (ложь) } вар isBackgroundLocationPermissionsGranted запомнить { mutableStateOf( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) ContextCompat.checkSelfPermission( контекст, Manifest.permission.ACCESS_BACKGROUND_LOCATION ) == PackageManager.PERMISSION_GRANTED иначе true ) } val backgroundLocationPermissionsLauncher = запомнитьLauncherForActivityResult(contract = ActivityResultContracts.RequestPermission(), onResult = {isGranted -> isBackgroundLocationPermissionsGranted = isGranted }) val allPermissionsLauncher = запомнитьLauncherForActivityResult(contract = ActivityResultContracts.RequestMultiplePermissions(), onResult = { результаты -> areAllPermissionsGranted = !results.containsValue(false) если (results.containsValue(false)) { } еще { areAllPermissionsGranted = правда если (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { backgroundLocationPermissionsLauncher.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION) } } }) LaunchedEffect(key1 = "123") { если (!areAllPermissionsGranted) { allPermissionsLauncher.launch(listOfPermissions.toTypedArray()) } } Scaffold {paddingValues ​​-> Столбец( модификатор = модификатор .padding(paddingValues) .fillMaxSize(), вертикальноеРасположение = Расположение.Центр, HorizontalAlignment = Alignment.CenterHorizontally ) { Кнопка (onClick = { if (areAllPermissionsGranted && isBackgroundLocationPermissionsGranted) { FusedClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, ноль) .addOnSuccessListener { geofencingClient.addGeofences(GeofencingRequest.Builder().apply { setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER) addGeofence( Geofence.Builder().setRequestId("GeoRequest1") .setCircularRegion(it.latitude, it.longitude, 5f) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER или Geofence.GEOFENCE_TRANSITION_EXIT или Geofence.GEOFENCE_TRANSITION_DWELL) .setNotificationResponsiveness(1) .setExpirationDuration(Geofence.NEVER_EXPIRE) .setLoiteringDelay(5).build() ) }.build(), geofencePendingIntent).addOnSuccessListener { Toast.makeText(context, «Добавлена ​​геозона», Toast.LENGTH_LONG).show() } } } }) { Text(text = «Получить местоположение и установить геозону») } } } } класс GeofenceBroadcastReceiver : BroadcastReceiver() { переопределить fun onReceive(context: Context?, Intent: Intent?) { Log.d(ТЕГ, «получено») намерение?.применить { val geofencingEvent = GeofencingEvent.fromIntent(this) if (geofencingEvent?.hasError() == true) { значение errorMessage = GeofenceStatusCodes.getStatusCodeString(geofencingEvent.errorCode) Log.e(TAG, errorMessage) возвращаться } // Получаем тип перехода. val geofenceTransition = geofencingEvent!!.geofenceTransition контекст?.применить { NotificationHelper(this).sendNotification( «ГеоГео», "Вы ${if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) "останавливались" else if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) "вышли" иначе "вошло"}" ) } } } } класс NotificationHelper(private val context: Context) : ContextWrapper(context) { сопутствующий объект { const val ChannelId = "my_notification_channel" const val ChannelName = "Мой канал уведомлений" константное значение важности = NotificationManager.IMPORTANCE_DEFAULT } fun sendNotification (title: String, message: String) { // Создаем канал уведомлений для Android O и выше if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val канал = NotificationChannel (идентификатор канала, имя канала, важность) val NotificationManager = context.getSystemService(NotificationManager::class.java) NotificationManager.createNotificationChannel(канал) } // Создаем конструктор уведомлений val builder = NotificationCompat.Builder(контекст, идентификатор канала) .setSmallIcon(R.drawable.baseline_notifications_24) // Замените на свой значок .setContentTitle(заголовок).setContentText(сообщение) .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Показываем уведомление val NotificationManager = context.getSystemService(NotificationManager::class.java) NotificationManager.notify(0, builder.build()) } } Теперь мой манифест
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»