I'm working on an app for a Sony Smarthwatch 3.
It records audio and sensor values after a command from another device that is connected by Bluetooth. I try to be more clear.
The problems
- The
Handler
doesn't update the associatedTextView
(also theButton
isn't set properly). The handler attached to "log" TextView just update the view in the end of execution with the last text sent. - The sensor doesn't update the field as required. The sensors and related listeners are poperly instantiated but i can't save the values associated to events they are ispecting. The string where i should save the values will never been changed, it's like listeners never find related events. I've already tested sensors on this device and they work normally.
- The chronometer doesn't work. Thenever start his count. it's not realy important but i wonna understand why. I'm thinking about some issue related to threads but i don't know how manage it.
The main code
public class MainActivity extends Activity implements OnRequestPermissionsResultCallback{
//GUI Elements
Chronometer chrono;
TextView log;
Button button;
MyHandlerThread update;
Handler myHandler;
boolean ready;
//Bluetooth Connection
BluetoothAdapter adapter;
BluetoothServerSocket serverSocket;
BluetoothDevice clientDevice;
BluetoothSocket clientSocket;
final UUID id = UUID.fromString("067e6162-3b6f-4ae2-a171-2470b63dff00");
InputStream in;
/*Sensors*/
SensorManager manager;
Sensor acc, gyr, mag;
SensorEventListener accEvent, gyrEvent, magEvent;
/*Microphone*/
MediaRecorder medRec;
/*File Data*/
File data;
FileWriter writer;
long time;
Thread writing;
String accValues="", gyrValues="", magValues="";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
//GUI Elements
chrono = (Chronometer)findViewById(R.id.chrono);
log = (TextView) findViewById(R.id.logger);
button = (Button) findViewById(R.id.start);
myHandler= new MyHandler();
update = new MyHandlerThread(myHandler);
update.start();
ready=true;
writing=null;
//Listner
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//flag di stato
//boolean ready = (button.getText().equals("Start"));
audioInit(); //Audio Init, defined below
fileInit(); //File Init, defined below
if(ready){
try {
bluetoothInit(); //Bluetooth Init, defined below
} catch (Exception e) {/**/}
if (!adapter.isEnabled()){
update.setMessage("please, Turn Bluetooth On");
}
else{
try {
update.setMessage("Waiting Device...");
bluetoothConnect();
if(clientSocket!=null && in != null) {
update.setMessage("Connected:\n"+ clientDevice.getName());
}
while(ready){
int cmd = in.read(); //1 = start, 0 = stop
if(cmd == 1){
update.setMessage("Should be Ready");
time=SystemClock.elapsedRealtime();
update.setMessage("Recording...");
button.setText("Stop");
try {
if(writing==null)
writing = new Thread(new Runnable() {
@Override
public void run() {
while(ready){
try {
stopSensor(); //Defined Below
writer.flush(); //Clear Stream
writer.append((SystemClock.elapsedRealtime()-time)+";"); //Writing Record in CSV
writer.append(accValues+gyrValues+magValues+"\n");
sensorInit(); //Sensor Init, defined Below
wait(250);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
sensorInit();
writing.start(); //Start Thread Reading/Writing for Sensor values
startRecord(); //Audio and Chrono Start
} catch (Exception e) {
e.printStackTrace();
}
}
else if (cmd==0){
//log.setText("Should be Stopped");
update.setMessage("Should be Stopped");
ready=false;
writing=null;
stopRecord();
update.setMessage("Stopped");
button.setText("Start");
}
}
} catch (Exception e) {
//log.setText("Bluetooth Problem");
update.setMessage("Bluetooth Problem");
}
}
}
}
}); //fine Listner
}
});
}
/*Handler for Log TextView*/
private class MyHandler extends Handler {
public MyHandler(){
super(Looper.getMainLooper());
}
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
if(bundle.containsKey("refresh")) {
String value = bundle.getString("refresh");
log.setText(value);
}
}
}
/*Bluetooth Init*/
void bluetoothInit(){
try {
adapter = BluetoothAdapter.getDefaultAdapter();
serverSocket = adapter.listenUsingRfcommWithServiceRecord("TennisRecord",id);
clientSocket=null;
clientDevice=null;
in=null;
} catch (Exception e) {
e.printStackTrace();
}
}
/*Bluetooth Connection*/
void bluetoothConnect() throws IOException {
clientSocket = serverSocket.accept();
clientDevice = clientSocket.getRemoteDevice();
in=clientSocket.getInputStream();
}
/*Audio Init*/
void audioInit(){
medRec = new MediaRecorder();
medRec.setAudioSource(MediaRecorder.AudioSource.MIC);
medRec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
medRec.setOutputFile(Environment.getExternalStorageDirectory()+"/tennis_record.3gp");
medRec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
medRec.setAudioSamplingRate(44100);
medRec.setAudioChannels(1);
}
/*File Init*/
void fileInit(){
try {
data=new File(Environment.getExternalStorageDirectory(),"/data.csv");
writer = new FileWriter(data);
} catch (IOException e) {
e.printStackTrace();
}
}
/*Sensors Init*/
void sensorInit(){
manager = (SensorManager) getSystemService(SENSOR_SERVICE);
acc = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
gyr = manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
mag = manager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
accEvent = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
accValues=event.values[0]+";"+event.values[1]+";"+event.values[2]+";";
log.setText((int) event.values[0]);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
gyrEvent = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
gyrValues=event.values[0]+";"+event.values[1]+";"+event.values[2]+";";
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
magEvent = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
magValues=event.values[0]+";"+event.values[1]+";"+event.values[2]+";";
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
manager.registerListener(accEvent,acc,SensorManager.SENSOR_DELAY_NORMAL);
manager.registerListener(gyrEvent,gyr,SensorManager.SENSOR_DELAY_NORMAL);
manager.registerListener(magEvent,mag,SensorManager.SENSOR_DELAY_NORMAL);
}
/*Start Records*/
void startRecord() throws IOException {
/*Microfono*/
medRec.prepare();
medRec.start();
/*Cronometro*/
chrono.setBase(SystemClock.elapsedRealtime());
chrono.start();
}
/*Close Record*/
void stopRecord(){
/*Microfono*/
medRec.stop();
medRec.release();
medRec=null;
/*Cronometro*/
chrono.setBase(SystemClock.elapsedRealtime());
chrono.stop();
/*File*/
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*Stop Senors*/
void stopSensor(){
/*Sensori*/
manager.unregisterListener(accEvent);
manager.unregisterListener(gyrEvent);
manager.unregisterListener(magEvent);
}
}
The Handler thread in another class
public class MyHandlerThread extends Thread {
private Handler handler;
Queue<String> text;
public MyHandlerThread(Handler handler) {
this.handler = handler;
text=new ArrayDeque<String>();
}
public void run() {
try {
while(true) {
if(!text.isEmpty()){
notifyMessage(text.remove());
Thread.sleep(1000);
}
}
}catch(Exception ex) {}
}
public void setMessage(String str){
text.add(str);
}
private void notifyMessage(String str) {
Message msg = handler.obtainMessage();
Bundle b = new Bundle();
b.putString("refresh", ""+str);
msg.setData(b);
handler.sendMessage(msg);
}
}
Any solutions?