如何?收听位置设置(Android App) [英] How to? Listen for Location Setting being turned ON (Android App)

查看:208
本文介绍了如何?收听位置设置(Android App)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我花了几周的时间研究我的Android应用程序,并研究了实现我需要做的最好的方法,但仍然不能完全正确地做到。任何/所有帮助都非常值得赞赏,因为我仍然得到一些东西。

任务:



(假设位置 GPS设置目前关闭),我需要让我的应用程序不断地收听位置设置为开启。此时,只需启动一个活动。



< h2>想法:

这些都是我认为可能有效的所有不同方式:

    $ b $
  • 使用onGpsStatusChanged和GPS_EVENT_STARTED的GpsStatusListener


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


  • SettingInjectorService使用ACTION_SERVICE_INTENT (和/或)ACTION_INJECTED_SETT ING_CHANGEDwithonGetEnabled或isEnabled


  • Settings.Secure使用LOCATION_MODE!=LOCATION_MODE_OFF


  • a ContentObserver / ContentResolver


  • Intent getAction(...)

  • li>

    某种if / else



问题:



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


  • 上述哪个想法是完成这项任务的最佳方式?越简单越好,但最重要的是它必须始终在监听,并且在打开位置设置时立即作出响应。


  • 无论哪一个上面的想法效果最好,我将如何实现它? (例如,我是否需要一个BroadcastListener?或一个服务?以及它将如何组合在一起?



我真正感谢你能给我提供的任何建议或帮助..我仍然掌握了所有这些,但有足够的信心去做,并且渴望发布我的第一个应用程序。所以,谢谢你,这意味着很多,将大大帮助我。






编辑:



好​​所以这里是我到目前为止...


我的收件人:




MyReceiver.Java

  public class MyReceiver extends BroadcastReceiver {

private final static String TAG =LocationProviderChanged;

boolean isGpsEnabled;
boolean isNetworkEnabled;


$ b $ public MyReceiver(){
// EMPTY

// MyReceiver关闭括号
}



//开始的onReceive
@Override
public v oid onReceive(Context context,Intent intent){


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

Log.i(标签,位置提供商已更改);

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);






$ b //完成引导$ b 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);

}

}



//接收CLOSE BRACKET
}



//完整类别关闭
}

并且继承人Manifest看起来像:

Manifest.XML

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

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

<使用权限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>
< 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>


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

< / application>

< / manifest>

除了这些文件,我还有以下文件:

MainActivity.Java DialogActivity.Java ,包含布局文件,

activity_main .xml activity_dialog.xml 与它们匹配。



所以如果我理解正确,当用户下载应用程序并打开它时,我的 MainActivity.Java 和相应的布局将启动。但我只是将其用作偏好屏幕。因此,一旦他们第一次打开应用程序,广播接收器应该自动开始监听LOCATION设置是否开启,是否正确?我还希望广播监听器保持监听,即使它接收到初始广播后(以便我们的 onReceive 如果它们关闭LOCATION设置仍会触发,然后它们转向它再次打开..



所以(A)我的代码到目前为止看起来如何?

和(B)为了完成我刚刚描述的内容,需要添加?

和(C)当我打开LOCATION设置时,运行它会引发此错误。

..如何修复它?:

java.lang.RuntimeException:无法启动接收器com.bryce.projects.servicesthreadsetc.MyReceiver:android.util.AndroidRuntimeException:从Activity上下文外部调用startActivity()需要FLAG_ACTIVITY_NEW_TASK标志。这真的是你想要的吗?





再次感谢所有帮助!

$由于您不需要真正获取位置,因此您的需求的最佳实施将是Broadca streceiver。



这是最好的选择,因为你不需要一直在运行一个服务(导致额外的连击),你将能够使用意向过滤器和BroadcastReceiver,当位置设置发生变化(启用或禁用)时,您的应用将由操作系统启动,并且在启用的情况下,您可以从BroadcastReceiver启动您的Activity。



首先添加intent过滤器,当操作系统发出隐式Intent设置已经改变:



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

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



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

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

boolean isGpsEnabled;
boolean isNetworkEnabled;
$ b @Override
public void onReceive(Context context,Intent intent){
if(intent.getAction()。matches(android.location.PROVIDERS_CHANGED))
{
Log.i(标签,定位提供商已更改);

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

//如果启用位置,则开始您的活动:
if(isGpsEnabled || isNetworkEnabled){
Intent i = new Intent(context,YourActivity.class);
context.startActivity(i);
}
}
}
}


So I've spent the past few weeks working on my Android App and looking into the best way of implementing what I need to do, but still can't quite get it right.. Any/all help is greatly appreciated, as I am still getting the hang of things..

Task:

(Assuming the "Location"/GPS Setting is currently off), I need to have my App constantly be listening for the "Location" Setting to be turned ON.. At this point, simply start an Activity.

Ideas:

These are all the different ways I think it could possibly work:

  • LocationListener using "onProviderEnabled"

  • GpsStatusListener using "onGpsStatusChanged" with "GPS_EVENT_STARTED"

  • GpsProvider requiresSatellite (to determine if it starts), or somehow use the GpsProvider's "AVAILABLE" Constant/int

  • SettingInjectorService using "ACTION_SERVICE_INTENT" (and/or) "ACTION_INJECTED_SETTING_CHANGED" with "onGetEnabled" or "isEnabled"

  • Settings.Secure using "LOCATION_MODE" != "LOCATION_MODE_OFF"

  • a ContentObserver/ContentResolver

  • Intent getAction (...)

  • An "if/else" of some kind

Questions:

Any kind of advice or answers for any of the following questions are very much appreciated..

  • Which of the Ideas above would be the best way of accomplishing the Task? The simpler the better, but most importantly it needs to be listening at all times, and respond instantly when the Location Setting is turned On.

  • For whichever one of the Ideas above works best, how would I implement it? (For example, would I need a BroadcastListener? or a Service? and how would it all piece together?

I truly appreciate any advice or help that you can provide me with.. I'm still getting the hang of all this, but confident enough to do it, and eager to publish my first App.. So thank you, it means a lot and will greatly help me along.


EDIT:

OK So here's what I've got so far...
Heres my Receiver:

MyReceiver.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
}

And heres what the Manifest looks like:

Manifest.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>

Aside from these files, I have the following files:
MainActivity.Java and DialogActivity.Java, both with Layout files,
activity_main.xml and activity_dialog.xml to match with them.

So if I understand correctly, when the user downloads the App and opens it, my MainActivity.Java and corresponding layout will launch. But I am only going to use this simply as a preferences screen. So once they open the App for the first time, the Broadcast Receiver should automatically start listening for the LOCATION setting to be turned on, correct? I also want the Broadcast Listener to remain listening, even after it receives the initial Broadcast (so that my onReceive still fires if they turn the LOCATION setting off, and then later they turn it ON again..

So (A) How does my code look thus far?
and (B) To accomplish what I just described, what would need to be added?
and (C) Running it throws this error when I turn the LOCATION setting ON.
..How can I fix it?:
java.lang.RuntimeException: Unable to start receiver com.bryce.projects.servicesthreadsetc.MyReceiver: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?


Thanks again for all the help!

解决方案

Since you don't need to actually get a Location, the best implementation for your needs would be a BroadcastReceiver.

This is the best option because you wouldn't need to have a Service running at all times (resulting in extra batter drain), and you would be able to start your Activity from the BroadcastReceiver.

With the intent filter and BroadcastReceiver, your app will be started by the OS whenever the Location setting has changed (enabled or disabled), and in the case that it is enabled, you can start your Activity from the BroadcastReceiver.

First add the intent filter, which will be captured when the OS sends out the implicit Intent that the setting has changed:

<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>

Then, in LocationProviderChangedReceiver.java, your implementation would be something like this:

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 App)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆