Java tutorial
/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Original source for uart service handler is from Nordic Semiconductor example code // Modifications are for diagnostic and testing purposes only // This is unreleased code. // Modifications, Copyright 2014, Zephyr Engineering, Inc. All Rights Reserved. // Last update: 5/23/2014 R0.1 - Alpha test version for hardware/firmware debug support // 6/10/2014 adjusted demo mode medium sensitivity for acc from 16 to 8 // 6/11/2014 adjusted demo mode medium sensitivity for gyro from 64 to 40 // removed data collection from demo mode package com.zpci.firstsignhairclipdemo; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.util.Date; import android.app.Activity; import android.app.AlertDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements RadioGroup.OnCheckedChangeListener { private static final int REQUEST_SELECT_DEVICE = 1; private static final int REQUEST_ENABLE_BT = 2; private static final int REQUEST_DIAG_CMD = 3; private static final int UART_PROFILE_READY = 10; public static final String TAG = "Hairclip_MainActivity"; private static final int UART_PROFILE_CONNECTED = 20; private static final int UART_PROFILE_DISCONNECTED = 21; private static final int STATE_OFF = 10; TextView mRemoteRssiVal; RadioGroup mRg; public int mState = UART_PROFILE_DISCONNECTED; public static UartService mService = null; private BluetoothDevice mDevice = null; private BluetoothAdapter mBtAdapter = null; private ListView messageListView; private ArrayAdapter<String> listAdapter; private Button btnConnectDisconnect, btnSend; private EditText edtMessage; private byte[] dcmd; public boolean armed = false; public boolean alarmsent = false; public static ByteArrayOutputStream adStream = new ByteArrayOutputStream(100000); //size grows if needed public static ByteArrayOutputStream SensorStream = new ByteArrayOutputStream(10000); // " public static int expectedAudioSamples = 8000; //8000 sps, 1 byte per sample public static int expectedSensorSamples = 100 * 12; //100 sps, 12 bytes per sample (2 bytes each Ax, Ay, Az, Rr, Rp, Ry) public static boolean demomode = true; public static Button c1, c2, dm1, dm2, sb1, sb2, sb3, alonb, aloffb; public static TextView stxt; // URLs private static final Uri URL_FS = Uri.parse("http://www.firstsign.us"); // constants protected static final int FILETYPEAUDIO = 0; protected static final int FILETYPESENSOR = 1; private static final int ALARMAUDIOSAMPLES = 8000 * 10; //60 * 1; //FIXME before releasing - 10 seconds private static final int ALARMSENSORSAMPLES = 192 * 12 * 1; //FIXME too @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.diag); mBtAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBtAdapter == null) { Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); finish(); return; } messageListView = (ListView) findViewById(R.id.listMessage); listAdapter = new ArrayAdapter<String>(this, R.layout.message_detail); messageListView.setAdapter(listAdapter); messageListView.setDivider(null); btnConnectDisconnect = (Button) findViewById(R.id.btn_select); btnSend = (Button) findViewById(R.id.sendButton); edtMessage = (EditText) findViewById(R.id.sendText); // top level select either demo mode or diag mode dm1 = (Button) findViewById(R.id.DemoModeButton); dm2 = (Button) findViewById(R.id.DiagModeButton); // make other controls invisible until mode is selected c1 = (Button) findViewById(R.id.Command1Button); c2 = (Button) findViewById(R.id.Command2Button); sb1 = (Button) findViewById(R.id.Sens1Button); sb2 = (Button) findViewById(R.id.Sens2Button); sb3 = (Button) findViewById(R.id.Sens3Button); stxt = (TextView) findViewById(R.id.textSensy); Log.d(TAG, "stext = " + stxt); alonb = (Button) findViewById(R.id.DemoAlarmOnButton); aloffb = (Button) findViewById(R.id.DemoAlarmOffButton); Log.d(TAG, "demomode = " + demomode); c1.setVisibility(View.INVISIBLE); c2.setVisibility(View.INVISIBLE); btnSend.setVisibility(View.INVISIBLE); edtMessage.setVisibility(View.INVISIBLE); messageListView.setVisibility(View.INVISIBLE); sb1.setVisibility(View.GONE); sb2.setVisibility(View.GONE); sb3.setVisibility(View.GONE); stxt.setVisibility(View.GONE); alonb.setVisibility(View.GONE); aloffb.setVisibility(View.GONE); service_init(); // Handler Disconnect & Connect button btnConnectDisconnect.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!mBtAdapter.isEnabled()) { Log.i(TAG, "onClick - BT not enabled yet"); Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE_BT); } else { if (btnConnectDisconnect.getText().equals("Connect")) { //Connect button pressed, open DeviceListActivity class, with popup windows that scan for devices Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class); startActivityForResult(newIntent, REQUEST_SELECT_DEVICE); } else { //Disconnect button pressed if (mDevice != null) { mService.disconnect(); } } } } }); // Handler Send button btnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EditText editText = (EditText) findViewById(R.id.sendText); String message = editText.getText().toString(); byte[] value; try { //send data to service value = message.getBytes("UTF-8"); mService.writeRXCharacteristic(value); //Update the log with time stamp String currentDateTimeString = DateFormat.getTimeInstance().format(new Date()); listAdapter.add("[" + currentDateTimeString + "] TX: " + message); messageListView.smoothScrollToPosition(listAdapter.getCount() - 1); edtMessage.setText(""); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } // ---------------------------------------------------------------------------------------------------- public void onDemoModeButton(View view) { c1.setVisibility(View.INVISIBLE); c2.setVisibility(View.INVISIBLE); btnSend.setVisibility(View.INVISIBLE); edtMessage.setVisibility(View.INVISIBLE); messageListView.setVisibility(View.INVISIBLE); dm1.setVisibility(View.GONE); dm2.setVisibility(View.GONE); stxt.setVisibility(View.VISIBLE); sb1.setVisibility(View.VISIBLE); sb2.setVisibility(View.VISIBLE); sb3.setVisibility(View.VISIBLE); alonb.setVisibility(View.VISIBLE); aloffb.setVisibility(View.VISIBLE); } public void onDiagModeButton(View view) { c1.setVisibility(View.VISIBLE); c2.setVisibility(View.VISIBLE); btnSend.setVisibility(View.INVISIBLE); edtMessage.setVisibility(View.INVISIBLE); messageListView.setVisibility(View.VISIBLE); dm1.setVisibility(View.GONE); dm2.setVisibility(View.GONE); sb1.setVisibility(View.GONE); sb2.setVisibility(View.GONE); sb3.setVisibility(View.GONE); stxt.setVisibility(View.GONE); alonb.setVisibility(View.GONE); aloffb.setVisibility(View.GONE); } public void onCommandButton(View view) { if (mState == UART_PROFILE_CONNECTED) { Intent i = new Intent(this, DiagActivity.class); startActivityForResult(i, REQUEST_DIAG_CMD); } else { showMessage("Not Connected"); } } public void onCmd2Button(View view) { if (mState == UART_PROFILE_CONNECTED) { Intent i = new Intent(this, Cmd2Activity.class); startActivityForResult(i, REQUEST_DIAG_CMD); } else { showMessage("Not Connected"); } } public void onSens1Button(View view) { if (mState == UART_PROFILE_CONNECTED) { //set accelerometer and gyro to low sensitivity byte[] value = { 0x04, 0x01, (byte) 0x7f }; Log.d(TAG, "Set Gyro threshold = " + value[2]); mService.writeRXCharacteristic(value); byte[] value2 = { 0x04, 0x00, (byte) 0x40 }; Log.d(TAG, "Set Acc threshold = " + value2[2]); mService.writeRXCharacteristic(value2); showMessage("Sensitivity LOW"); } else { showMessage("Not Connected"); } } public void onSens2Button(View view) { if (mState == UART_PROFILE_CONNECTED) { //set accelerometer and gyro to medium sensitivity //06112014 gyro adjust from 0x40 to 0x30 //06132014 gyro adjust from 0x28 to 0x7f byte[] value = { 0x04, 0x01, (byte) 0x7f }; Log.d(TAG, "Set Gyro threshold = " + value[2]); mService.writeRXCharacteristic(value); //06102014 customer says not sensitive enough //byte[] value2 = {0x04,0x00,(byte)0x10}; byte[] value2 = { 0x04, 0x00, (byte) 0x08 }; Log.d(TAG, "Set Acc threshold = " + value2[2]); mService.writeRXCharacteristic(value2); showMessage("Sensitivity MED"); } else { showMessage("Not Connected"); } } public void onSens3Button(View view) { if (mState == UART_PROFILE_CONNECTED) { //set accelerometer and gyro to high sensitivity //06132014 gyro adjust from 0x10 to 0x7f byte[] value = { 0x04, 0x01, (byte) 0x7f }; Log.d(TAG, "Set Gyro threshold = " + value[2]); mService.writeRXCharacteristic(value); byte[] value2 = { 0x04, 0x00, (byte) 0x04 }; Log.d(TAG, "Set Acc threshold = " + value2[2]); mService.writeRXCharacteristic(value2); showMessage("Sensitivity HIGH"); } else { showMessage("Not Connected"); } } public void onDemoAlarmOnButton(View view) { if (mState == UART_PROFILE_CONNECTED) { Log.d(TAG, "Demo Alarm On button pressed"); byte[] value = { 0x05, 0x00 }; mService.writeRXCharacteristic(value); armed = true; alarmsent = false; adStream.reset(); // reset audio data buffer expectedAudioSamples = ALARMAUDIOSAMPLES; // set to default number of samples SensorStream.reset(); // reset sensor data buffer expectedSensorSamples = ALARMSENSORSAMPLES; // set to default showMessage("Alarm On"); } else { showMessage("Not Connected"); } } public void onDemoAlarmOffButton(View view) { if (mState == UART_PROFILE_CONNECTED) { Log.d(TAG, "Demo Alarm Off button pressed"); byte[] value = { 0x05, 0x01 }; mService.writeRXCharacteristic(value); armed = false; showMessage("Alarm Off"); } else { showMessage("Not Connected"); } } public void onTestButton(View view) { //placeholder for debug tests. modify as needed //--------- test alarm activity --------- //Intent alarmintent = new Intent(getApplicationContext(), AlarmActivity.class); //startActivity(alarmintent); //-------- test wavefile writes ----- /* byte[] testbuff = new byte[128000]; //byte[] testbuff = {0,1,2,3,4,5,6,7,8,9}; //saverawaudio(testbuff); for(int i=0;i<testbuff.length;i++) { testbuff[i] = (byte) (int)(0.5 * (127 * Math.sin(2.0 * Math.PI * 440 * i /8000) + 127.5) + 0.5 * (127 * Math.sin(2.0 * Math.PI * 350 * i /8000) + 127.5)); } saverawdata(testbuff,FILETYPEAUDIO); savewavefile(testbuff); */ // display audio buffer length showMessage("Audio samples = " + adStream.size()); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); // if (id == R.id.action_settings) { // return true; //} switch (item.getItemId()) { case android.R.id.home: onBackPressed(); return true; case R.id.action_settings: showMessage("settings"); break; case R.id.opt_about: onUrl(URL_FS); break; case R.id.opt_exit: finish(); break; default: return super.onOptionsItemSelected(item); } return true; } private void onUrl(Uri uri) { Intent web = new Intent(Intent.ACTION_VIEW, uri); startActivity(web); } //UART service connected/disconnected private ServiceConnection mServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder rawBinder) { mService = ((UartService.LocalBinder) rawBinder).getService(); Log.d(TAG, "onServiceConnected mService= " + mService); if (!mService.initialize()) { Log.e(TAG, "Unable to initialize Bluetooth"); finish(); } } public void onServiceDisconnected(ComponentName classname) { //// mService.disconnect(mDevice); mService = null; } }; private Handler mHandler = new Handler() { @Override //Handler events that received from UART service public void handleMessage(Message msg) { } }; private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); final Intent mIntent = intent; //*********************// if (action.equals(UartService.ACTION_GATT_CONNECTED)) { runOnUiThread(new Runnable() { public void run() { String currentDateTimeString = DateFormat.getTimeInstance().format(new Date()); Log.d(TAG, "UART_CONNECT_MSG"); btnConnectDisconnect.setText("Disconnect"); //edtMessage.setEnabled(true); //btnSend.setEnabled(true); ((TextView) findViewById(R.id.deviceName)) .setText(mDevice.getName() + " - Connected and Monitoring"); listAdapter.add("[" + currentDateTimeString + "] Connected to: " + mDevice.getName()); messageListView.smoothScrollToPosition(listAdapter.getCount() - 1); mState = UART_PROFILE_CONNECTED; } }); } //*********************// if (action.equals(UartService.ACTION_GATT_DISCONNECTED)) { runOnUiThread(new Runnable() { public void run() { String currentDateTimeString = DateFormat.getTimeInstance().format(new Date()); Log.d(TAG, "UART_DISCONNECT_MSG"); btnConnectDisconnect.setText("Connect"); //edtMessage.setEnabled(false); // btnSend.setEnabled(false); ((TextView) findViewById(R.id.deviceName)).setText("Not Connected"); listAdapter.add("[" + currentDateTimeString + "] Disconnected to: " + mDevice.getName()); mState = UART_PROFILE_DISCONNECTED; mService.close(); //setUiState(); } }); } //*********************// if (action.equals(UartService.ACTION_GATT_SERVICES_DISCOVERED)) { mService.enableTXNotification(); } //*********************// if (action.equals(UartService.ACTION_DATA_AVAILABLE)) { // -------------------------------------------------------------- // Data has been received from Hairclip // -------------------------------------------------------------- // get data from uart service final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA); // alarm if ((armed && !alarmsent && (txValue[0] == (byte) 0x55) && (txValue[1] == (byte) 0xaa)) || ((txValue[0] == (byte) 0x55) && (txValue[1] == (byte) 0xab))) { Log.d(TAG, "alarm2: " + "0x" + Integer.toHexString(txValue[0] & 0xff) + " 0x" + Integer.toHexString(txValue[1] & 0xff)); Intent alarmintent = new Intent(getApplicationContext(), AlarmActivity.class); startActivity(alarmintent); try { // turn off alarm notifications byte[] value = { 0x05, 0x01 }; mService.writeRXCharacteristic(value); //06112014 turn off data collection to allow quick re-trigger for demos // get sensor data for alarm event //value[0] = 0x06; //value[1] = 0x00; //mService.writeRXCharacteristic(value); // get audio data for alarm event //value[0] = 0x06; //value[1] = 0x01; //mService.writeRXCharacteristic(value); } catch (Exception e) { Log.e(TAG, e.toString()); } alarmsent = true; } // audio data else if ((txValue[0] == (byte) 0x07 && txValue[1] == (byte) 0x03) || (txValue[0] == (byte) 0x06 && txValue[1] == (byte) 0x01)) { // audio data // append data to audio buffer // future - make more robust with save on timeout if (expectedAudioSamples > 0) { if (adStream.size() < expectedAudioSamples) adStream.write(txValue, 2, txValue.length - 2); if (adStream.size() >= expectedAudioSamples) { Log.d(TAG, "adStream complete. buffer filled to: " + adStream.size()); saverawdata(adStream.toByteArray(), FILETYPEAUDIO); savewavefile(adStream.toByteArray()); expectedAudioSamples = 0; } } } // sensor data else if ((txValue[0] == (byte) 0x07 && txValue[1] == (byte) 0x01) || (txValue[0] == (byte) 0x06 && txValue[1] == (byte) 0x00)) { // sensor data // append data to sensor buffer - up to expected number of samples // future - make more robust with save on timeout if (expectedSensorSamples > 0) { if (SensorStream.size() < expectedSensorSamples) { if (txValue[0] == (byte) 0x07) //diag sensor data includes 2 byte pkt# in header SensorStream.write(txValue, 4, txValue.length - 4); //add data to buffer, skip first 4 header bytes else SensorStream.write(txValue, 2, txValue.length - 2); //add data to buffer, skip first 2 header bytes Log.d(TAG, "SensorStream Buffer filled to: " + SensorStream.size()); } if (SensorStream.size() >= expectedSensorSamples) { Log.d(TAG, "SensorStream complete. Buffer filled to: " + SensorStream.size()); saverawdata(SensorStream.toByteArray(), FILETYPESENSOR); expectedSensorSamples = 0; } } else Log.d(TAG, "received more sensor data than expected"); } runOnUiThread(new Runnable() { public void run() { try { //String text = new String(txValue, "UTF-8"); Log.d(TAG, "txValue.length = " + txValue.length); String msg = ""; for (int i = 0; i < txValue.length; i++) { msg = msg + "0x" + Integer.toHexString(txValue[i] & 0xff) + " "; } String currentDateTimeString = DateFormat.getTimeInstance().format(new Date()); listAdapter.add("[" + currentDateTimeString + "] RX: " + msg); messageListView.smoothScrollToPosition(listAdapter.getCount() - 1); } catch (Exception e) { Log.e(TAG, e.toString()); } } }); } //*********************// if (action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_UART)) { showMessage("Device doesn't support UART service. Disconnecting"); mService.disconnect(); } } }; private void service_init() { Intent bindIntent = new Intent(this, UartService.class); bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE); LocalBroadcastManager.getInstance(this).registerReceiver(UARTStatusChangeReceiver, makeGattUpdateIntentFilter()); } private static IntentFilter makeGattUpdateIntentFilter() { final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(UartService.ACTION_GATT_CONNECTED); intentFilter.addAction(UartService.ACTION_GATT_DISCONNECTED); intentFilter.addAction(UartService.ACTION_GATT_SERVICES_DISCOVERED); intentFilter.addAction(UartService.ACTION_DATA_AVAILABLE); intentFilter.addAction(UartService.DEVICE_DOES_NOT_SUPPORT_UART); return intentFilter; } @Override public void onStart() { super.onStart(); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy()"); try { LocalBroadcastManager.getInstance(this).unregisterReceiver(UARTStatusChangeReceiver); } catch (Exception ignore) { Log.e(TAG, ignore.toString()); } unbindService(mServiceConnection); mService.stopSelf(); mService = null; } @Override protected void onStop() { Log.d(TAG, "onStop"); super.onStop(); } @Override protected void onPause() { Log.d(TAG, "onPause"); super.onPause(); } @Override protected void onRestart() { super.onRestart(); Log.d(TAG, "onRestart"); } @Override public void onResume() { super.onResume(); Log.d(TAG, "onResume"); if (!mBtAdapter.isEnabled()) { Log.i(TAG, "onResume - BT not enabled yet"); Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE_BT); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_SELECT_DEVICE: //When the DeviceListActivity return, with the selected device address if (resultCode == Activity.RESULT_OK && data != null) { String deviceAddress = data.getStringExtra(BluetoothDevice.EXTRA_DEVICE); mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress); Log.d(TAG, "... onActivityResultdevice.address==" + mDevice + "mserviceValue" + mService); ((TextView) findViewById(R.id.deviceName)).setText(mDevice.getName() + " - connecting"); mService.connect(deviceAddress); } break; case REQUEST_ENABLE_BT: // When the request to enable Bluetooth returns if (resultCode == Activity.RESULT_OK) { Toast.makeText(this, "Bluetooth has turned on ", Toast.LENGTH_SHORT).show(); } else { // User did not enable Bluetooth or an error occurred Log.d(TAG, "BT not enabled"); Toast.makeText(this, "Problem in BT Turning ON ", Toast.LENGTH_SHORT).show(); finish(); } break; case REQUEST_DIAG_CMD: if (resultCode == Activity.RESULT_OK) { byte[] value = data.getByteArrayExtra("cmd"); Log.d(TAG, "Diag command request success. length = " + value.length + ", 0x" + Integer.toHexString(value[0] & 0xff) + ", " + value[0]); if (value[0] == (byte) 0x05) { //alarm arm/disarm if (value[1] == (byte) 0x00) { armed = true; alarmsent = false; adStream.reset(); // reset audio data buffer expectedAudioSamples = ALARMAUDIOSAMPLES; // set to default number of samples SensorStream.reset(); // reset sensor data buffer expectedSensorSamples = ALARMSENSORSAMPLES; // set to default } else armed = false; } try { mService.writeRXCharacteristic(value); } catch (Exception e) { Log.e(TAG, e.toString()); } ; //Update the log with time stamp and message sent String msg = ""; for (int i = 0; i < value.length; i++) { msg = msg + "0x" + Integer.toHexString(value[i] & 0xff) + " "; } String currentDateTimeString = DateFormat.getTimeInstance().format(new Date()); listAdapter.add("[" + currentDateTimeString + "] TX: " + msg); messageListView.smoothScrollToPosition(listAdapter.getCount() - 1); } else { Log.d(TAG, "Diag command request result fail"); } break; default: Log.e(TAG, "bad activity result request code"); break; } } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { } public void saverawdata(byte[] ra, int type) { String filename; boolean usetext = true; if (type == FILETYPEAUDIO) filename = "rawaudio.dat"; else { if (usetext) filename = "rawsensor.csv"; else filename = "rawsensor.dat"; } try { //FileOutputStream adfos = openFileOutput(filename, Context.MODE_PRIVATE); //FileOutputStream adfos = openFileOutput(filename, Context.MODE_WORLD_READABLE); String state = Environment.getExternalStorageState(); Log.d(TAG, "External storage state: " + state); if (Environment.MEDIA_MOUNTED.equals(state)) { //create firstsign directory File rootPath = new File(Environment.getExternalStorageDirectory(), "firstsign"); if (!rootPath.exists()) { rootPath.mkdirs(); Log.d(TAG, "mkdirs"); } File file = new File(rootPath, filename); file.createNewFile(); OutputStream os = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(os); DataOutputStream rf = new DataOutputStream(bos); if (usetext) { rf.write("Ax Ay Az Rr Rp Ry\n".getBytes()); for (int i = 0, j = 0; i < ra.length; i += 2) { short sval = (short) ((ra[i] << 8) | (ra[i + 1] & 0xff)); //Log.d(TAG,"sval = " + sval); String ssval = Short.toString(sval) + " "; j++; if (j % 6 == 0) ssval += "\n"; rf.write(ssval.getBytes()); } } else { rf.write(ra); } File rfile = getFileStreamPath(filename); Log.d(TAG, "path: " + rfile); Log.d(TAG, "raw file write: " + filename + ra + "size = " + ra.length); rf.close(); bos.close(); os.close(); } else { Toast.makeText(this, "SDCard not mounted", Toast.LENGTH_LONG).show(); } //what do i do? } catch (Exception e) { e.printStackTrace(); } } public void savewavefile(byte[] ra) { //prepend 44 byte wave header to data int sampleRate = 8000; // audio sample rate is 8000 SPS int numSecs = ra.length / sampleRate; // number of seconds of audio to record int samples = sampleRate * numSecs; // number of samples in file short bitsPerSample = 8; // one byte per sample int filesize = samples + 44; // check this? int fmtChunkSize = 16; // size of 'fmt' chunk short channels = 1; // mono int byteRate = sampleRate * channels * bitsPerSample / 8; // will be 8K for us short format = 1; // 1 == uncompressed pcm short blockalign = (short) (channels * bitsPerSample / 8); // bytes per sample int audiolen = samples * channels * bitsPerSample / 8; // length of audio in bytes try { //OutputStream os = openFileOutput("diagaudio.wav", Context.MODE_PRIVATE); String state = Environment.getExternalStorageState(); Log.d(TAG, "External storage state: " + state); if (Environment.MEDIA_MOUNTED.equals(state)) { //create firstsign directory File rootPath = new File(Environment.getExternalStorageDirectory(), "firstsign"); if (!rootPath.exists()) { rootPath.mkdirs(); Log.d(TAG, "mkdirs"); } File file = new File(rootPath, "hairclipaudio.wav"); file.createNewFile(); OutputStream os = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(os); DataOutputStream wf = new DataOutputStream(bos); wf.write("RIFF".getBytes()); wf.writeInt(Integer.reverseBytes(filesize - 8)); wf.write("WAVE".getBytes()); wf.write("fmt ".getBytes()); wf.writeInt(Integer.reverseBytes(fmtChunkSize)); wf.writeShort(Short.reverseBytes(format)); wf.writeShort(Short.reverseBytes(channels)); wf.writeInt(Integer.reverseBytes(sampleRate)); wf.writeInt(Integer.reverseBytes(byteRate)); wf.writeShort(Short.reverseBytes(blockalign)); wf.writeShort(Short.reverseBytes(bitsPerSample)); wf.write("data".getBytes()); wf.writeInt(Integer.reverseBytes(audiolen)); wf.write(ra); wf.close(); bos.close(); os.close(); Log.d(TAG, "wavefile write complete"); } else { Toast.makeText(this, "SDCard not mounted", Toast.LENGTH_LONG).show(); } //what do i do? } catch (Exception e) { Log.e(TAG, "exception in savewavefile"); e.printStackTrace(); } } public void showMessage(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } @Override public void onBackPressed() { if (mState == UART_PROFILE_CONNECTED) { Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); showMessage("Hairclip demo running in background.\n Disconnect to exit"); } else { new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle(R.string.popup_title) .setMessage(R.string.popup_message) .setPositiveButton(R.string.popup_yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }).setNegativeButton(R.string.popup_no, null).show(); } } }