-
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bfe34fc
Showing
13 changed files
with
404 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
LOCAL_PATH := $(call my-dir) | ||
include $(CLEAR_VARS) | ||
|
||
LOCAL_MODULE := UnifiedNlpApi | ||
LOCAL_SRC_FILES := $(call all-java-files-under, src) | ||
LOCAL_SRC_FILES += src/org/microg/nlp/api/LocationBackend.aidl \ | ||
src/org/microg/nlp/api/GeocoderBackend.aidl \ | ||
src/org/microg/nlp/api/LocationCallback.aidl | ||
|
||
include $(BUILD_STATIC_JAVA_LIBRARY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest package="org.microg.nlp.api"> | ||
<!-- This is not needed, it's just here to stop build systems from complaining --> | ||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
UnifiedNlpApi | ||
============= | ||
This library contains anything needed to build a backend for UnifiedNlp. | ||
|
||
Writing the service | ||
------------------- | ||
### The easy way (Location) | ||
Writing a service is fairly easy. Just create a class that extends `org.microg.nlp.api.LocationBackendService`, it provides several methods: | ||
|
||
#### `update()`-method | ||
You'll most likely want to override this method. It is called every time when an application requests a location. | ||
|
||
However, as this method is blocking, you should not do heavy I/O operations (like network) in it. | ||
If your backend uses a remote provider for location retrieval, do requests in an additional thread and return null in `update()`. | ||
On request success, use `report()` to send the new location to the requesting application. | ||
|
||
See JavaDoc for additional information. | ||
|
||
#### `onOpen()`-method and `onClose()`-method | ||
These might be interesting to override too. `onOpen()` is called after UnifiedNlp connected to this backend and `onClose()` is called before connection closure. | ||
This is a good place to initialize or respectively destroy whatever you need during `update()` calls. | ||
|
||
#### `report(Location)`-method | ||
You can call this method every time to report the given location as soon as possible. | ||
|
||
### The easy way (Geocoding) | ||
Providing a Geocoder is even simpler than a LocationProvider. Extend `org.microg.nlp.api.GeocoderBackendService` and implement the methods `getFromLocation` and `getFromLocationName`. | ||
Both methods reflect a call to the corresponding method in `android.location.Geocoder`. | ||
|
||
### The flexible way | ||
Instead of using the `LocationBackendService` helper class you can do it by hand. | ||
It's important that your service overrides the `onBind()` method and responds with a `Binder` to the `LocationBackend` interface. | ||
|
||
Advertise your service | ||
---------------------- | ||
To let UnifiedNlp see your service you need to advertise it by providing the `org.microg.nlp.LOCATION_BACKEND` action. | ||
|
||
For security reasons, you should add an `android:permission` restriction to `android.permission.ACCESS_COARSE_LOCATION`. This ensures only application with access to coarse locations will be able to connect to your service. | ||
|
||
You may want to set `android:icon` and `android:label` to something reasonable, else your applications icon/label are used. | ||
If your backend has settings you can advertise it's activity using the `org.microg.nlp.BACKEND_SETTINGS_ACTIVITY` meta-data so that it is callable from the UnifiedNlp settings. | ||
|
||
A service entry for a backend service could be: | ||
|
||
<service | ||
android:name=".SampleService" | ||
android:exported="true" | ||
android:permission="android.permission.ACCESS_COARSE_LOCATION" | ||
android:label="A very nice Backend"> | ||
<intent-filter> | ||
<action android:name="org.microg.nlp.LOCATION_BACKEND" /> | ||
</intent-filter> | ||
<meta-data | ||
android:name="org.microg.nlp.BACKEND_SETTINGS_ACTIVITY" | ||
android:value="org.microg.nlp.api.sample.SampleActivity" /> | ||
</service> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
buildscript { | ||
repositories { | ||
mavenCentral() | ||
} | ||
dependencies { | ||
classpath 'com.android.tools.build:gradle:1.0.0' | ||
} | ||
} | ||
|
||
apply plugin: 'com.android.library' | ||
|
||
android { | ||
compileSdkVersion 21 | ||
buildToolsVersion "21.0.2" | ||
lintOptions.abortOnError false | ||
|
||
sourceSets { | ||
main { | ||
manifest.srcFile 'AndroidManifest.xml' | ||
java.srcDirs = ['src'] | ||
aidl.srcDirs = ['src'] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
android.library=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package org.microg.nlp.api; | ||
|
||
import android.app.Service; | ||
import android.content.Intent; | ||
import android.os.IBinder; | ||
|
||
public abstract class AbstractBackendService extends Service { | ||
|
||
@Override | ||
public IBinder onBind(Intent intent) { | ||
return getBackend(); | ||
} | ||
|
||
/** | ||
* Called after a connection was setup | ||
*/ | ||
protected void onOpen() { | ||
|
||
} | ||
|
||
/** | ||
* Called before connection closure | ||
*/ | ||
protected void onClose() { | ||
|
||
} | ||
|
||
protected abstract IBinder getBackend(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.microg.nlp.api; | ||
|
||
import android.location.Location; | ||
import android.location.Address; | ||
|
||
interface GeocoderBackend { | ||
void open(); | ||
List<Address> getFromLocation(double latitude, double longitude, int maxResults, String locale); | ||
List<Address> getFromLocationName(String locationName, int maxResults, double lowerLeftLatitude, | ||
double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude, | ||
String locale); | ||
void close(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package org.microg.nlp.api; | ||
|
||
import android.location.Address; | ||
import android.os.IBinder; | ||
import android.os.RemoteException; | ||
|
||
import java.util.List; | ||
|
||
public abstract class GeocoderBackendService extends AbstractBackendService { | ||
|
||
private Backend backend = new Backend(); | ||
|
||
@Override | ||
protected IBinder getBackend() { | ||
return backend; | ||
} | ||
|
||
/** | ||
* @param locale The locale, formatted as a String with underscore (eg. en_US) the resulting | ||
* address should be localized in | ||
* @see android.location.Geocoder#getFromLocation(double, double, int) | ||
*/ | ||
protected abstract List<Address> getFromLocation(double latitude, double longitude, | ||
int maxResults, String locale); | ||
|
||
/** | ||
* @param locale The locale, formatted as a String with underscore (eg. en_US) the resulting | ||
* address should be localized in | ||
* @see android.location.Geocoder#getFromLocationName(String, int, double, double, double, double) | ||
*/ | ||
protected abstract List<Address> getFromLocationName(String locationName, int maxResults, | ||
double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, | ||
double upperRightLongitude, String locale); | ||
|
||
private class Backend extends GeocoderBackend.Stub { | ||
|
||
@Override | ||
public void open() throws RemoteException { | ||
onOpen(); | ||
} | ||
|
||
@Override | ||
public List<Address> getFromLocation(double latitude, double longitude, int maxResults, | ||
String locale) throws RemoteException { | ||
return GeocoderBackendService.this | ||
.getFromLocation(latitude, longitude, maxResults, locale); | ||
} | ||
|
||
@Override | ||
public List<Address> getFromLocationName(String locationName, int maxResults, | ||
double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, | ||
double upperRightLongitude, String locale) throws RemoteException { | ||
return GeocoderBackendService.this | ||
.getFromLocationName(locationName, maxResults, lowerLeftLatitude, | ||
lowerLeftLongitude, upperRightLatitude, upperRightLongitude, locale); | ||
} | ||
|
||
@Override | ||
public void close() throws RemoteException { | ||
onClose(); | ||
backend = null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.microg.nlp.api; | ||
|
||
import org.microg.nlp.api.LocationCallback; | ||
import android.location.Location; | ||
|
||
interface LocationBackend { | ||
void open(LocationCallback callback); | ||
Location update(); | ||
void close(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package org.microg.nlp.api; | ||
|
||
import android.location.Location; | ||
import android.os.IBinder; | ||
import android.os.RemoteException; | ||
|
||
public abstract class LocationBackendService extends AbstractBackendService { | ||
|
||
private Backend backend = new Backend(); | ||
private LocationCallback callback; | ||
private Location waiting; | ||
|
||
/** | ||
* Called, whenever an app requires a location update. This can be a single or a repeated request. | ||
* <p/> | ||
* You may return null if your backend has no newer location available then the last one. | ||
* Do not send the same {@link android.location.Location} twice, if it's not based on updated/refreshed data. | ||
* <p/> | ||
* You can completely ignore this method (means returning null) if you use {@link #report(android.location.Location)}. | ||
* | ||
* @return a new {@link android.location.Location} instance or null if not available. | ||
*/ | ||
protected Location update() { | ||
return null; | ||
} | ||
|
||
/** | ||
* Directly report a {@link android.location.Location} to the requesting apps. Use this if your updates are based | ||
* on environment changes (eg. cell id change). | ||
* | ||
* @param location the new {@link android.location.Location} instance to be send | ||
*/ | ||
public void report(Location location) { | ||
if (callback != null) { | ||
try { | ||
callback.report(location); | ||
} catch (android.os.DeadObjectException e) { | ||
waiting = location; | ||
callback = null; | ||
} catch (RemoteException e) { | ||
waiting = location; | ||
} | ||
} else { | ||
waiting = location; | ||
} | ||
} | ||
|
||
/** | ||
* @return true if we're an actively connected backend, false if not | ||
*/ | ||
public boolean isConnected() { | ||
return callback != null; | ||
} | ||
|
||
@Override | ||
protected IBinder getBackend() { | ||
return backend; | ||
} | ||
|
||
private class Backend extends LocationBackend.Stub { | ||
@Override | ||
public void open(LocationCallback callback) throws RemoteException { | ||
LocationBackendService.this.callback = callback; | ||
if (waiting != null) { | ||
callback.report(waiting); | ||
waiting = null; | ||
} | ||
onOpen(); | ||
} | ||
|
||
@Override | ||
public Location update() throws RemoteException { | ||
return LocationBackendService.this.update(); | ||
} | ||
|
||
@Override | ||
public void close() throws RemoteException { | ||
onClose(); | ||
callback = null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.microg.nlp.api; | ||
|
||
import android.location.Location; | ||
|
||
interface LocationCallback { | ||
void report(in Location location); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package org.microg.nlp.api; | ||
|
||
import android.location.Location; | ||
import android.os.Bundle; | ||
|
||
import java.util.Collection; | ||
|
||
public final class LocationHelper { | ||
private LocationHelper() { | ||
} | ||
|
||
public static Location create(String source) { | ||
return new Location(source); | ||
} | ||
|
||
public static Location create(String source, double latitude, double longitude, | ||
float accuracy) { | ||
Location location = create(source); | ||
location.setLatitude(latitude); | ||
location.setLongitude(longitude); | ||
location.setAccuracy(accuracy); | ||
return location; | ||
} | ||
|
||
public static Location create(String source, double latitude, double longitude, float altitude, | ||
Bundle extras) { | ||
Location location = create(source, latitude, longitude, altitude); | ||
location.setExtras(extras); | ||
return location; | ||
} | ||
|
||
public static Location create(String source, double latitude, double longitude, double altitude, | ||
float accuracy) { | ||
Location location = create(source, latitude, longitude, accuracy); | ||
location.setAltitude(altitude); | ||
return location; | ||
} | ||
|
||
public static Location create(String source, double latitude, double longitude, double altitude, | ||
float accuracy, Bundle extras) { | ||
Location location = create(source, latitude, longitude, altitude, accuracy); | ||
location.setExtras(extras); | ||
return location; | ||
} | ||
|
||
public static Location create(String source, long time) { | ||
Location location = create(source); | ||
location.setTime(time); | ||
return location; | ||
} | ||
|
||
public static Location create(String source, long time, Bundle extras) { | ||
Location location = create(source, time); | ||
location.setExtras(extras); | ||
return location; | ||
} | ||
|
||
public static Location average(String source, Collection<Location> locations) { | ||
if (locations == null || locations.size() == 0) { | ||
return null; | ||
} | ||
int num = locations.size(); | ||
double latitude = 0; | ||
double longitude = 0; | ||
float accuracy = 0; | ||
int altitudes = 0; | ||
double altitude = 0; | ||
for (Location value : locations) { | ||
if (value != null) { | ||
latitude += value.getLatitude(); | ||
longitude += value.getLongitude(); | ||
accuracy += value.getAccuracy(); | ||
if (value.hasAltitude()) { | ||
altitude += value.getAltitude(); | ||
altitudes++; | ||
} | ||
} | ||
} | ||
Bundle extras = new Bundle(); | ||
extras.putInt("AVERAGED_OF", num); | ||
if (altitudes > 0) { | ||
return create(source, latitude / num, longitude / num, altitude / altitudes, | ||
accuracy / num, extras); | ||
} else { | ||
return create(source, latitude / num, longitude / num, accuracy / num, extras); | ||
} | ||
} | ||
} |
Oops, something went wrong.