- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我搜索了有关使用 NDK 更快地轮询加速度计的教程/答案,但尚未找到求解器。刚找到一个 androiddevelopers 文档 here .
我需要的是大约每秒 100 个样本 (100Hz) 的轮询加速,默认情况下我的设备(带有 Gingerbread 2.3.5 的三星 Galaxy SL i9003)默认 SENSOR_DELAY_FASTEST 每秒只能获得大约 60 个样本(60Hz)。因此,我尝试通过 NativeActivity 使用 NDK 访问传感器,方法是生成我尝试基于 sensor.h 和 looper.h 制作的 .c 文件:
#include <jni.h>
#include <string.h>
#include <android/sensor.h>
#include <android/log.h>
#include <android/looper.h>
#define TAG "accelerondk"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOOPER_ID 1
#define SAMP_PER_SEC 100 //i've changed to 120, even 10, but nothing happen
void Java_azka_web_ndk_AcceleroNDKActivity_startMonitoring(JNIEnv* env, jclass clazz) {
ASensorManager* sensorManager = ASensorManager_getInstance();
ALooper* looper = ALooper_forThread();
if(looper == NULL)
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ASensorRef accelerometerSensor = ASensorManager_getDefaultSensor(sensorManager,ASENSOR_TYPE_ACCELEROMETER);
LOGI("accelerometerSensor: %s, vendor: %s", ASensor_getName(accelerometerSensor), ASensor_getVendor(accelerometerSensor));
ASensorEventQueue* queue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID, NULL, NULL);
ASensorEventQueue_enableSensor(queue, accelerometerSensor);
ASensorEventQueue_setEventRate(queue, accelerometerSensor, (1000L/SAMP_PER_SEC)*1000);
int ident;//identifier
int events;
while (1) {
while ((ident=ALooper_pollAll(-1, NULL, &events, NULL) >= 0)) {
// If a sensor has data, process it now.
if (ident == LOOPER_ID) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(queue, &event, 1) > 0) {
LOGI("aaaaaaa accelerometer X = %f y = %f z=%f ", event.acceleration.x, event.acceleration.y, event.acceleration.z);
}
}
}
}
}
到目前为止,我已经能够使用 NativeActivity 访问加速度计,但采样数没有变化。即使我将 ASensorEventQueue_setEventRate 更改得足够大或足够小,加速度记录仍然约为每秒 60 个样本(每 15 毫秒 1 个样本)
我的代码有没有错误?还是我忘记带的东西?
提前致谢
最佳答案
我还对传感器的采样率进行了一些尝试。我使用 Galaxy Nexus。如果我只使用 Acc-Sensor 频率非常低(大约 40Hz),但是如果我使用 Acc-Sensor 加上磁传感器和陀螺仪传感器,每个传感器的采样率大约是 100Hz。我无法解释为什么会这样。另一个观察是传递给 ASensorEventQueue_setEventRate 的值没有效果。采样率始终相同。SDK 代码的行为完全相同。
这是我用于基准测试的代码:
#include <string.h>
#include <jni.h>
#include <android/sensor.h>
#include <android/looper.h>
#include <android/log.h>
#include <time.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "TestJNIActivity", __VA_ARGS__))
#define LOOPER_ID 1
#define SAMP_PER_SEC 100
ASensorEventQueue* sensorEventQueue;
int accCounter = 0;
int64_t lastAccTime = 0;
int gyroCounter = 0;
int64_t lastGyroTime = 0;
int magCounter = 0;
int64_t lastMagTime = 0;
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
*/
static int get_sensor_events(int fd, int events, void* data);
struct tm* start;
struct tm* finish;
jstring
Java_de_tum_ndktest_TestJNIActivity_stringFromJNI( JNIEnv* env, jobject thiz )
{
LOGI("stringFromJNI");
return (*env)->NewStringUTF(env,"Hello from JNI !");
}
void
Java_de_tum_ndktest_TestJNIActivity_sensorValue( JNIEnv* env, jobject thiz ) {
ASensorEvent event;
int events, ident;
ASensorManager* sensorManager;
const ASensor* accSensor;
const ASensor* gyroSensor;
const ASensor* magSensor;
void* sensor_data = malloc(1000);
LOGI("sensorValue() - ALooper_forThread()");
ALooper* looper = ALooper_forThread();
if(looper == NULL)
{
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
}
sensorManager = ASensorManager_getInstance();
accSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
gyroSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_GYROSCOPE);
magSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_MAGNETIC_FIELD);
sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, 3, get_sensor_events, sensor_data);
ASensorEventQueue_enableSensor(sensorEventQueue, accSensor);
ASensorEventQueue_enableSensor(sensorEventQueue, gyroSensor);
ASensorEventQueue_enableSensor(sensorEventQueue, magSensor);
//Sampling rate: 100Hz
int a = ASensor_getMinDelay(accSensor);
int b = ASensor_getMinDelay(gyroSensor);
int c = ASensor_getMinDelay(magSensor);
LOGI("min-delay: %d, %d, %d",a,b,c);
ASensorEventQueue_setEventRate(sensorEventQueue, accSensor, 100000);
ASensorEventQueue_setEventRate(sensorEventQueue, gyroSensor, 100000);
ASensorEventQueue_setEventRate(sensorEventQueue, magSensor, 100000);
LOGI("sensorValue() - START");
}
static int get_sensor_events(int fd, int events, void* data) {
ASensorEvent event;
//ASensorEventQueue* sensorEventQueue;
while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0) {
if(event.type == ASENSOR_TYPE_ACCELEROMETER) {
//LOGI("accl(x,y,z,t): %f %f %f %lld", event.acceleration.x, event.acceleration.y, event.acceleration.z, event.timestamp);
if(accCounter == 0 || accCounter == 1000)
{
LOGI("Acc-Time: %lld (%f)", event.timestamp,((double)(event.timestamp-lastAccTime))/1000000000.0);
lastAccTime = event.timestamp;
accCounter = 0;
}
accCounter++;
}
else if(event.type == ASENSOR_TYPE_GYROSCOPE) {
//LOGI("accl(x,y,z,t): %f %f %f %lld", event.acceleration.x, event.acceleration.y, event.acceleration.z, event.timestamp);
if(gyroCounter == 0 || gyroCounter == 1000)
{
LOGI("Gyro-Time: %lld (%f)", event.timestamp,((double)(event.timestamp-lastGyroTime))/1000000000.0);
lastGyroTime = event.timestamp;
gyroCounter = 0;
}
gyroCounter++;
}
else if(event.type == ASENSOR_TYPE_MAGNETIC_FIELD) {
//LOGI("accl(x,y,z,t): %f %f %f %lld", event.acceleration.x, event.acceleration.y, event.acceleration.z, event.timestamp);
if(magCounter == 0 || magCounter == 1000)
{
LOGI("Mag-Time: %lld (%f)", event.timestamp,((double)(event.timestamp-lastMagTime))/1000000000.0);
lastMagTime = event.timestamp;
magCounter = 0;
}
magCounter++;
}
}
//should return 1 to continue receiving callbacks, or 0 to unregister
return 1;
}
关于android - 通过 NativeActivity NDK 访问(更快的轮询)加速度计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8989686/
我有一个单独运行的 NativeActivity,我尝试添加一些 SDK(更准确地说是 Admob/Chartboost/Facebook)。 另一方面,只有当我们在参数中传递一个 Activity
Android NDK刚刚得到显着扩展,包括支持完全使用 native C/C++ 代码编写 Android 应用程序。现在可以使用 native 代码捕获键盘和触摸屏上的输入事件,还可以使用新的 N
在我的 Android 设备(使用 JellyBean 4.1.2)上有一个错误: 当我启动特定的 NativeActivity(从我的应用程序加载游戏的 libretroarch-activity)
有什么方法可以从 Execute 中看到 NativeActivity 的父事件的类型?方法 ? 最佳答案 是的,您可以执行以下代码块,它会返回内部的值 Parent属性(property)——这将是
我从 JavaActivity 调用 NativeActivity。我的 NativeActivity 的入口点是 android_main(struct android_app* state) 最
要使用 gdb 在 android 应用程序中调试 native 代码,首先我需要启动基于 sdk 的应用程序并在使用 native 代码加载库之前将其停止在断点处,之后我需要启动 gdb,依此类推.
我有一个原生android应用,那么入口main就是android_main。我的问题:是否可以使用 NativeActivity 生成另一个 Activity ?我必须只插入代码 java con
我正在将纯 C++ 游戏移植到 Android,由于我的目标是 Android 3.0+ 平板电脑,因此我选择使用 NativeActivity 以完全避免使用 Java。但是,我看不到任何允许我写入
环境…… 我有一个全新的 Visual Studio 2015 Android NDK 解决方案。这包含 2 个项目(由 visual studio 生成的默认模板代码): 原生 Activity 。
我正在 NativeActivity 上开发应用程序(仅限 C/C++)。 我想禁用屏幕超时。 你知道怎么做吗? 最佳答案 如果 OP 仍在寻找答案,或者像我这样的人在搜索时发现了这个主题,请按以下步
我有一个使用 NativeActivity 的应用程序。我想调用 Java 来做一些需要上下文的事情(例如,访问 TelephonyManager 以查询 IMEI)。 如何为我的 Activity
我在我的应用程序中使用键盘时遇到问题,该应用程序是一个纯 native 应用程序(基于 Android NDK 中提供的native-activity 示例)。 我有这段 Java 代码来显示键盘:
我尝试仅使用 C++ 将我的所有应用程序从 IOS 和 ANDROID 与 JAVA EGL 移植到 Android 设备上。 我刚刚遇到的一件事是“ fatal error :android_nat
我想要一个使用 NativeActivity 的真正的全屏 android 应用程序。我在 AndroidManifest.xml 中设置主题“Theme.Black.NoTitleBar.Fulls
有什么方法可以将我的源代码(包括所有 .h .cpp 和 .mk 文件)移出项目文件夹?换句话说,我想将 jni 文件夹的内容移出 android 项目文件夹。现在,我的项目的物理结构如下所示: ..
NativeActivity 是否可以访问 GestureDetector 并将事件绑定(bind)到它? 我认为这可能必须通过 JNI,很痛苦。 最佳答案 是的,您必须使用 JNIEnv 来访问 G
我正在使用带有 native_app_glue 的 NativeActivty 为 Android 编写一个 OpenGL 游戏。很难确定何时是删除堆分配对象和 OpenGL 分配对象的最佳时机。 在
有谁知道我在哪里可以找到用于 android NativeActivity 的所有 native c/c++ 方法和函数的列表。我似乎无法在 google/android 网站上的任何地方找到列表,过
我正在尝试在 NativeActivity 中使用自定义 C# 表达式 它可以很好地处理像 Condition = new CSharpValue("1 == 1") 这样的简单表达式 它不适用于这样
我有一个事件将操作安排到外部 API,然后只有在此外部 API 完成时才必须继续,这由事件指示。我目前使用 NativActitivy。 我的想法是设置一个书签,然后注册一个触发书签的事件处理程序。可
我是一名优秀的程序员,十分优秀!