Printing multiple times via Bluetooth Printer in Android - java

I am trying to print multiple times base on inputted integer. I can print now once at a time but after trying to print multiple times the result is always printing only 1 times, and sometimes it is not printing.
MainActivity.java
//This is my global variable for printing
BluetoothAdapter mBTAdapter;
BluetoothSocket mBTSocket = null;
Dialog dialogProgress;
String BILL, TRANS_ID;
String PRINTER_MAC_ID;
final String ERROR_MESSAGE = "There has been an error in printing the bill.";
//The copyPrint is a String Var which will contain the inputted integer and it will convert into Int so it will become copyPrintIs.
int copyPrintIs = Integer.parseInt(copyPrint);
for(int x = 1; x <= copyPrintIs; x++){
printNow(thePrinted);
//Call the printNow and repeat calling on it base on inputted integer
//The thePrinted will contain String Text which will become the result of printing
}
and here is my code when the printNow function is called
public void printNow(String thePrintedvalue) {
try {
PRINTER_MAC_ID = "00:12:F3:19:4D:D8";
BILL = thePrintedvalue; //thePrintedvalue will be pass on BILL Var
mBTAdapter = BluetoothAdapter.getDefaultAdapter();
dialogProgress = new Dialog(Ticketing.this);
try {
if (mBTAdapter.isDiscovering())
mBTAdapter.cancelDiscovery();
else
mBTAdapter.startDiscovery();
} catch (Exception e) {
Toast.makeText(this, "A: " + e, Toast.LENGTH_LONG).show();
}
System.out.println("BT Searching status :"
+ mBTAdapter.isDiscovering());
if (mBTAdapter == null) {
Toast.makeText(this, "Device has no bluetooth capability",
Toast.LENGTH_LONG).show();
} else {
if (!mBTAdapter.isEnabled()) {
Intent i = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(i, 0);
}
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(
BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
}
} catch (Exception e) {
Toast.makeText(this, "B: " + e, Toast.LENGTH_LONG).show();
}
}
/********/
public void printBillToDevice(final String address) {
mBTAdapter.cancelDiscovery();
try { BluetoothDevice mdevice = mBTAdapter.getRemoteDevice(address);
Method m = mdevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mBTSocket = (BluetoothSocket) m.invoke(mdevice, 1);
mBTSocket.connect();
OutputStream os = mBTSocket.getOutputStream();
os.flush();
os.write(BILL.getBytes());
System.out.println(BILL);
if (mBTAdapter != null)
mBTAdapter.cancelDiscovery();
mBTSocket.close();
setResult(RESULT_OK);
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
// Toast.makeText(BluetoothPrint.this, ERROR_MESSAGE,
// Toast.LENGTH_SHORT).show();
e.printStackTrace();
setResult(RESULT_CANCELED);
}
}
/********/
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("***" + device.getName() + " : "
+ device.getAddress());
if (device.getAddress().equalsIgnoreCase(PRINTER_MAC_ID)) {
mBTAdapter.cancelDiscovery();
dialogProgress.dismiss();
Toast.makeText(Ticketing.this,device.getName() + " Printing data", Toast.LENGTH_LONG).show();
printBillToDevice(PRINTER_MAC_ID);
}
}
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
}
}
};
All of the code above is inside on MainActivity.java.
I cant figure out where I need to put the loop so it will continue printing copies of paper.
Please help!

try this:
Remove the loop here.
for(int x = 1; x <= copyPrintIs; x++){
printNow(thePrinted);
//Call the printNow and repeat calling on it base on inputted integer
//The thePrinted will contain String Text which will become the result of printing
}
and then change this code
public void printBillToDevice(final String address) {
mBTAdapter.cancelDiscovery();
try { BluetoothDevice mdevice = mBTAdapter.getRemoteDevice(address);
Method m = mdevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mBTSocket = (BluetoothSocket) m.invoke(mdevice, 1);
mBTSocket.connect();
OutputStream os = mBTSocket.getOutputStream();
os.flush();
os.write(BILL.getBytes());
System.out.println(BILL);
if (mBTAdapter != null)
mBTAdapter.cancelDiscovery();
mBTSocket.close();
setResult(RESULT_OK);
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
// Toast.makeText(BluetoothPrint.this, ERROR_MESSAGE,
// Toast.LENGTH_SHORT).show();
e.printStackTrace();
setResult(RESULT_CANCELED);
}
}
to this code
public void printBillToDevice(final String address) {
mBTAdapter.cancelDiscovery();
try { BluetoothDevice mdevice = mBTAdapter.getRemoteDevice(address);
Method m = mdevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mBTSocket = (BluetoothSocket) m.invoke(mdevice, 1);
mBTSocket.connect();
//this will do the code
int copyPrintIs = Integer.parseInt(copyPrint);
for (int x = 1; x <= copyPrintIs; x++) {
OutputStream os = mBTSocket.getOutputStream();
os.flush();
os.write(BILL.getBytes());
System.out.println(BILL);
SystemClock.sleep(4000);//This will pause every 4 seconds after printing once and the continue and pause again
}
copyPrint = "1";//This will change the copyPrint back to 1 value
if (mBTAdapter != null)
mBTAdapter.cancelDiscovery();
mBTSocket.close();
setResult(RESULT_OK);
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
// Toast.makeText(BluetoothPrint.this, ERROR_MESSAGE,
// Toast.LENGTH_SHORT).show();
e.printStackTrace();
setResult(RESULT_CANCELED);
}
}

Related

Issue with Bluetooth through transferring data between Android and Arduino

As you can see I made an app which sends data from an Android device to a Bluetooth module. Everything works perfectly except for one little thing: every time I want to open the app I should've already turned on Bluetooth through my phone settings or the app will crash, and I have to reopen it after turning on Bluetooth so it will run properly.
I've designed a Bluetooth click listener button myself but it still crashes while I enable it via button.
Can you help me find the mistake in my code?
public class MainActivity extends AppCompatActivity {
private static final String TAG = "bluetooth1";
Button btnsend ;
EditText edttext ;
Button btnOnOff;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
// SPP UUID service
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// MAC-address of Bluetooth module (you must edit this line)
private static String address = "20:16:06:28:17:83";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnsend = (Button) findViewById(R.id.btnsend);
edttext = (EditText) findViewById(R.id.edttxt);
btnOnOff = (Button) findViewById(R.id.btnOnOff);
btAdapter = BluetoothAdapter.getDefaultAdapter();
btnOnOff.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (btAdapter.isEnabled()) {
btAdapter.disable();
Toast.makeText(getApplicationContext(), " Disabling Bluetooth", Toast.LENGTH_SHORT).show();
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,1);
Toast.makeText(getApplicationContext(), " Enabling Bluetooth", Toast.LENGTH_SHORT).show();
}
}
});
edttext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
edttext.setTransformationMethod(new NumericKeyBoardTransformationMethod());
btnsend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
String dataTransmit = edttext.getText().toString();
if (dataTransmit != null) {
sendData(dataTransmit);
} else {
Toast.makeText(getApplicationContext(), "Please type something first", Toast.LENGTH_SHORT).show();
}
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
if(Build.VERSION.SDK_INT >= 10) {
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, MY_UUID);
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Could not Insecure", Toast.LENGTH_SHORT).show();
}
}
return device.createRfcommSocketToServiceRecord(MY_UUID);
}
#Override
public void onResume() {
super.onResume();
// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. In this case we are using the
// UUID for SPP.
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e1) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e1.getMessage() + ".");
}
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
Toast.makeText(getBaseContext(), "Connecting", Toast.LENGTH_SHORT).show();
try {
btSocket.connect();
Toast.makeText(getBaseContext(), "Connecting Ok", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
}
}
// Create a data stream so we can talk to server.
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
}
}
#Override
public void onPause() {
super.onPause();
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
errorExit("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
}
}
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
}
}
private void errorExit(String title, String message) {
Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show();
finish();
}
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
if (address.equals("20:16:06:28:17:83"))
msg = msg + ".\n\nUpdate your server address from 20:16:06:28:17:83 to the correct address on line 35 in the java code";
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";
errorExit("Fatal Error", msg);
}
}
}
You have to check if BT is enabled. Try with this:
protected void checkBTState() {
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBtAdapter == null) {
String message = getResources().getText(R.string.bluetooth_not_supported).toString();
Toast.makeText(getBaseContext(), message, Toast.LENGTH_SHORT).show();
} else {
if (mBtAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
} else {
// Prompt user to turn on Bluetooth //
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
Put it in onResume
#Override
public void onResume() {
super.onResume();
checkBTState();
// ...
// some code
// ...
}

Bluetooth Connection between LeJOS EV3 and Android

I'm having trouble connecting my smartphone to my EV3 over bluetooth using an app.
My situation:
I'm developing an App to send simple Strings to the EV3 which runs with leJOS 0.9.1-aplu11.
My Problem is, I'm not really familiar with Bluetooth, so my app or my receiver-software doesn't work as well.
My goal:
My goal is to create a Listener on the EV3 which is permanant listening for Strings from the app and an App that sends the strings when I press a button.
I hope you can help me.
I'm from germany so don't wonder about my beautifull writing skills!
Here is my Code:
App:
public class MainActivity extends AppCompatActivity {
private final static String TAG = "MainActivity";
private BluetoothAdapter mBluetoothAdapter;
private static BluetoothDevice mDevice;
private Button mSendBN;
private final static String MY_UUID = "00001101-0000-1000-8000-00805f9b34fb";
private static BluetoothSocket mSocket = null;
private static String mMessage = "Stop";
private static PrintStream sender;
private void findBrick() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
.getBondedDevices();
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("EV3"))
this.mDevice = device;
}
}
private void initBluetooth() {
Log.d(TAG, "Checking Bluetooth...");
if (mBluetoothAdapter == null) {
Log.d(TAG, "Device does not support Bluetooth");
mSendBN.setClickable(false);
} else {
Log.d(TAG, "Bluetooth supported");
}
if (!mBluetoothAdapter.isEnabled()) {
mSendBN.setClickable(false);
Log.d(TAG, "Bluetooth not enabled");
} else {
Log.d(TAG, "Bluetooth enabled");
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(this, "SpeechRecognizer gestartet", Toast.LENGTH_SHORT).show();
setContentView(R.layout.activity_main);
mSendBN = (Button) findViewById(R.id.button);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
initBluetooth();
findBrick();
if (mDevice == null) {
mSendBN.setClickable(false);
Toast.makeText(this, "No Devices found or BT disabled", Toast.LENGTH_SHORT).show();
Log.d("onC", "Connected to " + mDevice);
}
try {
createSocket();
} catch (IOException e) {
e.printStackTrace();
}
startService();
}
private void startService() {
if (PermissionHandler.checkPermission(this, PermissionHandler.RECORD_AUDIO)) {
Intent i = new Intent(this, BackgroundRecognizerService.class);
startService(i);
}
}
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PermissionHandler.RECORD_AUDIO && grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startService();
}
}
}
public static void onSend(View view) throws IOException {
try {
OutputStream os = mSocket.getOutputStream();
sender = new PrintStream(os);
Log.d("onSend", "Message = " + mMessage);
sender.println(mMessage);
sender.flush();
Log.d("onSend", "Message sent");
mSocket.close();
Log.d("onSend", "Socket closed");
} catch (IllegalStateException | NullPointerException e) {
e.printStackTrace();
}
}
public void createSocket() throws IOException {
try {
UUID uuid = UUID.fromString(MY_UUID);
mSocket = mDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
Log.d("createSocket", "Adapter");
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
mSocket.connect();
OutputStream os = mSocket.getOutputStream();
sender = new PrintStream(os);
Log.d("createSocket", "Fertig, " + "Socket: " + mSocket + " Sender: " + sender + " OutputStream: " + os + " mDevice: " + mDevice.getName());
}
protected void onDestroy() {
super.onDestroy();
Log.d("onDestroy", "App beendet");
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("onDestroy", "App vollständig beendet");
}
}
EV3:
public class BTJ {
public static void main(String[] args) {
BTConnector connector = new BTConnector();
System.out.println("0. Auf Signal warten");
NXTConnection conn = connector.waitForConnection(0, NXTConnection.RAW);
InputStream is = conn.openInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String message = "";
while (true){
System.out.println("1. Schleife gestartet");
message = "";
try {
message = br.readLine();
System.out.println("2. Message: " + message);
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
}
}
I have the answer..!
public class BTJ {
public static void main(String[] args) {
BTConnector connector = new BTConnector();
System.out.println("0. Auf Signal warten");
NXTConnection conn = connector.waitForConnection(0, NXTConnection.RAW);
InputStream is = conn.openInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is), 1);
String message = "";
while (true){
System.out.println("1. Schleife gestartet");
message = "";
try {
message = br.readLine();
System.out.println("2. Message: " + message);
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
}

Handle stream of data sensor

I'm trying to write a code I can write all the results values from accelerometer sensor into a .txt file. I can't write all the data in somehow. I think there is a problem in my loop. It is just reading about 10 to 15 samples.
How can I write all the values of the sensor into that file until I toggle off the button to stop? here is the code I wrote.
Thanks in advance!
public class MainActivity extends Activity implements SensorEventListener {
public SensorManager sm;
Sensor accelermeter;
private static final String DEBUG = "LogAccelermeter";
ToggleButton OnStore;
Button OffStore;
Button btnOn, btnOff;
TextView txtArduino, txtString, txtStringLength, sensorView0, sensorView1, sensorView2, sensorView3;
Handler bluetoothIn;
final int handlerState = 0; //used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
TextView sensorText;
// String for MAC address
private static String address;
private GestureDetectorCompat mDetector;
FileOutputStream fileOutputStream;
double TotalAccelerate;
ArrayList<Double> list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<Double>();
//Link the buttons and textViews to respective views
btnOn = (Button) findViewById(R.id.buttonOn);
btnOff = (Button) findViewById(R.id.buttonOff);
txtString = (TextView) findViewById(R.id.txtString);
txtStringLength = (TextView) findViewById(R.id.testView1);
sensorView0 = (TextView) findViewById(R.id.sensorView0);
sensorView1 = (TextView) findViewById(R.id.sensorView1);
sensorView2 = (TextView) findViewById(R.id.sensorView2);
sensorView3 = (TextView) findViewById(R.id.sensorView3);
//for Accelermeter
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorText = (TextView) findViewById(R.id.sensor);
accelermeter = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sm.registerListener(this, accelermeter, SensorManager.SENSOR_DELAY_NORMAL);
mDetector = new GestureDetectorCompat(this, new MyGestureListener());
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
File Root = Environment.getExternalStorageDirectory();
File dir = new File(Root.getAbsolutePath() + "/MyApp");
if (!dir.exists()) {
dir.mkdir();
}
File file = new File(dir, "MyMessage.txt");
try {
fileOutputStream = new FileOutputStream(file, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "SDcard not found", Toast.LENGTH_LONG).show();
}
OnStore = (ToggleButton) findViewById(R.id.onStore);
OnStore.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (OnStore.isChecked()){
try {
for(double TotalAccelerate : list){
// System.out.println("final"+ TotalAccelerate);
String space = "\n";
byte[] convert = space.getBytes();
fileOutputStream.write(convert);
String finalData;
finalData = String.valueOf(TotalAccelerate);
fileOutputStream.write(finalData.getBytes());
Log.i(DEBUG, "ans: " + finalData);
}
// fileOutputStream.close();
Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}if (!OnStore.isChecked()){
try {
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOutputStream.close();
list.clear();
Collections.synchronizedList(list);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
}
}
});
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { //if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
recDataString.append(readMessage); //keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string
txtString.setText("Data Received = " + dataInPrint);
int dataLength = dataInPrint.length(); //get length of data received
txtStringLength.setText("String Length = " + String.valueOf(dataLength));
if (recDataString.charAt(0) == '#') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, 5); //get sensor value from string between indices 1-5
String sensor1 = recDataString.substring(6, 10); //same again...
String sensor2 = recDataString.substring(11, 15);
String sensor3 = recDataString.substring(16, 20);
sensorView0.setText(" Sensor 0 Voltage = " + sensor0 + "V"); //update the textviews with sensor values
sensorView1.setText(" Sensor 1 Voltage = " + sensor1 + "V");
sensorView2.setText(" Sensor 2 Voltage = " + sensor2 + "V");
sensorView3.setText(" Sensor 3 Voltage = " + sensor3 + "V");
}
recDataString.delete(0, recDataString.length()); //clear all string data
// strIncom =" ";
dataInPrint = " ";
}
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
// Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
btnOff.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("0"); // Send "0" via Bluetooth
Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
}
});
btnOn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("1"); // Send "1" via Bluetooth
Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
}
});
}//end OnCreate Method
#Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
#Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
double xx = event.values[0];
double yy = event.values[1];
double zz = event.values[2];
TotalAccelerate = Math.round(Math.sqrt(Math.pow(xx, 2)
+ Math.pow(yy, 2)
+ Math.pow(zz, 2)));
Log.i(DEBUG, "Accelerometer = " + TotalAccelerate);
list.add(TotalAccelerate);
findPeaks(list);
sensorText.setText("Total: " + TotalAccelerate);
Log.i(DEBUG, "list values " + list);
}
//Find peak values.
public static ArrayList<Double> findPeaks(List<Double> points) {
ArrayList<Double> peaks = new ArrayList<Double>();
if (points == null || points.size() < 1)
return peaks;
Double x1_n_ref = 0.0;
int alpha = 0; //0=down, 1=up.
int size = points.size();// -1)/100;
for (int i = 0; i < size; i += 5) {
Double IndexValues = points.get(i);
if (IndexValues > 9) {
Double delta = (x1_n_ref - IndexValues);
if (delta < 0) {
x1_n_ref = IndexValues;
alpha = 1;
} else if (alpha == 1 && delta > 0) {
peaks.add(x1_n_ref);
alpha = 0;
}
} else if (alpha == 0) {
x1_n_ref = IndexValues;
}
}
return peaks;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String DEBUG_TAG = "Gestures";
#Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG, "onDown: " + event.toString());
Toast.makeText(getApplication(), "OnDown Touch Occur", Toast.LENGTH_LONG).show();
if (event.getX() > 0) {
mConnectedThread.write("1");
}
return true;
}
#Override
public void onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
mConnectedThread.write("0");
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
//creates secure outgoing connecetion with BT device using UUID
}
#Override
public void onResume() {
super.onResume();
//Get MAC address from DeviceListActivity via intent
Intent intent = getIntent();
//Get the MAC address from the DeviceListActivty via EXTRA
address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//create device and set the MAC address
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
//I send a character when resuming.beginning transmission to check device is connected
//If it is not an exception will be thrown in the write method and finish() will be called
mConnectedThread.write("x");
}
#Override
public void onPause() {
super.onPause();
try {
//Don't leave Bluetooth sockets open when leaving activity
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
//Checks that the Android device Bluetooth is available and prompts to be turned on if off
private void checkBTState() {
if (btAdapter == null) {
Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show();
} else {
if (btAdapter.isEnabled()) {
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
//create new class for connect thread
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
Could you try this for the toggle button onClick callback? It should write all the data when it's unchecked.
OnStore.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (OnStore.isChecked()){
// should do nothing
} else if (!OnStore.isChecked()){
try {
for(double TotalAccelerate : list){
//System.out.println("final"+ TotalAccelerate);
String space = "\n";
byte[] convert = space.getBytes();
fileOutputStream.write(convert);
String finalData;
finalData = String.valueOf(TotalAccelerate);
fileOutputStream.write(finalData.getBytes());
Log.i(DEBUG, "ans: " + finalData);
}
fileOutputStream.flush();
fileOutputStream.close();
Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
}
}
});
To regulate the code to start/stop listen to the sensor event, add the following variable somewhere in this class:
private boolean isListening = false;
And make the following modifications to your existing code:
OnStore.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (OnStore.isChecked()){
//
// set listening flag to true
//
isListening = true;
} else if (!OnStore.isChecked()){
//
// set listening flag to false
//
isListening = false;
try {
for(double TotalAccelerate : list){
//System.out.println("final"+ TotalAccelerate);
String space = "\n";
byte[] convert = space.getBytes();
fileOutputStream.write(convert);
String finalData;
finalData = String.valueOf(TotalAccelerate);
fileOutputStream.write(finalData.getBytes());
Log.i(DEBUG, "ans: " + finalData);
}
fileOutputStream.flush();
fileOutputStream.close();
Toast.makeText(getApplicationContext(), "Message saving", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Message Stopped.",Toast.LENGTH_LONG).show();
}
}
});
#Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
//
// regulate
//
if (isListening) {
double xx = event.values[0];
double yy = event.values[1];
double zz = event.values[2];
TotalAccelerate = Math.round(Math.sqrt(Math.pow(xx, 2)
+ Math.pow(yy, 2)
+ Math.pow(zz, 2)));
Log.i(DEBUG, "Accelerometer = " + TotalAccelerate);
list.add(TotalAccelerate);
findPeaks(list);
sensorText.setText("Total: " + TotalAccelerate);
Log.i(DEBUG, "list values " + list);
}
}

how to recognize only loud voice (words) with pocketsphinx on android

I am building android app which have to listen all the time (constantly) a voice and catch a key word like eg help. I am using now MediaRecorder to get an amplitude, then if is loud (eg 20000), I call pocketsphinx speechrecognizer. The problem is that when speechrecognizer caught (or not) the key word I can't jump back to MediaRecorder, the app is crashed. Of course my app must work in the background (24 h/day) so my implementation is in Service, so my MediaRecorder is in separate thread.
I know that pocketsphinx can check also the amplitude (a scream), but how to make it? And is pocketsphinx (get amplitude) better solution to trigger the speech recognizer? Below my class, I would be very appreciate for any help.
#Override
public IBinder onBind(Intent intent) {
return null;
}
private final class ServiceHandler extends Handler{
public ServiceHandler(Looper looper){
super(looper);
}
#Override
public void handleMessage(Message msg){
outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record.3gp";
getVoiceRecord();
}
}
#Override
public void onCreate() {
thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
//change to START_STICKY
Log.d("tag", "on start command");
Message msg = serviceHandler.obtainMessage();
msg.arg1 = startId;
serviceHandler.sendMessage(msg);
return Service.START_NOT_STICKY;
}
private void getVoiceRecord() {
startRecorder();
start = System.currentTimeMillis();
Log.d("tag", "Time started at " + start);
while (true){
if(recorder!=null){
amplitude = recorder.getMaxAmplitude();
if(amplitude>20000){
Toast.makeText(getApplicationContext(), "Scream detected",
Toast.LENGTH_LONG).show();
Log.d("tag", "Scream detected " + 20 * Math.log10(amplitude) + " amplitude: " + amplitude);
stopRecorder();
Log.d("tag", "Finish recording");
getSpeech();
}
finish = System.currentTimeMillis();
if(finish-start>50000){
//loop = false;
stopRecorder();
Log.d("tag", "Finish recording");
if(recorder==null){
recorder.reset();
startRecorder();
start = System.currentTimeMillis();
}
}
}
}//end of while loop
}
private void getSpeech() {
try {
Assets assets = new Assets(ScreamService.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
//return e;
}
reset();
}
private void stopRecorder() {
try{
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
Log.d("tag", "Stop recording");
}catch (IllegalStateException e) {
e.printStackTrace();
Log.d("tag", "Media Recorder did not stop " + e);
try {
Thread.sleep(2000);
recorder.stop();
recorder.release();
recorder = null;
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}catch (RuntimeException e) {
e.printStackTrace();
Log.d("tag", "Media Recorder did not stop " + e);
}
}
private void startRecorder() {
Log.d("tag", "Start recording... ");
try {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(outputFile);
recorder.prepare();
recorder.start();
} catch (IOException e) {
e.printStackTrace();
Log.d("tag", "Media Recorder did not start IOExeption " + e);
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d("tag", "Media Recorder did not start Ilegal State Trace" + e);
}
}
#Override
public void onDestroy() {
super.onDestroy();
recognizer.cancel();
recognizer.shutdown();
Toast.makeText(this, "Scream Service & recognizer Stopped.", Toast.LENGTH_SHORT).show();
}
#Override
public void onPartialResult(Hypothesis hypothesis) {
}
/**
* This callback is called when we stop the recognizer.
*/
#Override
public void onResult(Hypothesis hypothesis) {
if (hypothesis != null) {
String text = hypothesis.getHypstr();
//makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
Log.d("tag", "onResult " + text);
if(text.equals("help") || text.equals("help me")) {
recognizer.stop();
recognizer.cancel();
this.startService(new Intent(this, SendMessage.class));
getVoiceRecord();
}
}else {
Log.d("tag", "onResult is null");
}
}
#Override
public void onBeginningOfSpeech() {
//Log.d("tag", "onBeginningOfSpeech ");
}
#Override
public void onEndOfSpeech() {
counter++;
if(counter>5){
//recognizer.stop();
recognizer.cancel();
counter=0;
getVoiceRecord();
Log.d("tag", "Speech recognizer is killed");
}else {
//Log.d("tag", "onEndOfSpeech ");
reset();
}
}
private void reset() {
recognizer.stop();
recognizer.startListening("menu");
}
private void setupRecognizer(File assetsDir) throws IOException {
Log.d("tag", "default setup");
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// To disable logging of raw audio comment out this call (takes a lot of space on the device)
.setRawLogDir(assetsDir)
// Threshold to tune for keyphrase to balance between false alarms and misses
.setKeywordThreshold(1e-45f)
// Use context-independent phonetic search, context-dependent is too slow for mobile
.setBoolean("-allphone_ci", true)
.getRecognizer();
recognizer.addListener(this);
// Create grammar-based search for selection between demos
File menuGrammar = new File(assetsDir, "menu.gram");
recognizer.addGrammarSearch("menu", menuGrammar);
}
#Override
public void onError(Exception error) {
Log.d("tag", "error "+error.getMessage());
}
#Override
public void onTimeout() {
Log.d("tag", "onTimeout");
}
You can modify pocketsphinx sources to compute amplitude of recorded audio data before you pass it into recognizer. In SpeechRecognizer.java RecognizerThread class:
.........
while (!interrupted()
&& ((timeoutSamples == NO_TIMEOUT) || (remainingSamples > 0))) {
int nread = recorder.read(buffer, 0, buffer.length);
if (-1 == nread) {
throw new RuntimeException("error reading audio buffer");
} else if (nread > 0) {
// int max = 0;
// for (int i = 0; i < nread; i++) {
// max = Math.max(max, Math.abs(buffer[i]));
// }
// Log.e("!!!!!!!!", "Level is: " + max);
// You can decide to skip buffer here
decoder.processRaw(buffer, nread, false, false);
......

Restore purchases in In-app Billing (IAB Version 3) android

Google has upgraded to IAB3(In App Billing version 3).
First what a issue in example code.. super.onDestroy() is missed.
I implemented v3 with the help of http://developer.android.com/google/play/billing/billing_integrate.html
It is tested on phone, does not work in emulator.It stuck in emulator.
My issue is, I did not see the API for restoring transactions. How can I restore purchases with IAB3? Is it mService.getPurchases(apiVersion, packageName, type, continuationToken). Has anyone tested this?? Does this returns purchased items from locally stored items or does it restore purchased items?
Uninstalling application does not have continuationToken. Should it be null?
And What about when the purchase state changes??
Please help!
Thanks in advance.
EDIT :
Google has updated the In app billing library and solved the super.onDestroy() issue.
They have also added some additional features.
To make item consumable you have to sent a consume request and you have to do that in separate thread.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1111) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
Logger.printMessage(TAG, "on activity result reponse"
+ responseCode, Logger.DEBUG);
if (resultCode == RESULT_OK && responseCode == 0) {
try {
JSONObject jo = new JSONObject(purchaseData);
String sku = jo.getString("productId");
String title = jo.getString("title");
addChipsToBalance(sku);
final String token = jo.getString("purchaseToken");
Toast.makeText(BuyChipsActivity.this,
"You have bought " + title + ". Enjoy the game!",
Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Logger.printMessage(TAG, "inside run", Logger.DEBUG);
try {
int response = mService.consumePurchase(3,
getPackageName(), token);
Logger.printMessage(TAG, "inside run response"
+ response, Logger.DEBUG);
} catch (RemoteException e) {
// TODO Auto-generated catch block
Logger.printMessage(TAG, "exception here 1",
Logger.DEBUG);
e.printStackTrace();
}
}
}).start();
// alert("You have bought the " + sku +
// ". Excellent choice, adventurer!");
} catch (JSONException e) {
// alert("Failed to parse purchase data.");
e.printStackTrace();
}
}
}
But sometimes consume request is not completed on google end so you may want to query the purchased item list and consume it with the purchase token. I did like this
private void showPreviousPurchases() {
Logger.printMessage(TAG, "previous purchases", Logger.DEBUG);
if (mService == null) {
Toast.makeText(this, "Something Went Wrong. Try later",
Toast.LENGTH_LONG).show();
return;
}
Bundle ownedItems = null;
;
try {
ownedItems = mService.getPurchases(3, getPackageName(), "inapp",
null);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (ownedItems == null) {
Logger.printMessage(TAG, "criical error ", Logger.DEBUG);
return;
}
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> ownedSkus = ownedItems
.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
ArrayList<String> purchaseDataList = ownedItems
.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
/* ArrayList<String> signatureList = ownedItems
.getStringArrayList("INAPP_DATA_SIGNATURE");
String continuationToken = ownedItems
.getString("INAPP_CONTINUATION_TOKEN");*/
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
Logger.printMessage(TAG, "json = " + purchaseData,
Logger.DEBUG);
// String signature = signatureList.get(i);
String sku = ownedSkus.get(i);
addChipsAndMakeItConsumable(purchaseData);
// do something with this purchase information
// e.g. display the updated list of products owned by user
}
// if continuationToken != null, call getPurchases again
// and pass in the token to retrieve more items
}
}
private void addChipsAndMakeItConsumable(String purchaseData) {
try {
JSONObject jo = new JSONObject(purchaseData);
String sku = jo.getString("productId");
// String title = jo.getString("title");
addChipsToBalance(sku);
final String token = jo.getString("purchaseToken");
Logger.printMessage(TAG, "id = " + sku, Logger.DEBUG);
Logger.printMessage(TAG, "inside run", Logger.DEBUG);
try {
int response = mService.consumePurchase(3, getPackageName(),
token);
Logger.printMessage(TAG, "inside run response" + response,
Logger.DEBUG);
} catch (RemoteException e) {
// TODO Auto-generated catch block
Logger.printMessage(TAG, "exception here 1", Logger.DEBUG);
e.printStackTrace();
}
// alert("You have bought the " + sku +
// ". Excellent choice, adventurer!");
} catch (JSONException e) {
// alert("Failed to parse purchase data.");
e.printStackTrace();
}
}
In your IabHelper.java which is an example in your /android-sdk/extras/google/play_billing/samples/ put this code to get all the item that has been purchased by the user. This will return an JSON array of purchased data. You can also used Purchase.java to parse with, which is available also in the samples folder.
public ArrayList<String> getAllPurchases() throws RemoteException{
Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(),"inapp", null);
int response = getResponseCodeFromBundle(ownedItems);
logDebug("Owned items response: " + String.valueOf(response));
if (response != BILLING_RESPONSE_RESULT_OK) {
logDebug("getPurchases() failed: " + getResponseDesc(response));
}
if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST)
|| !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST)
|| !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) {
logError("Bundle returned from getPurchases() doesn't contain required fields.");
}
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST);
return purchaseDataList;
}
And into your Main activity
public class MainActivity extends Activity{
private IabHelper mHelper;
private String arrayString;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHelper = new IabHelper(this,"YOUR PUBLIC KEY" );
mHelper.enableDebugLogging(true);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) { // Oh noes, there was a problem.
Toast.makeText(this,"Problem setting up in-app billing: " + result,Toast.LENGTH_LONG).show();
return;
}
arrayString=mHelper.getAllPurchases().toString();
Log.d("Purchases: ",""+arrayString);
array = new JSONArray(arrayString);
for (int i = 0; i < array.length(); i++) {
JSONObject row = array.getJSONObject(i);
productId=row.getString("productId"); //this will get the product id's that has been purchased.
Log.e("To be restored:", " PRODUCT ID's "+productId);
}
});
}
}
I hope this will help you. ^_^ Thanks.

Categories