You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
implement LocationManager and orientation sensor using libportal
This commit is contained in:
@@ -82,11 +82,12 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
|
|||||||
'src/api-impl-jni/android_graphics_Bitmap.c',
|
'src/api-impl-jni/android_graphics_Bitmap.c',
|
||||||
'src/api-impl-jni/android_app_NativeActivity.c',
|
'src/api-impl-jni/android_app_NativeActivity.c',
|
||||||
'src/api-impl-jni/android_opengl_GLES20.c',
|
'src/api-impl-jni/android_opengl_GLES20.c',
|
||||||
|
'src/api-impl-jni/location/android_location_LocationManager.c',
|
||||||
] + marshal_files,
|
] + marshal_files,
|
||||||
install: true,
|
install: true,
|
||||||
install_dir : get_option('libdir') / 'java/dex/android_translation_layer/natives',
|
install_dir : get_option('libdir') / 'java/dex/android_translation_layer/natives',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('gtk4'), dependency('gl'), dependency('egl'), dependency('wayland-client'), dependency('jni')
|
dependency('gtk4'), dependency('gl'), dependency('egl'), dependency('wayland-client'), dependency('jni'), dependency('libportal')
|
||||||
],
|
],
|
||||||
link_with: [ libandroid_so ],
|
link_with: [ libandroid_so ],
|
||||||
link_args: [
|
link_args: [
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class android_location_LocationManager */
|
||||||
|
|
||||||
|
#ifndef _Included_android_location_LocationManager
|
||||||
|
#define _Included_android_location_LocationManager
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Class: android_location_LocationManager
|
||||||
|
* Method: nativeGetLocation
|
||||||
|
* Signature: ()V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_android_location_LocationManager_nativeGetLocation
|
||||||
|
(JNIEnv *, jobject);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
35
src/api-impl-jni/location/android_location_LocationManager.c
Normal file
35
src/api-impl-jni/location/android_location_LocationManager.c
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#include <libportal/portal.h>
|
||||||
|
|
||||||
|
#include "../defines.h"
|
||||||
|
#include "../generated_headers/android_location_LocationManager.h"
|
||||||
|
|
||||||
|
static void location_updated (
|
||||||
|
XdpPortal* self,
|
||||||
|
gdouble latitude,
|
||||||
|
gdouble longitude,
|
||||||
|
gdouble altitude,
|
||||||
|
gdouble accuracy,
|
||||||
|
gdouble speed,
|
||||||
|
gdouble heading,
|
||||||
|
gchar* description,
|
||||||
|
gint64 timestamp_s,
|
||||||
|
gint64 timestamp_ms,
|
||||||
|
JavaVM *jvm
|
||||||
|
) {
|
||||||
|
JNIEnv *env;
|
||||||
|
(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6);
|
||||||
|
jclass class = (*env)->FindClass(env, "android/location/LocationManager");
|
||||||
|
(*env)->CallStaticVoidMethod(env, class, _STATIC_METHOD(class, "locationUpdated", "(DDD)V"), latitude, longitude, heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
static XdpPortal *portal = NULL;
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_android_location_LocationManager_nativeGetLocation(JNIEnv *env, jobject) {
|
||||||
|
if (!portal) {
|
||||||
|
portal = xdp_portal_new();
|
||||||
|
JavaVM *jvm;
|
||||||
|
(*env)->GetJavaVM(env, &jvm);
|
||||||
|
g_signal_connect(portal, "location-updated", G_CALLBACK(location_updated), jvm);
|
||||||
|
}
|
||||||
|
xdp_portal_location_monitor_start (portal, NULL, 0, 0, XDP_LOCATION_ACCURACY_EXACT, XDP_LOCATION_MONITOR_FLAG_NONE, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import android.hardware.input.InputManager;
|
|||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
|
import android.location.LocationManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.MediaRouter;
|
import android.media.MediaRouter;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
@@ -131,6 +132,8 @@ public class Context extends Object {
|
|||||||
return new AlarmManager();
|
return new AlarmManager();
|
||||||
case "input":
|
case "input":
|
||||||
return new InputManager();
|
return new InputManager();
|
||||||
|
case "location":
|
||||||
|
return new LocationManager();
|
||||||
default:
|
default:
|
||||||
System.out.println("!!!!!!! getSystemService: case >" + name + "< is not implemented yet");
|
System.out.println("!!!!!!! getSystemService: case >" + name + "< is not implemented yet");
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -327,7 +327,8 @@ public final class Sensor {
|
|||||||
private int mFifoReservedEventCount;
|
private int mFifoReservedEventCount;
|
||||||
private int mFifoMaxEventCount;
|
private int mFifoMaxEventCount;
|
||||||
|
|
||||||
Sensor() {
|
Sensor(int type) {
|
||||||
|
mType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
11
src/api-impl/android/hardware/SensorEvent.java
Normal file
11
src/api-impl/android/hardware/SensorEvent.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package android.hardware;
|
||||||
|
|
||||||
|
public class SensorEvent {
|
||||||
|
|
||||||
|
public final float[] values;
|
||||||
|
|
||||||
|
public SensorEvent(float[] values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
package android.hardware;
|
package android.hardware;
|
||||||
|
|
||||||
public interface SensorEventListener {
|
public interface SensorEventListener {
|
||||||
|
|
||||||
|
public void onSensorChanged(SensorEvent event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,31 @@
|
|||||||
package android.hardware;
|
package android.hardware;
|
||||||
|
|
||||||
|
import android.location.Location;
|
||||||
|
import android.location.LocationListener;
|
||||||
|
import android.location.LocationManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
||||||
public class SensorManager {
|
public class SensorManager {
|
||||||
public Sensor getDefaultSensor(int type) {
|
public Sensor getDefaultSensor(int type) {
|
||||||
return null;
|
return new Sensor(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs, Handler handler) {
|
public boolean registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs, Handler handler) {
|
||||||
return true; // we could try saying that the sensor doesn't exist and hope the app just doesn't use it then, but as long as we never call the handler the app should leave this alone
|
return true; // we could try saying that the sensor doesn't exist and hope the app just doesn't use it then, but as long as we never call the handler the app should leave this alone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean registerListener(final SensorEventListener listener, Sensor sensor, int samplingPeriodUs) {
|
||||||
|
switch(sensor.getType()) {
|
||||||
|
case Sensor.TYPE_ORIENTATION:
|
||||||
|
new LocationManager().requestLocationUpdates(null, 0, 0, new LocationListener() {
|
||||||
|
@Override
|
||||||
|
public void onLocationChanged(Location location) {
|
||||||
|
listener.onSensorChanged(new SensorEvent(new float[]{(float)location.getBearing()}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,12 @@ public class Criteria {
|
|||||||
public static final int ACCURACY_HIGH = 3;
|
public static final int ACCURACY_HIGH = 3;
|
||||||
|
|
||||||
public void setAccuracy(int accuracy) {}
|
public void setAccuracy(int accuracy) {}
|
||||||
|
|
||||||
|
public void setAltitudeRequired(boolean required) {}
|
||||||
|
|
||||||
|
public void setBearingRequired(boolean required) {}
|
||||||
|
|
||||||
|
public void setCostAllowed(boolean allowed) {}
|
||||||
|
|
||||||
|
public void setPowerRequirement(int powerRequirement) {}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/api-impl/android/location/Location.java
Normal file
27
src/api-impl/android/location/Location.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package android.location;
|
||||||
|
|
||||||
|
public class Location {
|
||||||
|
|
||||||
|
private double latitude;
|
||||||
|
private double longitude;
|
||||||
|
private double bearing;
|
||||||
|
|
||||||
|
public Location (double latitude, double longitude, double bearing) {
|
||||||
|
this.latitude = latitude;
|
||||||
|
this.longitude = longitude;
|
||||||
|
this.bearing = bearing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBearing() {
|
||||||
|
return bearing;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
package android.location;
|
package android.location;
|
||||||
|
|
||||||
public interface LocationListener {
|
public interface LocationListener {
|
||||||
|
|
||||||
|
public void onLocationChanged(Location location);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/api-impl/android/location/LocationManager.java
Normal file
31
src/api-impl/android/location/LocationManager.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package android.location;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class LocationManager {
|
||||||
|
|
||||||
|
static Set<LocationListener> listeners = new HashSet<>();
|
||||||
|
|
||||||
|
public String getBestProvider(Criteria criteria, boolean enabledOnly) {
|
||||||
|
return "xdgportal";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLastKnownLocation(String provider) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestLocationUpdates (String provider, long minTimeMs, float minDistanceM, LocationListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
nativeGetLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void nativeGetLocation();
|
||||||
|
|
||||||
|
private static void locationUpdated(double latitude, double longitude, double heading) {
|
||||||
|
for (LocationListener locationListener : listeners) {
|
||||||
|
locationListener.onLocationChanged(new Location(latitude, longitude, heading));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -98,12 +98,15 @@ hax_jar = jar('hax', [
|
|||||||
'android/graphics/drawable/Drawable.java',
|
'android/graphics/drawable/Drawable.java',
|
||||||
'android/hardware/display/DisplayManager.java',
|
'android/hardware/display/DisplayManager.java',
|
||||||
'android/hardware/input/InputManager.java',
|
'android/hardware/input/InputManager.java',
|
||||||
|
'android/hardware/SensorEvent.java',
|
||||||
'android/hardware/SensorEventListener.java',
|
'android/hardware/SensorEventListener.java',
|
||||||
'android/hardware/Sensor.java',
|
'android/hardware/Sensor.java',
|
||||||
'android/hardware/SensorManager.java',
|
'android/hardware/SensorManager.java',
|
||||||
'android/hardware/usb/UsbManager.java',
|
'android/hardware/usb/UsbManager.java',
|
||||||
'android/location/Criteria.java',
|
'android/location/Criteria.java',
|
||||||
|
'android/location/Location.java',
|
||||||
'android/location/LocationListener.java',
|
'android/location/LocationListener.java',
|
||||||
|
'android/location/LocationManager.java',
|
||||||
'android/Manifest.java',
|
'android/Manifest.java',
|
||||||
'android/media/AudioManager.java',
|
'android/media/AudioManager.java',
|
||||||
'android/media/AudioTrack.java',
|
'android/media/AudioTrack.java',
|
||||||
|
|||||||
Reference in New Issue
Block a user