gpt4 book ai didi

java - 如何?监听位置设置是否已打开(Android 应用程序)

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:22:07 26 4
gpt4 key购买 nike

因此,在过去的几周里,我一直在开发我的 Android 应用程序,并寻找实现我需要做的事情的最佳方式,但仍然不能完全正确。非常感谢任何/所有帮助,因为我还在掌握一些东西..

任务:

(假设“位置”/GPS 设置当前关闭),我需要让我的应用程序不断监听“位置”设置是否打开。此时,只需启动一个 Activity 即可。

想法:

这些是我认为它可能起作用的所有不同方式:

  • 使用“onProviderEnabled”的 LocationListener

  • GpsStatusListener 使用“onGpsStatusChanged”和“GPS_EVENT_STARTED”

  • GpsProvider 需要卫星(以确定它是否启动),或以某种方式使用 GpsProvider 的“AVAILABLE”常量/int

  • SettingInjectorService 使用“ACTION_SERVICE_INTENT”(和/或)“ACTION_INJECTED_SETTING_CHANGED”和“onGetEnabled”或“isEnabled”

  • 设置。使用“LOCATION_MODE”安全!=“LOCATION_MODE_OFF”

  • ContentObserver/ContentResolver

  • Intent getAction (...)

  • 某种“if/else”

问题:

非常感谢对以下任何问题的任何建议或答案..

  • 以上哪项想法是完成任务的最佳方式?越简单越好,但最重要的是它需要时刻监听,并在位置设置打开时立即响应。

  • 对于上述想法中哪一个最有效,我将如何实现它? (例如,我需要一个 BroadcastListener 还是一个 Service?它们如何组合在一起?

我非常感谢您能为我提供的任何建议或帮助。我仍然掌握所有这一切,但有足够的信心去做,并渴望发布我的第一个应用程序。谢谢,它意义重大,对我有很大帮助。


编辑:

好的,这就是我到目前为止所得到的...
这是我的接收器:

我的接收器.Java

public class MyReceiver extends BroadcastReceiver {

private final static String TAG = "LocationProviderChanged";

boolean isGpsEnabled;
boolean isNetworkEnabled;



public MyReceiver() {
// EMPTY

// MyReceiver Close Bracket
}



// START OF onReceive
@Override
public void onReceive(Context context, Intent intent) {


// PRIMARY RECEIVER
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {

Log.i(TAG, "Location Providers Changed");

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

Toast.makeText(context, "GPS Enabled: " + isGpsEnabled + " Network Location Enabled: " + isNetworkEnabled, Toast.LENGTH_LONG).show();

// START DIALOG ACTIVITY
if (isGpsEnabled || isNetworkEnabled) {
Intent runDialogActivity = new Intent(context, DialogActivity.class);
context.startActivity(runDialogActivity);

}

}



// BOOT COMPLETED (REPLICA OF PRIMARY RECEIVER CODE FOR WHEN BOOT_COMPLETED)
if (intent.getAction().matches("android.intent.action.BOOT_COMPLETED")) {

Log.i(TAG, "Location Providers Changed Boot");

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

Toast.makeText(context, "GPS Enabled Boot: " + isGpsEnabled + " Network Location Enabled Boot: " + isNetworkEnabled, Toast.LENGTH_LONG).show();

// START DIALOG ACTIVITY
if (isGpsEnabled || isNetworkEnabled) {
Intent runDialogActivity = new Intent(context, DialogActivity.class);
context.startActivity(runDialogActivity);

}

}



// onReceive CLOSE BRACKET
}



// CLOSE OF FULL CLASS
}

list 如下所示:

list .XML

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ender.projects.receivertest">

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

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name=".DialogActivity">
</activity>

<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />

<action android:name="android.intent.action.BOOT_COMPLETED" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>

</application>

</manifest>

除了这些文件,我还有以下文件:
MainActivity.JavaDialogActivity.Java,均带有布局文件,
activity_main.xmlactivity_dialog.xml 来匹配它们。

所以如果我理解正确的话,当用户下载应用程序并打开它时,我的 MainActivity.Java 和相应的布局将启动。但我只会将其用作首选项屏幕。所以一旦他们第一次打开应用程序,广播接收器应该会自动开始监听要打开的位置设置,对吗?我还希望 Broadcast Listener 保持收听状态,即使在它接收到初始广播之后(这样我的 onReceive 仍然会在他们关闭 LOCATION 设置时触发,然后他们再次打开它..< br/>
那么 (A) 目前我的代码看起来如何?
(B) 要完成我刚才描述的内容,需要添加什么?
和 (C) 当我打开 LOCATION 设置时运行它会抛出这个错误。
..我该如何修复它?:
java.lang.RuntimeException:无法启动接收器 com.bryce.projects.servicesthreadsetc.MyReceiver:android.util.AndroidRuntimeException:从 Activity 上下文外部调用 startActivity() 需要 FLAG_ACTIVITY_NEW_TASK 标志。这真的是你想要的吗?


再次感谢所有的帮助!

最佳答案

由于您不需要实际获取 Location,因此满足您需求的最佳实现是 BroadcastReceiver。

这是最佳选择,因为您不需要一直运行服务(导致额外的电池耗尽),并且您可以从 BroadcastReceiver 启动 Activity 。

使用 Intent 过滤器和 BroadcastReceiver,只要 Location 设置发生更改(启用或禁用),操作系统就会启动您的应用程序,如果它已启用,您可以从 BroadcastReceiver 启动 Activity。

首先添加 Intent 过滤器,当 OS 发出设置已更改的隐式 Intent 时将捕获该过滤器。

<receiver
android:name=".LocationProviderChangedReceiver"
android:exported="false" >
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>

请注意,要使其在 Android Oreo 及更高版本上运行,您需要在运行时注册广播接收器,请参见此处:https://developer.android.com/guide/components/broadcasts#context-registered-receivers

然后,在 LocationProviderChangedReceiver.java 中,您的实现将如下所示:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.util.Log;
import android.widget.Toast;

public class LocationProviderChangedReceiver extends BroadcastReceiver {
private final static String TAG = "LocationProviderChanged";

boolean isGpsEnabled;
boolean isNetworkEnabled;

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
{
Log.i(TAG, "Location Providers changed");

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

//Start your Activity if location was enabled:
if (isGpsEnabled || isNetworkEnabled) {
Intent i = new Intent(context, YourActivity.class);
context.startActivity(i);
}
}
}
}

编辑

针对 Android 9 使用 Kotlin 和在运行时注册接收器的更新解决方案。

Kotlin 中的 BroadcastReceiver 类:

class LocationProviderChangedReceiver : BroadcastReceiver() {

internal var isGpsEnabled: Boolean = false
internal var isNetworkEnabled: Boolean = false

override fun onReceive(context: Context, intent: Intent) {
intent.action?.let { act ->
if (act.matches("android.location.PROVIDERS_CHANGED".toRegex())) {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

Log.i(TAG, "Location Providers changed, is GPS Enabled: " + isGpsEnabled)

//Start your Activity if location was enabled:
if (isGpsEnabled || isNetworkEnabled) {
val i = Intent(context, YourActivity::class.java)
context.startActivity(i)
}
}
}
}

companion object {
private val TAG = "LocationProviderChanged"
}
}

在运行时注册,例如在您应用的 MainActivity 的 onCreate() 中:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val br: BroadcastReceiver = LocationProviderChangedReceiver()
val filter = IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION)
registerReceiver(br, filter)
}

关于java - 如何?监听位置设置是否已打开(Android 应用程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36325088/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com