I am working on a service application to detect acceleration values greater than a treshold continuously.
Is it possible to keep reading acceleration values when the device (GEAR SPORT = wearable 3.0) is set to power save mode?
I have been searching for this but only found individual lines of code for HRM sensor reading, that I could not get to work for my purpose.
I am beginner with tizen native implementation, so I would be very grateful for any help.
Here's my code so far:
#include <tizen.h> // standard header from the template
#include <service_app.h> // standard header from the template
#include "accelerationservice.h" // a header automatically created along with the template
// headers that will be needed for our service:
#include <sensor.h>
#include <player.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlog.h> // for logging purposes
#include <device/haptic.h>
static void device_vibrate(int duration, int feedback) {
haptic_device_h haptic_handle;
haptic_effect_h effect_handle;
if(device_haptic_open(0, &haptic_handle) == DEVICE_ERROR_NONE) {
dlog_print(DLOG_INFO, LOG_TAG, "Connection to vibrator established");
if(device_haptic_vibrate(haptic_handle, duration, feedback, &effect_handle) == DEVICE_ERROR_NONE) {
dlog_print(DLOG_INFO, LOG_TAG, "Device vibrates!");
}
// To stop vibration which are being played use below code with proper handles
//if(device_haptic_stop(haptic_handle, effect_handle) == DEVICE_ERROR_NONE) {
// dlog_print(DLOG_INFO, LOG_TAG, "Device vibration stopped");
//}
// When you decided not to use haptic anymore disconnect it
//if(device_haptic_close(haptic_handle) == DEVICE_ERROR_NONE) {
// dlog_print(DLOG_INFO, LOG_TAG, "Vibrator disconnected");
//}
}
}
// some constant values used in the app
#define MAX_PATH_SIZE 4096 // max file path size
#define ACCELEROMETER_SHAKE_THRESHOLD_VALUE 15 // the value read on any accelerometer axis to be considered the shake event
// application data (context) that will be passed to functions when needed
typedef struct appdata
{
sensor_h sensor; // sensor handle
sensor_listener_h listener; // sensor listener handle
char sound_path[MAX_PATH_SIZE]; // a path to a sound file that is used as an alarm
} appdata_s;
void playback_completed_cb(void *user_data)
{
// Extracting application data
appdata_s* ad = (appdata_s*)user_data;
dlog_print(DLOG_INFO, LOG_TAG, "Sound playback completed.");
if (sensor_listener_start(ad->listener) == SENSOR_ERROR_NONE)
{
dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener started again.");
}
}
//sensor event callback implementation
void sensor_event_callback(sensor_h sensor, sensor_event_s *event, void *user_data)
{
// Extracting application data
appdata_s* ad = (appdata_s*)user_data;
sensor_type_e type = SENSOR_ALL;
if((sensor_get_type(sensor, &type) == SENSOR_ERROR_NONE) && type == SENSOR_ACCELEROMETER)
{
int h0 = event->values[0];
int h1 = event->values[1];
int h2 = event->values[2];
dlog_print(DLOG_INFO, LOG_TAG, "0, %i", h0);
dlog_print(DLOG_INFO, LOG_TAG, "1, %i", h1);
dlog_print(DLOG_INFO, LOG_TAG, "2, %i", h2);
if (event->values[0] >= ACCELEROMETER_SHAKE_THRESHOLD_VALUE
|| event->values[1] >= ACCELEROMETER_SHAKE_THRESHOLD_VALUE
|| event->values[2] >= ACCELEROMETER_SHAKE_THRESHOLD_VALUE
|| event->values[0] <= -ACCELEROMETER_SHAKE_THRESHOLD_VALUE
|| event->values[1] <= -ACCELEROMETER_SHAKE_THRESHOLD_VALUE
|| event->values[2] <= -ACCELEROMETER_SHAKE_THRESHOLD_VALUE)
{
dlog_print(DLOG_INFO, LOG_TAG, "Event occurred!");
//vibrate
dlog_print(DLOG_INFO, LOG_TAG, "Vibrator method called!");
device_vibrate(1000,100);
// We stop the sensor listener, because until the sound playback
// is finished we don't need to monitor sensors.
if (sensor_listener_stop(ad->listener) == SENSOR_ERROR_NONE)
{
dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener temporarily stopped!");
}
else
{
dlog_print(DLOG_INFO, LOG_TAG, "Something went wrong! Sensor listener could not be stopped!");
}
dlog_print(DLOG_INFO, LOG_TAG, "after Sensorlistener stopped!!!");
if (sensor_listener_start(ad->listener) == SENSOR_ERROR_NONE)
{
dlog_print(DLOG_INFO, LOG_TAG, "Sensor restarted.");
}
else
{
dlog_print(DLOG_ERROR, LOG_TAG, "Restarting sensor failed!");
}
}
}
}
bool service_app_create(void *data)
{
// Extracting application data
appdata_s* ad = (appdata_s*)data;
dlog_print(DLOG_INFO, LOG_TAG, "Starting sensor service...");
bool sensor_supported = false;
if (sensor_is_supported(SENSOR_ACCELEROMETER, &sensor_supported) != SENSOR_ERROR_NONE || sensor_supported == false)
{
dlog_print(DLOG_ERROR, LOG_TAG, "Accelerometer not supported! Service is useless, exiting...");
service_app_exit();
return false;
}
// Preparing and starting the sensor listener for the accelerometer.
if (sensor_get_default_sensor(SENSOR_ACCELEROMETER, &(ad->sensor)) == SENSOR_ERROR_NONE)
{
if (sensor_create_listener(ad->sensor, &(ad->listener)) == SENSOR_ERROR_NONE
&& sensor_listener_set_event_cb(ad->listener, 200, sensor_event_callback, ad) == SENSOR_ERROR_NONE
&& sensor_listener_set_option(ad->listener, SENSOR_OPTION_ALWAYS_ON) == SENSOR_ERROR_NONE)
{
if (sensor_listener_start(ad->listener) == SENSOR_ERROR_NONE)
{
dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener started.");
}
}
}
return true;
}
void service_app_terminate(void *data)
{
// Extracting application data
appdata_s* ad = (appdata_s*)data;
//Stopping & destroying sensor listener
if ((sensor_listener_stop(ad->listener) == SENSOR_ERROR_NONE)
&& (sensor_destroy_listener(ad->listener) == SENSOR_ERROR_NONE))
{
dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener destroyed.");
}
else
{
dlog_print(DLOG_INFO, LOG_TAG, "Error occurred when destroying sensor listener or a sensor listener was never created!");
}
}
void service_app_control(app_control_h app_control, void *data)
{
dlog_print(DLOG_INFO, LOG_TAG, "Service app control has been called");
return;
}
static void service_app_lang_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LANGUAGE_CHANGED*/
return;
}
static void service_app_region_changed(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_REGION_FORMAT_CHANGED*/
}
static void service_app_low_battery(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LOW_BATTERY*/
}
static void service_app_low_memory(app_event_info_h event_info, void *user_data)
{
/*APP_EVENT_LOW_MEMORY*/
}
int main(int argc, char* argv[])
{
// we declare application data as a structure defined earlier
appdata_s ad = {0,};
service_app_lifecycle_callback_s event_callback = {0,};
app_event_handler_h handlers[5] = {NULL, };
event_callback.create = service_app_create;
event_callback.terminate = service_app_terminate;
event_callback.app_control = service_app_control; //we will not use this one yet
service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);
// we keep a template code above and then modify the line below
return service_app_main(argc, argv, &event_callback, &ad);
}