2013-04-09 7 views
9

Ich möchte eine Benachrichtigung erhalten, wenn der Benutzer Netzwerk- oder GPS-Standorte aktiviert oder deaktiviert, und vor allem möchte ich wissen, welche und wie sie geändert haben. Ich habe einen Rundfunkempfänger für die Sendeabsicht android.location.PROVIDERS_CHANGED und empfängt die richtige Sendung.Ist es möglich, eine Benachrichtigung zu erhalten, wenn ein Standortanbieter aktiviert/deaktiviert ist, und festzustellen, welche Aktion stattgefunden hat?

Ich muss jetzt versuchen zu bestimmen, welche Aktion aufgetreten ist, d. H. Aktivieren oder deaktivieren und welcher Provider wurde geändert. Ich weiß, dass ich den Status jedes Anbieters behalten kann. Wenn ich dann eine Benachrichtigung erhalten habe, dass sie sich geändert haben, dann könnte ich herausfinden, was sich geändert hat. Ich suche nach einer "Standard" -Methode, dies zu tun. Die Übertragungsabsicht scheint keine Extras zu enthalten, um anzuzeigen, welcher Anbieter sich geändert hat.

Dies ist der Code, den ich derzeit habe.

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

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) 
     { 
     Log.i(TAG,"Location Providers changed"); 
     Bundle bundle = intent.getExtras(); 
     if (bundle == null) { 
      Log.d(TAG, "No extras data"); 
     } else { 
      Log.d(TAG, "Bundle received of size " + bundle.size); 
     } 
     } 
    } 
    } 

Und das ist ein kleiner Auszug aus meinem Manifest

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

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

Das wäre perfekt, wenn es eine zusätzliche innerhalb der Sendung war, die die Provider angegeben hatte sich verändert und ob sie aktiviert oder deaktiviert. Leider ist dies nicht der Fall. Kennt jemand irgendeinen Mechanismus, durch den ich feststellen kann, welcher Zustand sich geändert hat, ohne meine eigenen Zustandsvariablen beizubehalten?

In einer idealen Welt würde ich ständig auf Änderungen überwachen, aber nur gelegentlich auf Standortänderungen hören. Ich möchte vermeiden, ständig auf Standortänderungen zu überwachen.

Antwort

4

Ich hoffe, dass dies nicht Ihre Forderung nicht widerspricht

Ich weiß, dass ich den Zustand der einzelnen Anbieter halten konnte und dann, wenn ich Benachrichtigung erhalten , dass sie sich geändert haben, dann könnte ich herausfinden, was hat geändert, suche ich nach einer "Standard" -Methode, dies zu tun.

... aber ich wäre der beste, „Standard“ denke, und flexibelste Weg, dies zu tun, Ihre LocationProviderChangedReceiver implementieren die LocationListener Schnittstelle zu lassen und dann implementieren onProviderEnabled() und onProviderDisabled() wie so:

public void onProviderEnabled(String provider) { 
    if(provider.equals(LocationManager.GPS_PROVIDER)){ 
    ... 
    } else if (provider.equals(LocationManager.NETWORK_PROVIDER)){ 
    ... 
    } 
} 

Beachten Sie, dass Sie die Berechtigung ACCESS_FINE_LOCATION zu Ihrem Manifest hinzufügen sollten, falls dies noch nicht geschehen ist. Auch andere Anbieter (außer "Netzwerk" und "GPS") können sich je nach Kontext bewerben, wie PASSIVE_PROVIDER oder sogar FUSED_PROVIDER.

Aktualisiert Antwort:
Wenn für die Lage ändert sich ständig zu hören ist keine Option für Sie, auch die LocationManager weiß which provider is currently enabled:

LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

..., so dass Sie diese Prüfungen zusammen mit Ihrem BroadcastReceiver verwenden könnte um zu vermeiden, dass aktivierte/deaktivierte Flags manuell gehalten werden. Darüber hinaus gibt es eine Absicht namens android.location.GPS_ENABLED_CHANGE, die Sie versuchen könnten, auch zu empfangen (und zu verarbeiten). Aber da diese Absicht in der offiziellen Dokumentation versteckt ist, ist es möglicherweise nicht sicher, sie zu verwenden, wie in this answer erwähnt.

Noch ein anderer Ansatz:
Android-Standardeinstellungen Widget umschalten (Sie wissen schon, was ich meine) zeigt die GPS/deaktivierten Zustand aktiviert durch Absicht der android.location.PROVIDERS_CHANGED abonnieren (wie Sie) eine Anfrage des GPS-Zustand auslösen über die Benutzereinstellungen:

@Override 
public int getActualState(Context context) { 
    ContentResolver resolver = context.getContentResolver(); 
    boolean on = Settings.Secure.isLocationProviderEnabled(
       resolver, LocationManager.GPS_PROVIDER); 
    return on ? STATE_ENABLED : STATE_DISABLED; 
} 

(vom official sources).
Sie könnten diesen Ansatz auch für andere Standortanbieter anpassen.

+0

Sorry, um die Frage zu ändern, und die Anforderungen, nachdem Sie beantwortet haben, aber ich suchte nach einer Möglichkeit, dies zu überwachen, ohne auf Standorte zu hören. Ich ersuche zwar an verschiedenen Stellen die Aktualisierung des Standorts, aber ich wollte Änderungen an den Providern ständig überwachen, ohne ständig auf Standorte zu warten. –

+0

Ok, in diesem Fall könnte der 'LocationManager' auch helfen. Ich habe meine Antwort aktualisiert. – saschoar

0

Auf dem Receiver können Sie einfach überprüfen, welche Provider aktiviert sind:

LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE) 
List<String> providers = lm.getProviders(true); 

Auf diese Weise können alle Anbieter ermöglichen erhalten.

5

Dies funktioniert für mich:

Add Empfänger auf die Manifest-Datei:

<receiver 
     android:name="com.eegeo.location.LocationProviderChangedReceiver"> 
     <intent-filter> 
      <action android:name="android.location.PROVIDERS_CHANGED" /> 
     </intent-filter> 
    </receiver> 

prüfen beide Standort-Anbieter in Empfänger:

public class LocationProviderChangedReceiver extends BroadcastReceiver{ 

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

     boolean anyLocationProv = false; 
     LocationManager locationManager = (LocationManager) MyMainActivity.context.getSystemService(Context.LOCATION_SERVICE); 

     anyLocationProv |= locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     anyLocationProv |= locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

     Log.i("", "Location service status" + anyLocationProv); 


    } 

} 

Obwohl dieser Empfänger mehr als einmal wegen genannt wird zu offensichtlichen Gründen, aber dies wird Ihnen den Status sagen.

0

Dank @usman Antwort können wir die Lösung ohne extends die Klasse auf die folgende Weise anwenden;

AndroidManifest.xml;

<receiver android:name="com.eegeo.location.LocationProviderChangedReceiver"> 
    <intent-filter> 
     <action android:name="android.location.PROVIDERS_CHANGED" /> 
    </intent-filter> 
</receiver> 

Klasse (ich habe nie getestet);

public class LocationProviderChangedReceiver { 

    private mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 
    private BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String ability = (isGPSProviderEnabled() && isNetworkProviderEnabled()) ? "CAN" : "CANNOT"; 
      Log.d("", "The location " + ability + " be caught in high accuracy!"); 
     } 
    }; 


    public startProviderChangeObserving() { 
     registerReceiver(mReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION)); 

    } 


    public stopProviderChangeObserving() { 
     unregisterReceiver(mReceiver); 
    } 


    /** 
    * Method to verify that the location providers wheter on or not on the device 
    **/ 
    public boolean isGPSProviderEnabled() { 
     return (Boolean) mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
    } 

    public boolean isNetworkProviderEnabled() { 
     return (Boolean) mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
    } 

}