javaandroidwear-osandroid-sensorsandroid-wear-2.0

Android wear OS retrieving stepcounter in background


I am trying to retrieve step counts from a smartwatch and push it to API. I was able to retrieve and push the data when I open the app. But once it is not activated, then it will not send any data. I am trying to use the android service to run the app in the background so that it will send the data continuously. I have given all the permissions and enabled them.

This is MainActivity.java

package com.example.stepcounter;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent; 
import android.os.Bundle;
public class MainActivity extends AppCompatActivity{
  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

 }
 protected void onResume() {
    super.onResume();
}
protected void onPause() {
    super.onPause();
}
protected void onDestroy() {
    super.onDestroy();
}

public void onPressStartService(View v){

    Intent intent = new Intent(this, MyService.class);

    startService(intent);
}
public void onPressStopService(View v){
    stopService(new Intent(getApplicationContext(), MyService.class));
 }
}
 

And this is MyService.java

package com.example.stepcounter;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.TextView;

import androidx.annotation.Nullable;

 import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;

public class MyService extends Service implements SensorEventListener {
 private SensorManager mSensorManager;
 private Sensor mSensor;
 private String HelloData;
 private TextView mTextView;
 private boolean isSensorPresent;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    mSensorManager = (SensorManager)this.getSystemService(Context.SENSOR_SERVICE);
    if(mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE) != null) {
        mSensor = mSensorManager.getDefaultSensor(69680);
        isSensorPresent = true;
    } else {
        isSensorPresent = false;
    }
    mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
    return START_STICKY;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onSensorChanged(SensorEvent event) {
    mTextView.setText("Heart Rate:  " + String.valueOf(event.values[0]));
    HelloData = (String) String.valueOf(event.values[0]);
    if(!HelloData.contains("0.0")){
        postDataUsingVolley(HelloData);
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int i) {

}

private void postDataUsingVolley(String ranData) {
    String url = "https://test.com";
    RequestQueue queue = Volley.newRequestQueue(this);
    JSONObject postData = new JSONObject();

    try {
        postData.put("data", ranData);

    } catch (JSONException e) {
        e.printStackTrace();
    }
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, postData, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            System.out.println(response);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    queue.add(jsonObjectRequest);
   }
 }

I have also added the following in AndroidManifest.xml

   <service
        android:name=".MyService"
        android:enabled="true"
        android:exported="true"></service>

It works for 30 seconds, send the data and once the watch goes inactive, it stops sending data. Any idea what is wrong with this?


Solution

  • You need to unregister your Sensor during onPause:

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
    

    Also, if you unregister, you need to use your boolean activityRunning.