I have made some apps (pedometer, heart rate, audio recorder) for the moto360 with android wear. everything works fine, but I don't know how to save the data on the watch and how to access the data on the smartphone. I have managed to send messages to the watch, but I can't send data from the watch to the phone. I can save my data on the smartphone, but I don't know how to manage it on the smartwatch. can someone show me a tutorial or an example? thank you so much!
edit:
The following Code below is used for tracking the heartrate on the Moto360 and it works fine.
I tried to transfer the data from the watch to the Phone for that I used this tutorial -> https://developer.android.com/training/wearables/data-layer/data-items.html
After implementing the Code from the android page I couldn`t run the Project on the device!
public class MainActivity extends Activity implements SensorEventListener {
private static final String TAG = "MainActivity";
private TextView mTextViewStepCount;
private TextView mTextViewStepDetect;
private TextView mTextViewHeart;
PutDataMapRequest dataMap = PutDataMapRequest.create("/count");
GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextViewStepCount = (TextView) stub.findViewById(R.id.step_count);
mTextViewStepDetect = (TextView) stub.findViewById(R.id.step_detect);
mTextViewHeart = (TextView) stub.findViewById(R.id.heart);
getStepCount();
}
});
}
private void getStepCount() {
SensorManager mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));
Sensor mHeartRateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
Sensor mStepCountSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
Sensor mStepDetectSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
mSensorManager.registerListener(this, mHeartRateSensor, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mStepCountSensor, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mStepDetectSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
private String currentTimeStr() {
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
return df.format(c.getTime());
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.d(TAG, "onAccuracyChanged - accuracy: " + accuracy);
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
String msg = "" + (int) event.values[0];
mTextViewHeart.setText(msg);
Log.d(TAG, msg);
} else if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
String msg = "Count: " + (int) event.values[0];
mTextViewStepCount.setText(msg);
Log.d(TAG, msg);
} else if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
String msg = "Detected at " + currentTimeStr();
mTextViewStepDetect.setText(msg);
Log.d(TAG, msg);
} else {
Log.d(TAG, "Unknown sensor type");
}
}
}
this code helps me a lot, i hope it helps many other people :)
https://github.com/pocmo/SensorDashboard
You need to uses data assets. Image sample:
private static Asset createAssetFromBitmap(Bitmap bitmap) {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
return Asset.createFromBytes(byteStream.toByteArray());
}
and then
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Asset asset = createAssetFromBitmap(bitmap);
PutDataRequest request = PutDataRequest.create("/image");
request.putAsset("profileImage", asset);
Wearable.DataApi.putDataItem(mGoogleApiClient, request);
more http://developer.android.com/training/wearables/data-layer/assets.html
Related
I am working on an application that records acceleration data from the smartphone and save them into a file everytime i click on the start recording button,
but i can't find the created file alhough no exceptions have been raised.
I added the permission request <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in the manifest file and i checked the previously asked questions related to this topic but i still can't find where the problem is?
Here is the code :
public class MainActivity extends AppCompatActivity implements SensorEventListener {
int clicknumber = 0;
private static final String LOG_TAG ="";
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Button mstartButton= null;
private boolean servicestatus = false;
private RelativeLayout Rl = null;
private LinearLayout ll= null;
long timeOffsetMs= System.currentTimeMillis()-System.nanoTime() / 1000000;
File file=null;
BufferedWriter out = null;
#Override
public void onCreate(Bundle savedInstanceState) {
final String path = Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_DOCUMENTS).getPath();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
servicestatus = isMyServiceRunning(RecordService.class);
mstartButton = (Button) findViewById(R.id.recordButton);
mstartButton.setText("Start Recording");
mstartButton.setTextColor(Color.GREEN);
Rl= (RelativeLayout) findViewById(R.id.Rlayout);
ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
Rl.addView(ll);
final Intent service = new Intent(this, RecordService.class);
mstartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clicknumber+=1;
if (clicknumber % 2 != 0 || clicknumber == 0 ){
startService(service);
mstartButton.setText("Stop Recording");
mstartButton.setTextColor(Color.RED);
String newpath = path +"data.txt";
file = new File(newpath);
}
else{
stopService(service);
mstartButton.setText("Start Recording");
mstartButton.setTextColor(Color.GREEN);
}
}
});
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
Sensor mySensor=sensorEvent.sensor;
if (mySensor.getType()==Sensor.TYPE_ACCELEROMETER){
float x=sensorEvent.values[0];
float y=sensorEvent.values[1];
float z=sensorEvent.values[2];
long timestamp=timeOffsetMs+ sensorEvent.timestamp / 1000000;
if (isMyServiceRunning(RecordService.class) == true){
TextView tv = new TextView(this);
tv.setTextColor(Color.WHITE);
tv.setText(String.format("t=%d,x=%.1f,y=%.1f,z=%.1f", timestamp,x,y,z));
ll.addView(tv);
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(Float.toString(x) + Float.toString(y) +
Float.toString(z) );
out.close();
}
catch (IOException e)
{
Log.e(MainActivity.LOG_TAG ,"Exception");
}
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service :
manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
Thanks in advance!
Your File is at: /storage/emulated/0/Documentsdata.txt
Note that 2 things should meet, because the error here is not intended.
The Directory Document must exist.
You forgot / in the following line
Error : String newpath = path +"data.txt"
No Error : String newpath = path +"/"+"data.txt"
If you test your code now, you can get you file or an exception is thrown.
which api are you using ?. declaring the permission in the manifest for writing file to a Storage is neccessary. but for the completness you should have granted permission from the user if the system api > 23.
I have implemented a snippet code to calculate the Tesla value of the magnetic field. I have tested it recently and I noticed when I am in the bus the value is 24 but when I am outside the value is about 45. I mean the bus is metal so the value should be higher inside of it. Is there any explanation for this strange behaviour?
I appreciate any help.
Code:
public class MainActivity extends ActionBarActivity implements
SensorEventListener {
String telsaString;
private TextView magneticX;
private TextView magneticY;
private TextView magneticZ;
private TextView magneticT;
private SensorManager sensorManager = null;
private long lastUpdate = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// Capture magnetic sensor related view elements
magneticX = (TextView) findViewById(R.id.valMag_X);
magneticY = (TextView) findViewById(R.id.valMag_Y);
magneticZ = (TextView) findViewById(R.id.valMag_Z);
magneticT = (TextView) findViewById(R.id.valMag_T);
// Register magnetic sensor
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
// Unregister the listener
sensorManager.unregisterListener(this);
super.onPause();
}
#Override
protected void onStop() {
// Unregister the listener
sensorManager.unregisterListener(this);
super.onStop();
}
#Override
protected void onResume() {
super.onResume();
// Register magnetic sensor
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent sensorEvent) {
synchronized (this) {
float magX = sensorEvent.values[0];
float magY = sensorEvent.values[1];
float magZ = sensorEvent.values[2];
magneticX.setText(Float.toString(sensorEvent.values[0]));
magneticY.setText(Float.toString(sensorEvent.values[1]));
magneticZ.setText(Float.toString(sensorEvent.values[2]));
int teslaXYZ = (int)(Math.sqrt((magX * magX) + (magY * magY)
+ (magZ * magZ)));
String str = String.valueOf(teslaXYZ);
magneticT.setText(str);
long curTime = System.currentTimeMillis();
if ((curTime - lastUpdate) > 15000) {
lastUpdate = curTime;
try {
JSONObject tesla = new JSONObject();
tesla.put("tesla", teslaXYZ);
//tesla.put("tesla", teslaXYZ);
telsaString = tesla.toString();
new MyAsyncTask().execute(telsaString);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
A vehicle like a bus will contain many metal parts, some of which will be magnetized and have their own magnetic fields. The magnetometer of your device will pick up the superposition of the geomagnetic field and these additional fields and will show bad directions and absolute values compared to when you're standing away from the vehicle.
The engine and electric infrastructure of the car can also cause interference (While testing, I noticed a clear difference in magnetometer readings when starting the engine of my car).
I am trying to send data of the magnetic field sensor to the Server every 5 seconds but I am facing Problem to unregister the sensorListerner from reading data. I have tried it like this sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),1000 * 10); too but without seccuss. Currently the data are being sent to the Server 12 time in one second.
I appreciate any help.
Code:
public class MainActivity extends ActionBarActivity implements
SensorEventListener {
String telsaString;
private TextView magneticX;
private TextView magneticY;
private TextView magneticZ;
private TextView magneticT;
private SensorManager sensorManager = null;
private float magX;
private float magY;
private float magZ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// Capture magnetic sensor related view elements
magneticX = (TextView) findViewById(R.id.valMag_X);
magneticY = (TextView) findViewById(R.id.valMag_Y);
magneticZ = (TextView) findViewById(R.id.valMag_Z);
magneticT = (TextView) findViewById(R.id.valMag_T);
// Register magnetic sensor
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);
final SensorEventListener listener = this;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
sensorManager.unregisterListener(listener);
}
}, 5000);
}
#Override
protected void onPause() {
// Unregister the listener
sensorManager.unregisterListener(this);
super.onPause();
}
#Override
protected void onStop() {
// Unregister the listener
sensorManager.unregisterListener(this);
super.onStop();
}
#Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_NORMAL);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent sensorEvent) {
synchronized (this) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magX = sensorEvent.values[0];
magY = sensorEvent.values[1];
magZ = sensorEvent.values[2];
magneticX.setText(Float.toString(sensorEvent.values[0]));
magneticY.setText(Float.toString(sensorEvent.values[1]));
magneticZ.setText(Float.toString(sensorEvent.values[2]));
double teslaXYZ = (Math.sqrt((magX * magX) + (magY * magY)
+ (magZ * magZ)));
magneticT.setText(Double.toString(teslaXYZ));
try {
JSONObject tesla = new JSONObject();
tesla.put("tesla", teslaXYZ);
telsaString = tesla.toString();
new MyAsyncTask().execute(telsaString);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Edit:
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
10*1000*1000);
.
.
.
.
long curTime = System.currentTimeMillis();
if ((curTime - lastUpdate) > 10000) {
lastUpdate = curTime;
}
The rate you provided 1000 * 10 is in microseconds, so you are requesting a 10 millisecond update period. Note that the requested sample period is only a request. The rate may be faster or slower, you need to track the times and do the appropriate thing. When you wish to completely stop receiving events, unregister your listener with the SensorManager.unregisterListener() method.
I'm simply trying to record accelerometer data and write a file in sdcard with a button click. While running the app in my Nexus S (with 4.1.2), it freezes after a minute. I tried to run it in Galaxy Nexus phone and it works smoothly. For some reasons I have to work in Nexus S. Can anyone suggest me what might be the reason of crashing. I tried to see the log, but it does not through any error message.
Here's my code:
final SensorEventListener mySensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
xAxis_lateralA = sensorEvent.values[0];
yAxis_longitudinalA = sensorEvent.values[1];
zAxis_verticalA = sensorEvent.values[2]; // TODO apply the acceleration changes to your application.
textView.append("\nACC_x = "+ xAxis_lateralA + ", ACC_y = "+yAxis_longitudinalA+ ", ACC_z = " + zAxis_verticalA);
acc += "\n"+miliSec()+", "+xAxis_lateralA + ", "+ yAxis_longitudinalA+", "+zAxis_verticalA;
try {
File myFile = new File("/sdcard/acc.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.append(acc);
myOutWriter.close();
fOut.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
startButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getBaseContext(),"Done writing SD 'acc.txt'",Toast.LENGTH_SHORT).show();
sm = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
int sensorType = Sensor.TYPE_ACCELEROMETER;
sm.registerListener(mySensorEventListener,sm.getDefaultSensor(sensorType), SensorManager.SENSOR_DELAY_NORMAL);
}// onClick
}); // btnWriteSDFile
stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int sensorType = Sensor.TYPE_ACCELEROMETER;
sm.unregisterListener(mySensorEventListener, sm.getDefaultSensor(sensorType));
Toast.makeText(getBaseContext(), "Stopped Recording",Toast.LENGTH_SHORT).show();
finish();
}// onClick
}); // btnstopButton
Issue is due to the way your writing values to text file.
You are opening/writing/closiing the file for everytime you get sensor reading.
Even for Sensor reading frequency of 50Hz it takes lot computation,writing these in text for 50 times/second is not efficient.
Use BufferedWriter ,it gives better performance.
I have written the following lines to record accelerometer data in a file with a button click
startButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final SensorEventListener mySensorEventListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
xAxis_lateralA = sensorEvent.values[0];
yAxis_longitudinalA = sensorEvent.values[1];
zAxis_verticalA = sensorEvent.values[2]; // TODO apply the acceleration changes to your application.
textView.append("\nACC_x = "+ xAxis_lateralA + ", ACC_y = "+yAxis_longitudinalA+ ", ACC_z = " + zAxis_verticalA);
acc+="\n"+xAxis_lateralA + ", "+ yAxis_longitudinalA+", "+zAxis_verticalA;
try {
File myFile = new File("/sdcard/acc.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append(acc);
myOutWriter.close();
fOut.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'acc.txt'",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
// write on SD card file data in the text box
sm = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
int sensorType = Sensor.TYPE_ACCELEROMETER;
sm.registerListener(mySensorEventListener,sm.getDefaultSensor(sensorType), SensorManager.SENSOR_DELAY_NORMAL);
}// onClick
});
Now I want it to stop recording the data with another button click. For example -
stopButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int sensorType = Sensor.TYPE_ACCELEROMETER;
sm.unregisterListener(listener, sensor)
}// onClick
}); // btnstopButton
}
Wanted to use unregisterListener but most of the time it is saying deprecated.
Can anyone help please?
The documentation says that using the methods associated with SensorListener are deprecated, and to use SensorEventListener instead. Your code snippet should not throw a deprecated warning, but if you use SensorListener, it would.
I think you want to declare your SensorEventListener object outside of the onClick() method so you can unregister it in the other onClick() method:
sm.unregisterListener(mySensorEventListener, sensorType);
That's the method signature you want to use according to the docs.