Have a problem while developing an app based in the BluetoothChat example, but divided in 2 activities.
The main with bluetooth actions ()BTActivity
The chat (BTCommunication)
I have the BluetoothChatService too divided in the following files, but they aren't activities:
Transmission: All the Handler actions
ConnectThread
ConnectedThread
AccpetThread
The app finds de device, starts connecting it and then crashes. I'm trying to find out what i'm doing wrong comparing with the BluetoothChat App, but i don't find the problem.
07-23 10:58:43.076: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:43.076: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:43.086: D/BluetoothUtils(17279): isSocketAllowedBySecurityPolicy start : device null
07-23 10:58:43.086: W/BluetoothAdapter(17279): getBluetoothService() called with no BluetoothManagerCallback
07-23 10:58:43.106: E/SpannableStringBuilder(17279): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
07-23 10:58:43.106: E/SpannableStringBuilder(17279): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
07-23 10:58:43.116: D/AbsListView(17279): onDetachedFromWindow
07-23 10:58:43.116: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:43.116: D/AbsListView(17279): onDetachedFromWindow
07-23 10:58:43.116: D/AbsListView(17279): unregisterIRListener() is called
07-23 10:58:44.527: D/AndroidRuntime(17279): Shutting down VM
07-23 10:58:44.527: W/dalvikvm(17279): threadid=1: thread exiting with uncaught exception (group=0x41d58ac8)
07-23 10:58:44.537: E/AndroidRuntime(17279): FATAL EXCEPTION: main
07-23 10:58:44.537: E/AndroidRuntime(17279): java.lang.NullPointerException
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.example.btaplication.BTActivity$1.handleMessage(BTActivity.java:288)
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.os.Looper.loop(Looper.java:137)
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.app.ActivityThread.main(ActivityThread.java:5328)
07-23 10:58:44.537: E/AndroidRuntime(17279): at java.lang.reflect.Method.invokeNative(Native Method)
07-23 10:58:44.537: E/AndroidRuntime(17279): at java.lang.reflect.Method.invoke(Method.java:511)
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
07-23 10:58:44.537: E/AndroidRuntime(17279): at dalvik.system.NativeStart.main(Native Method)
07-23 10:58:55.428: I/Process(17279): Sending signal. PID: 17279 SIG: 9
/ Here the Main activity
public class BTActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button button1 = (Button) findViewById(R.id.boton1);
final Button button2 = (Button) findViewById(R.id.boton2);
final Button button4 = (Button) findViewById(R.id.boton4);
final Button button5 = (Button) findViewById(R.id.boton5);
button5.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
lanzarComunicacion (null);
}
});
GlobalVar.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (GlobalVar.mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LanzarBusqueda(null);
}
});
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!GlobalVar.mBluetoothAdapter.isDiscovering()) {
Context context = getApplicationContext();
CharSequence text = "MAKING YOUR DEVICE DISCOVERABLE";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
});
button4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GlobalVar.mBluetoothAdapter.disable();
Context context = getApplicationContext();
CharSequence text = "TURNING OFF BLUETOOTH";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, 15);
toast.show();
}
});
}
#Override
public void onStart() {
super.onStart();
if (!GlobalVar.mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, GlobalVar.REQUEST_ENABLE_BT);
}
else {
if (GlobalVar.mTransmission == null) setupCaller();
}
}
#Override
public void onResume() {
super.onResume();
if (GlobalVar.mTransmission != null) {
/**Only if the state is STATE_NONE, do we know that we haven't started already*/
if (GlobalVar.mTransmission.getState() == GlobalVar.STATE_NONE) {
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case GlobalVar.REQUEST_CONNECT_DEVICE:
/**When DeviceListActivity returns with a device to connect*/
if (resultCode == Activity.RESULT_OK) {
connectDevice(data);
}
case GlobalVar.REQUEST_ENABLE_BT:
/**When the request to enable Bluetooth returns*/
if (resultCode == Activity.RESULT_OK) {
/**Bluetooth is now enabled, so set up a chat session*/
setupCaller();
} else {
/**User did not enable Bluetooth or an error occurred*/
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
break;
}
}
private void connectDevice(Intent data) {
/**Get the device MAC address*/
String address = data.getExtras().getString(DeviceListDialog.EXTRA_DEVICE_ADDRESS);
/**Get the BluetoothDevice object*/
BluetoothDevice device = GlobalVar.mBluetoothAdapter.getRemoteDevice(address);
/**Attempt to connect to the device*/
try{
GlobalVar.mTransmission.connect(device);
}catch(Exception ex) {
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
/**Inflate the menu; this adds items to the action bar if it is present.*/
getMenuInflater().inflate(R.menu.bt, menu);
return true;
}
public void lanzarComunicacion (View view) {
Intent i = new Intent(this, BTCommunication.class);
startActivity(i);
}
public void LanzarBusqueda (View view) {
Intent serverintent = new Intent(this, DeviceListDialog.class);
startActivityForResult(serverintent, GlobalVar.REQUEST_CONNECT_DEVICE);
}
private final void setStatus(int resId) {
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(resId);
}
private final void setStatus(CharSequence subTitle) {
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(subTitle);
}
/**
* The Handler that gets information back from the Transmission
*/
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GlobalVar.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case GlobalVar.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, GlobalVar.mConnectedDeviceName));
GlobalVar.mConversationArrayAdapter.clear();
break;
case GlobalVar.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case GlobalVar.STATE_LISTEN:
case GlobalVar.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case GlobalVar.MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
/**construct a string from the buffer*/
String writeMessage = new String(writeBuf);
GlobalVar.mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case GlobalVar.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
/**construct a string from the valid bytes in the buffer*/
String readMessage = new String(readBuf, 0, msg.arg1);
GlobalVar.mConversationArrayAdapter.add(GlobalVar.mConnectedDeviceName+": " + readMessage);
break;
case GlobalVar.MESSAGE_DEVICE_NAME:
/**save the connected device's name*/
GlobalVar.mConnectedDeviceName = msg.getData().getString(GlobalVar.DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to " + GlobalVar.mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case GlobalVar.MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(GlobalVar.TOAST), Toast.LENGTH_SHORT).show();
break;
}
}
};
public void setupCaller() {
/**Initialize the Transmission to perform bluetooth connections*/
GlobalVar.mTransmission = new Transmission(this, mHandler);
}
}
/ The Chat Avtivity
public class BTCommunication extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**Set up the window layout*/
setContentView(R.layout.chat);
/**Start the Bluetooth chat services*/
GlobalVar.mTransmission.start();
setupChat(); //PROBAMOS A LLAMAR AQUI\\
}
public void setupChat() {
/**Initialize the array adapter for the conversation thread*/
GlobalVar.mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
GlobalVar.mConversationView = (ListView) findViewById(R.id.in);
GlobalVar.mConversationView.setAdapter(GlobalVar.mConversationArrayAdapter);
/**Initialize the compose field with a listener for the return key*/
GlobalVar.mOutEditText = (EditText) findViewById(R.id.edit_text_out);
GlobalVar.mOutEditText.setOnEditorActionListener(mWriteListener);
/**Initialize the send button with a listener that for click events*/
GlobalVar.mSendButton = (Button) findViewById(R.id.button_send);
GlobalVar.mSendButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
/**Send a message using content of the edit text widget*/
TextView view = (TextView) findViewById(R.id.edit_text_out);
String message = view.getText().toString();
sendMessage(message);
}
});
/**Initialize the Transmission to perform bluetooth connections*/
//Done it in BTActivity in the function "setupCaller()"\\
/**Initialize the buffer for outgoing messages*/
GlobalVar.mOutStringBuffer = new StringBuffer("");
}
#Override
public void onDestroy() {
super.onDestroy();
/**Stop the Bluetooth chat services*/
if (GlobalVar.mTransmission != null) GlobalVar.mTransmission.stop();
}
/**
* Sends a message.
* #param message A string of text to send.
*/
public void sendMessage(String message) {
/**Check that we're actually connected before trying anything*/
if (GlobalVar.mTransmission.getState() != GlobalVar.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
/**Check that there's actually something to send*/
if (message.length() > 0) {
/**Get the message bytes and tell the BluetoothChatService to write*/
byte[] send = message.getBytes();
GlobalVar.mTransmission.write(send);
/**Reset out string buffer to zero and clear the edit text field*/
GlobalVar.mOutStringBuffer.setLength(0);
GlobalVar. mOutEditText.setText(GlobalVar.mOutStringBuffer);
}
}
/**The action listener for the EditText widget, to listen for the return key*/
private final TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
/**If the action is a key-up event on the return key, send the message*/
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
return true;
}
};
}
/The Transmission file:
public class Transmission {
/**
* Constructor. Prepares a new session.
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public Transmission(Context context, Handler handler) {
GlobalVar.mAdapter = BluetoothAdapter.getDefaultAdapter();
GlobalVar.mState = GlobalVar.STATE_NONE;
GlobalVar.mHandler = handler;
}
/**
* Set the current state of the connection
* #param state An integer defining the current connection state
*/
public synchronized void setState(int state) {
GlobalVar.mState = state;
/**Give the new state to the Handler so the UI Activity can update*/
GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state.
*/
public synchronized int getState() {
return GlobalVar.mState;
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
/**Cancel any thread attempting to make a connection*/
if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;}
/**Cancel any thread currently running a connection*/
if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;}
setState(GlobalVar.STATE_LISTEN);
/**Start the thread to listen on a BluetoothServerSocket*/
if (GlobalVar.mAcceptThread == null) {
GlobalVar.mAcceptThread = new AcceptThread();
GlobalVar.mAcceptThread.start();
}
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* #param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
/**Cancel any thread attempting to make a connection*/
if (GlobalVar.mState == GlobalVar.STATE_CONNECTING) {
if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;}
}
/**Cancel any thread currently running a connection*/
if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;}
/**Start the thread to connect with the given device*/
GlobalVar.mConnectThread = new ConnectThread(device);
GlobalVar.mConnectThread.start();
setState(GlobalVar.STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
/**Cancel the thread that completed the connection*/
if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;}
/**Cancel any thread currently running a connection*/
if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;}
/**Cancel the accept thread because we only want to connect to one device*/
if (GlobalVar.mAcceptThread != null) {
GlobalVar.mAcceptThread.cancel();
GlobalVar.mAcceptThread = null;
}
/**Start the thread to manage the connection and perform transmissions*/
GlobalVar.mConnectedThread = new ConnectedThread(socket);
GlobalVar.mConnectedThread.start();
/**Send the name of the connected device back to the UI Activity*/
Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(GlobalVar.DEVICE_NAME, device.getName());
msg.setData(bundle);
GlobalVar.mHandler.sendMessage(msg);
setState(GlobalVar.STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (GlobalVar.mConnectThread != null) {
GlobalVar.mConnectThread.cancel();
GlobalVar.mConnectThread = null;
}
if (GlobalVar.mConnectedThread != null) {
GlobalVar.mConnectedThread.cancel();
GlobalVar.mConnectedThread = null;
}
if (GlobalVar.mAcceptThread != null) {
GlobalVar.mAcceptThread.cancel();
GlobalVar.mAcceptThread = null;
}
setState(GlobalVar.STATE_NONE);
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
/**Create temporary object*/
ConnectedThread r;
/**Synchronize a copy of the ConnectedThread*/
synchronized (this) {
if (GlobalVar.mState != GlobalVar.STATE_CONNECTED) return;
r = GlobalVar.mConnectedThread;
}
/**Perform the write unsynchronized*/
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
public void connectionFailed() {
/**Send a failure message back to the Activity*/
Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(GlobalVar.TOAST, "Unable to connect device");
msg.setData(bundle);
GlobalVar.mHandler.sendMessage(msg);
/**tart the service over to restart listening mode*/
Transmission.this.start();
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
public void connectionLost() {
/**Send a failure message back to the Activity*/
Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(GlobalVar.TOAST, "Device connection was lost");
msg.setData(bundle);
GlobalVar.mHandler.sendMessage(msg);
/**Start the service over to restart listening mode*/
Transmission.this.start();
}
}
/The Accept, connect and connected threads are the same as in BleutoothChat app but each one has it's own file.
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.example.btaplication.BTActivity$1.handleMessage(BTActivity.java:288)
You need more condition in your Handler. It crashes because you have a null pointer in your BTActivity.
I exactly had this problem 2 weeks ago (I was trying to change text of a textview in a Handler). So, in my Handler I just put :
if(mTextView == null) {mTextView = (TextView) findViewById(R.id.tv)}
even if mTextView was define before. In that case you will be sure that your attribute is define, and you will avoid NPE
Hope it helps
Related
I am using following UsbSerial example from below link https://github.com/felHR85/SerialPortExample. I want receive data from over usb from the device shown in the photo.
Device is basically a counter machine which is sending counter data over serial port.
I am able to connect device and open port from it but unable to read data stream from it. Below is the code used. code is not giving any error
Mainactivity class
public class MainActivity extends AppCompatActivity {
/*
* Notifications from UsbService will be received here.
*/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
};
private UsbService usbService;
private TextView display;
private EditText editText;
private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((UsbService.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new MyHandler(this);
display = (TextView) findViewById(R.id.textView1);
editText = (EditText) findViewById(R.id.editText1);
Button sendButton = (Button) findViewById(R.id.buttonSend);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!editText.getText().toString().equals("")) {
String data = editText.getText().toString();
if (usbService != null) { // if UsbService was correctly binded, Send data
display.append(data);
usbService.write(data.getBytes());
}
}
}
});
}
#Override
public void onResume() {
super.onResume();
setFilters(); // Start listening notifications from UsbService
startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(mUsbReceiver);
unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
if (!UsbService.SERVICE_CONNECTED) {
Intent startService = new Intent(this, service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
startService(startService);
}
Intent bindingIntent = new Intent(this, service);
bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(UsbService.ACTION_NO_USB);
filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
registerReceiver(mUsbReceiver, filter);
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg) {
mActivity.get().display.append("Handle:");
switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String data = (String) msg.obj;
mActivity.get().display.append(data);
break;
}
}
}
}
I know it's bit late, however just to help others who might come across similar issue, did you find solution to your problem? If not, I cannot see the other java file corresponding to the service (USBService.java) as described in the example referred by you. The same file contains following code snippet which you would like to debug to find out what's going wrong (could be a problem with byte to string conversion or so). Hope this helps.
/*
* Data received from serial port will be received here. Just populate onReceivedData with your code
* In this particular example. byte stream is converted to String and send to UI thread to
* be treated there.
*/
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback()
{
#Override
public void onReceivedData(byte[] arg0)
{
try
{
String data = new String(arg0, "UTF-8");
if(mHandler != null)
mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT,data).sendToTarget();
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
};
I am developing an android application which requires me to send data to a Bluetooth Low Energy device.After the connection event is successful and after I receive a call back message I want to change the activity and display new GUI where on switch click I want to send data to connected device. The problem is after the activity has changed my BluetoothGatt becomes null and BluetoothGattCharacteristic also becomes null and i am not able to send the data. how can I solve this issue? Below is my code main class which onResume calls the connection activity and connects to first available device and after connection is successful it receives callback message and changes the activity.
public class MainActivity extends Activity implements BluetoothLeUart.Callback {
public TextView messages;
private BluetoothLeUart uart;
public void writeLine(final CharSequence text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
messages.append(text);
messages.append("\n");
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messages = (TextView) findViewById(R.id.messages);
// Initialize UART.
uart = new BluetoothLeUart(getApplicationContext());
messages.setMovementMethod(new ScrollingMovementMethod());
}
#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
protected void onResume() {
super.onResume();
writeLine("Scanning for devices ...");
uart.registerCallback(this);
uart.connectFirstAvailable();
}
#Override
protected void onStop() {
super.onStop();
uart.unregisterCallback(this);
uart.disconnect();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// UART Callback event handlers.
// UART Callback event handlers.
#Override
public void onConnected(BluetoothLeUart uart) {
// Called when UART device is connected and ready to send/receive data.
//messages.append("connected2");
writeLine("Connected!");
Intent intent = new Intent(MainActivity.this,SwitchClass.class);
startActivity(intent);
}
}
This is my codes BluetoothLeUart class which does connection activity and gives callback message.
public class BluetoothLeUart extends BluetoothGattCallback implements BluetoothAdapter.LeScanCallback {
// UUIDs for UART service and associated characteristics.
public static UUID UART_UUID = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
public static UUID TX_UUID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
public static UUID RX_UUID = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
// UUID for the UART BTLE client characteristic which is necessary for notifications.
public static UUID CLIENT_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
// UUIDs for the Device Information service and associated characeristics.
public static UUID DIS_UUID = UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb");
public static UUID DIS_MANUF_UUID = UUID.fromString("00002a29-0000-1000-8000-00805f9b34fb");
public static UUID DIS_MODEL_UUID = UUID.fromString("00002a24-0000-1000-8000-00805f9b34fb");
public static UUID DIS_HWREV_UUID = UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb");
public static UUID DIS_SWREV_UUID = UUID.fromString("00002a28-0000-1000-8000-00805f9b34fb");
// Internal UART state.
private Context context;
private WeakHashMap<Callback, Object> callbacks;
private BluetoothAdapter adapter;
private BluetoothGatt gatt;
private BluetoothGattCharacteristic tx;
private BluetoothGattCharacteristic rx;
private boolean connectFirst;
private boolean writeInProgress; // Flag to indicate a write is currently in progress
// Queues for characteristic read (synchronous)
private Queue<BluetoothGattCharacteristic> readQueue;
// Interface for a BluetoothLeUart client to be notified of UART actions.
public interface Callback {
public void onConnected(BluetoothLeUart uart);
public void onConnectFailed(BluetoothLeUart uart);
public void onDisconnected(BluetoothLeUart uart);
public void onReceive(BluetoothLeUart uart, BluetoothGattCharacteristic rx);
public void onDeviceFound(BluetoothDevice device);
public void onDeviceInfoAvailable();
}
public BluetoothLeUart(Context context) {
super();
this.context = context;
this.callbacks = new WeakHashMap<Callback, Object>();
this.adapter = BluetoothAdapter.getDefaultAdapter();
this.gatt = null;
this.tx = null;
this.rx = null;
this.disManuf = null;
this.disModel = null;
this.disHWRev = null;
this.disSWRev = null;
this.disAvailable = false;
this.connectFirst = false;
this.writeInProgress = false;
this.readQueue = new ConcurrentLinkedQueue<BluetoothGattCharacteristic>();
}
// Send data to connected UART device.
public void sendbyte(byte[] data) {
if (tx == null || data == null || data.length == 0) {
// Do nothing if there is no connection or message to send.
return;
}
// Update TX characteristic value. Note the setValue overload that takes a byte array must be used.
tx.setValue(data);
writeInProgress = true; // Set the write in progress flag
gatt.writeCharacteristic(tx);
// ToDo: Update to include a timeout in case this goes into the weeds
while (writeInProgress); // Wait for the flag to clear in onCharacteristicWrite
gatt.readCharacteristic(rx);
}
// Send data to connected UART device.
public void send(String data) {
if (data != null && !data.isEmpty()) {
sendbyte(data.getBytes(Charset.forName("UTF-8")));
}
}
// Register the specified callback to receive UART callbacks.
public void registerCallback(Callback callback) {
callbacks.put(callback, null);
}
// Unregister the specified callback.
public void unregisterCallback(Callback callback) {
callbacks.remove(callback);
}
// Disconnect to a device if currently connected.
public void disconnect() {
if (gatt != null) {
gatt.disconnect();
}
gatt = null;
tx = null;
rx = null;
}
// Stop any in progress UART device scan.
public void stopScan() {
if (adapter != null) {
adapter.stopLeScan(this);
}
}
// Start scanning for BLE UART devices. Registered callback's onDeviceFound method will be called
// when devices are found during scanning.
public void startScan() {
if (adapter != null) {
adapter.startLeScan(this);
}
}
// Connect to the first available UART device.
public void connectFirstAvailable() {
// Disconnect to any connected device.
disconnect();
// Stop any in progress device scan.
stopScan();
// Start scan and connect to first available device.
connectFirst = true;
startScan();
}
// Handlers for BluetoothGatt and LeScan events.
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothGatt.STATE_CONNECTED) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// Connected to device, start discovering services.
if (!gatt.discoverServices()) {
// Error starting service discovery.
connectFailure();
}
else {
notifyOnConnected(this);
}
}
else {
// Error connecting to device.
connectFailure();
}
}
else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
// Disconnected, notify callbacks of disconnection.
rx = null;
tx = null;
notifyOnDisconnected(this);
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
// Notify connection failure if service discovery failed.
if (status == BluetoothGatt.GATT_FAILURE) {
connectFailure();
return;
}
// Save reference to each UART characteristic.
tx = gatt.getService(UART_UUID).getCharacteristic(TX_UUID);
rx = gatt.getService(UART_UUID).getCharacteristic(RX_UUID);
// Save reference to each DIS characteristic.
disManuf = gatt.getService(DIS_UUID).getCharacteristic(DIS_MANUF_UUID);
disModel = gatt.getService(DIS_UUID).getCharacteristic(DIS_MODEL_UUID);
disHWRev = gatt.getService(DIS_UUID).getCharacteristic(DIS_HWREV_UUID);
disSWRev = gatt.getService(DIS_UUID).getCharacteristic(DIS_SWREV_UUID);
// Add device information characteristics to the read queue
// These need to be queued because we have to wait for the response to the first
// read request before a second one can be processed (which makes you wonder why they
// implemented this with async logic to begin with???)
readQueue.offer(disManuf);
readQueue.offer(disModel);
readQueue.offer(disHWRev);
readQueue.offer(disSWRev);
// Request a dummy read to get the device information queue going
// gatt.readCharacteristic(disManuf);
// Setup notifications on RX characteristic changes (i.e. data received).
// First call setCharacteristicNotification to enable notification.
if (!gatt.setCharacteristicNotification(rx, true)) {
// Stop if the characteristic notification setup failed.
connectFailure();
return;
}
// Next update the RX characteristic's client descriptor to enable notifications.
BluetoothGattDescriptor desc = rx.getDescriptor(CLIENT_UUID);
if (desc == null) {
// Stop if the RX characteristic has no client descriptor.
connectFailure();
return;
}
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
if (!gatt.writeDescriptor(desc)) {
// Stop if the client descriptor could not be written.
connectFailure();
return;
}
// Notify of connection completion.
notifyOnConnected(this);
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
notifyOnReceive(this, characteristic);
}
#Override
public void onCharacteristicRead (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
//Log.w("DIS", characteristic.getStringValue(0));
// Check if there is anything left in the queue
BluetoothGattCharacteristic nextRequest = readQueue.poll();
if(nextRequest != null){
// Send a read request for the next item in the queue
// gatt.readCharacteristic(nextRequest);
}
else {
// We've reached the end of the queue
disAvailable = true;
// notifyOnDeviceInfoAvailable();
}
}
else {
//Log.w("DIS", "Failed reading characteristic " + characteristic.getUuid().toString());
}
}
#Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
// Log.d(TAG,"Characteristic write successful");
}
writeInProgress = false;
}
#Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
// Stop if the device doesn't have the UART service.
if (!parseUUIDs(scanRecord).contains(UART_UUID)) {
//main.writeLine("Parse UUID failed...");
//main.messages.append("Parse UUID failed...");
return;
}
// Connect to first found device if required.
if (connectFirst) {
// Stop scanning for devices.
stopScan();
// Prevent connections to future found devices.
connectFirst = false;
// Connect to device.
gatt = device.connectGatt(context, true, this);
}
}
// Private functions to simplify the notification of all callbacks of a certain event.
private void notifyOnConnected(BluetoothLeUart uart) {
for (Callback cb : callbacks.keySet()) {
if (cb != null) {
cb.onConnected(uart);
}
}
}
private List<UUID> parseUUIDs(final byte[] advertisedData) {
List<UUID> uuids = new ArrayList<UUID>();
int offset = 0;
while (offset < (advertisedData.length - 2)) {
int len = advertisedData[offset++];
if (len == 0)
break;
// main.writeLine(advertisedData.toString());
int type = advertisedData[offset++];
switch (type) {
case 0x02: // Partial list of 16-bit UUIDs
case 0x03: // Complete list of 16-bit UUIDs
//main.writeLine("case 02,03...");
// main.messages.append("case 02,03...");
while (len > 1) {
int uuid16 = advertisedData[offset++];
uuid16 += (advertisedData[offset++] << 8);
len -= 2;
uuids.add(UUID.fromString(String.format("%08x-0000-1000-8000-00805f9b34fb", uuid16)));
}
break;
case 0x06:// Partial list of 128-bit UUIDs
case 0x07:// Complete list of 128-bit UUIDs
// Loop through the advertised 128-bit UUID's.
//main.writeLine("case 06,07...");
// main.messages.append("case 06,07...");
while (len >= 16) {
try {
// Wrap the advertised bits and order them.
ByteBuffer buffer = ByteBuffer.wrap(advertisedData, offset++, 16).order(ByteOrder.LITTLE_ENDIAN);
long mostSignificantBit = buffer.getLong();
long leastSignificantBit = buffer.getLong();
uuids.add(new UUID(leastSignificantBit,
mostSignificantBit));
} catch (IndexOutOfBoundsException e) {
// Defensive programming.
//Log.e(LOG_TAG, e.toString());
continue;
} finally {
// Move the offset to read the next uuid.
offset += 15;
len -= 16;
}
}
break;
default:
//main.writeLine("case default...");
// main.messages.append("case default");
offset += (len - 1);
break;
}
}
return uuids;
}
}
Here is my class from where I send the data
public class SwitchClass extends Activity {
public TextView messages;
public Switch Switch1;
public byte[] switchData = {'U','1','1','1','0','0','2','Z'};
private BluetoothLeUart uart;
public void writeLine(final CharSequence text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
messages.append(text);
messages.append("\n");
//messages.setText("anirudh");
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.switchlayout);
Switch1 = (Switch) findViewById(R.id.switch1);
uart = new BluetoothLeUart(getApplicationContext());
Switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
switchString = new String(switchData);
writeLine(switchString);
// send this array 8 bytes to BLE
sendData(switchString);
}
}
});
public void sendData(String sendVal) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(sendVal.toCharArray(), 0, 8);
uart.send(stringBuilder.toString());
}
You are creating a service from this activity and you are destroying it onStop
so your service is now been disconnected , so automatically you cant get bluetoothgatt and adapter for it
I suggest you to have child fragment inside you activity so your service will stay alive and you can have as many fragment you want to display the thing !!
Hopes this will help you !!
you can visit https://github.com/captain-miao/bleYan, It's a simple BLE library and example.
I also got exactly the same error like yours. In my case I comment out or deleted the following line under onServiceDiscover method. It works suddenly.It may not be the answer, Hope it will give you some clue to solve.
disManuf = gatt.getService(DIS_UUID).getCharacteristic(DIS_MANUF_UUID);
disModel = gatt.getService(DIS_UUID).getCharacteristic(DIS_MODEL_UUID);
disHWRev = gatt.getService(DIS_UUID).getCharacteristic(DIS_HWREV_UUID);
disSWRev = gatt.getService(DIS_UUID).getCharacteristic(DIS_SWREV_UUID);
readQueue.offer(disManuf);
readQueue.offer(disModel);
readQueue.offer(disHWRev);
readQueue.offer(disSWRev);
You must set to synchronized your BluetoothGatt Object like
public void setBluetoothGatt(BluetoothGatt gatt) {
synchronized (this) {
this.bluetoothGatt = gatt;
}
}
because BluetoothGatt throw DeadObject Exception when you change the Activity
I am working on the Bluetooth based project.I am using tabs for including different pages.While including button onclick listener the app is crashed. I referred bluetooth chat from sdk. In Setupchat() I am trying to identify buttons and assigning onclicklisteners. But the app crashed at the onclicklistner. I checked logcat Its showing null pointer exception. Here is the logcat output.
08-11 16:25:08.003: E/AndroidRuntime(16481): FATAL EXCEPTION: main
08-11 16:25:08.003: E/AndroidRuntime(16481): Process: com.dispenser, PID: 16481
08-11 16:25:08.003: E/AndroidRuntime(16481): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dispenser/com.dispenser.MainActivity}: java.lang.NullPointerException
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.access$800(ActivityThread.java:139)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.os.Handler.dispatchMessage(Handler.java:102)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.os.Looper.loop(Looper.java:136)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.main(ActivityThread.java:5086)
08-11 16:25:08.003: E/AndroidRuntime(16481): at java.lang.reflect.Method.invokeNative(Native Method)
08-11 16:25:08.003: E/AndroidRuntime(16481): at java.lang.reflect.Method.invoke(Method.java:515)
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
08-11 16:25:08.003: E/AndroidRuntime(16481): at dalvik.system.NativeStart.main(Native Method)
08-11 16:25:08.003: E/AndroidRuntime(16481): Caused by: java.lang.NullPointerException
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.dispenser.MainActivity.setupChat(MainActivity.java:223)
08-11 16:25:08.003: E/AndroidRuntime(16481): at com.dispenser.MainActivity.onStart(MainActivity.java:195)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1194)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.Activity.performStart(Activity.java:5258)
08-11 16:25:08.003: E/AndroidRuntime(16481): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2171)
08-11 16:25:08.003: E/AndroidRuntime(16481): ... 11 more
I know when this nullpointerexception comes. if i use the button without identify the button, The nullpointerexception raises. But I really don't know what is this. Please help me out.
This is the 195th line and 223
package com.dispenser;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.dispenser.adapter.TabsPagerAdapter;
public class MainActivity extends FragmentActivity implements ActionBar.TabListener, OnClickListener {
private ViewPager viewPager;
private TabsPagerAdapter mTabAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Diagnostic", "Set" ,"Settings"};
// Debugging
private static final String TAG = "Main";
private static final boolean D = true;
// Message types sent from the BluetoothChatService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothChatService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
// Layout Views
//private TextView mTitle;
private EditText mPS1,mPS2,mPS3,mFT,mFW,valve1,valve2,sPS1,sPS2,sPS3;
private Button mSendButtonOn,mEnable,mDisable,mSet;
private Button mSendButtonOff;
// Name of the connected device
private String mConnectedDeviceName;
// String buffer for outgoing messages
private StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter;
// Member object for the chat services
private ChatService mChatService;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (D) {
Log.e(TAG, "+++ ON CREATE +++");
}
// Set up the window layout
//requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_main);
// getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
// R.layout.custom_title);
// Set up the custom title
// mTitle = (TextView) findViewById(R.id.title_left_text);
// mTitle.setText(R.string.app_name);
// mTitle = (TextView) findViewById(R.id.title_right_text);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available",
Toast.LENGTH_LONG).show();
finish();
return;
}
// Initialization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mTabAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mTabAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
// Launch the DeviceListActivity to see devices and do scan
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
#Override
public void onStart() {
super.onStart();
if (D) {
Log.e(TAG, "++ ON START ++");
}
// If BT is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
} else {
if (mChatService == null) {
setupChat();
}
}
}
private void setupChat() {
mSet=(Button) findViewById(R.id.setBtn);
Log.d(TAG, "setupChat()");
// Diagnostic
mPS1=(EditText) findViewById(R.id.ps1);
mPS2=(EditText) findViewById(R.id.ps2);
mPS3=(EditText) findViewById(R.id.ps3);
mFT=(EditText) findViewById(R.id.ft);
mFW=(EditText) findViewById(R.id.fw);
valve1=(EditText) findViewById(R.id.valve1);
valve2=(EditText) findViewById(R.id.valve2);
//Set
sPS1=(EditText) findViewById(R.id.pressure1);
sPS2=(EditText) findViewById(R.id.pressure2);
sPS3=(EditText) findViewById(R.id.pressure3);
// mSet.setOnClickListener(MainActivity.this);
// Preference
// mSendButtonOff.setOnClickListener(MainActivity.this);
// Initialize the BluetoothChatService to perform bluetooth connections
mChatService = new ChatService(this, mHandler);
// Initialize the buffer for outgoing messages
mOutStringBuffer = new StringBuffer("");
}
#Override
public synchronized void onResume() {
super.onResume();
if (D) {
Log.e(TAG, "+ ON RESUME +");
}
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity
// returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't
// started already
if (mChatService.getState() == ChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
#Override
public synchronized void onPause() {
super.onPause();
if (D) {
Log.e(TAG, "- ON PAUSE -");
}
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
if (mChatService != null) {
mChatService.stop();
}
if (D) {
Log.e(TAG, "--- ON DESTROY ---");
}
}
private void ensureDiscoverable() {
if (D) {
Log.d(TAG, "ensure discoverable");
}
if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(
BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
/**
* Sends a message.
*
* #param message
* A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != ChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
.show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// XXX !!!
message = message + "\r\n"; // terminate for pc bluetooth spp server
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
// mOutEditText.setText(mOutStringBuffer);
}
}
// The Handler that gets information back from the BluetoothChatService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (D) {
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
}
switch (msg.arg1) {
case ChatService.STATE_CONNECTED:
Toast.makeText(getBaseContext(), R.string.title_connected_to+" " +mConnectedDeviceName, Toast.LENGTH_LONG).show();
// mTitle.append();
// mConversationArrayAdapter.clear();
break;
case ChatService.STATE_CONNECTING:
Toast.makeText(getBaseContext(), R.string.title_connecting, Toast.LENGTH_LONG).show();
break;
case ChatService.STATE_LISTEN:
case ChatService.STATE_NONE:
Toast.makeText(getBaseContext(), R.string.title_not_connected, Toast.LENGTH_LONG).show();
//mTitle.setText();
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
// mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
final String readMessage = new String(readBuf, 0, 50);
// mConversationArrayAdapter.add(mConnectedDeviceName + ": "
// + readMessage);
Runnable done = new Runnable()
{
public void run()
{
String[] b=readMessage.split(",");
for(int i=0;i<b.length;i++){
// Toast.makeText(getBaseContext(), b[i], Toast.LENGTH_SHORT).show();
if(b[i].contains("PS1")){
String[] c=b[i].split("=");
if(c.length==2){
mPS1.setText(c[1]);
}
}
else if(b[i].contains("PS2")){
String[] c=b[i].split("=");
if(c.length==2){
mPS2.setText(c[1]);
}
}
else if(b[i].contains("PS3")){
String[] c=b[i].split("=");
if(c.length==2){
mPS3.setText(c[1]);
}
}
else if(b[i].contains("LPM")){
String[] c=b[i].split("=");
if(c.length==2){
mFW.setText(c[1]);
}
}
else{
}
// mPS1.append(b[i]);
}
}
};
done.run();
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(),
"Connected to " + mConnectedDeviceName,
Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(),
msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
.show();
break;
}
}
};
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (D) {
Log.d(TAG, "onActivityResult " + resultCode);
}
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras().getString(
DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter
.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupChat();
} else {
// User did not enable Bluetooth or an error occured
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.setBtn:
if(sPS1.getText().length()!=0){
float pressure1=Float.parseFloat(sPS1.getText().toString());
if(pressure1>0.0F && pressure1<20.0F)
sendMessage("PS1="+pressure1);
}
else{
sPS1.setError("Enter PS1");
}
if(sPS2.getText().length()!=0){
float pressure2=Float.parseFloat(sPS2.getText().toString());
if(pressure2>0.0F && pressure2<20.0F)
sendMessage("PS2="+pressure2);
}
else{
sPS2.setError("Enter PS2");
}
if(sPS3.getText().length()!=0){
float pressure3=Float.parseFloat(sPS3.getText().toString());
if(pressure3>0.0F && pressure3<20.0F)
sendMessage("PS3="+pressure3);
}
else{
sPS3.setError("Enter PS3");
}
break;
default:
break;
}
}
}
You haven't instantiated your button
To use the onClickListener() of button, you should make it's instance in java file
From question: If i use the button without identify the button
You need to do the following:
Button button = (Button) findViewById(R.id.button_identity);
Bottom Line: You should have identity either from XML or from java code.
Hope it works.
The mistake what I made is I tried to include onclicklistener in Mainactivity Instead of including each tab activity. I removed the onclick listener from MainActivity and identify the button and included onclicklistner in corresponding activity tab. Thats solved my problem.
I am trying to solve a particular problem when I am calling another Activity from my main Activity to get the result.
My main concern is a variable in the DeviceListActivity named bToggle, which is being modified by a broadcast receiver, and the same variable is being sent to the MainActivity, which I am failing to get.
This is my MainActivity class which call another Activity to get the result:
public class MainActivity extends Activity{
public void someMethod(){
Runnable runnableBlueDeviceList = new Runnable(){
public void run() {
Intent BlueIntent = new Intent(MainActivity.this, DeviceListActivity.class);
startActivityForResult(BlueIntent, 13);
}
};
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// if(DEBUG) Log.d(LOG_TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case 13:
// When DeviceListActivity returns with a device MAC adress to connect
// But it may be alive or dead
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
device_address = data.getExtras().getString("device_address");
device_toggle = data.getIntExtra("device_toggle", 0);
// Attempt to connect to the device
if(device_toggle==1) {
changeMenuItem();
} else {
scanFlag=0;
device_address=null;
showToast(getApplicationContext(), "BLUTOOTH DEVICE NOT ACTIVE");
}
} else if (resultCode == Activity.RESULT_CANCELED) {
scanFlag=0;
device_address = null;
showToast(getApplicationContext(), "BLUTOOTH CONNECTION CANCELLED, " + "\n(OR) \nBLUTOOTH DEVICE NOT COMPATIBLE");
}
break;
}
}
}
DeviceListActivity has a variable bToggle which is being modified by a BroadcastReceiver and sent to the MainActivity through intents:
public class DeviceListActivity extends Activity {
// Debugging
private static final String TAG = "DeviceListActivity";
private static final boolean D = true;
// Return Intent extra
public static int bToggle = 0;
// The on-click listener for all devices in the ListViews
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
// Cancel discovery because it's costly and we're about to connect
mBtAdapter.cancelDiscovery();
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = " ";
if(info.length()>16)
address = info.substring(info.length() - 17);
// If the text view contains no devices found then dont proceed
if(info.contains("No devices found")) {
} else if (address.startsWith("00")) {
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra("device_address", address);
intent.putExtra("device_toggle", bToggle);
// Set result and finish this Activity
setResult(Activity.RESULT_OK , intent);
finish();
} else {
// Set result CANCELED incase the user tries to connect to other devices
setResult(Activity.RESULT_CANCELED);
finish();
}
}
};
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
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);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
scanButton.setVisibility(View.VISIBLE);
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setProgressBarIndeterminateVisibility(false);
setTitle(R.string.select_device);
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
mNewDevicesArrayAdapter.add(noDevices);
scanButton.setVisibility(View.VISIBLE);
}
} else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
//Device is now connected
bToggle = 1;
showToast(getApplicationContext(), "BLUTOOTH CONNECTION SUCCESS-FULL");
} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
//Device has disconnected
bToggle = 0;
showToast(getApplicationContext(), "BLUTOOTH NOT-CONNECTED");
}
}
};
So the main problem is I cannot get the variable bToggle
I am beginner to Android programming, I am doing my final project and I need to develop a packet sniffing application. I found some code on internet, and am trying to extended it into my project. But getting FATAL EXCEPTION: main and following errors.
Here is the code:
public class Main extends Activity {
// Variable declarations for handling the view items in the layout.
private Button start_button;
private Button stop_button;
private Button read_button;
private EditText parameters;
// Variable declarations for handling the TCPdump process.
private TCPdump tcpdump = null;
private TCPdumpHandler tcpDumpHandler = null;
private SharedPreferences settings = null;
// Variable declarations for handling the options and reader activities.
private Intent optionsIntent = null;
private Intent readerIntent = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Associating the items in the view to the variables.
start_button = (Button) findViewById(R.id.start_button);
stop_button = (Button) findViewById(R.id.stop_button);
read_button = (Button) findViewById(R.id.read_button);
parameters = (EditText) findViewById(R.id.params_text);
// Accessing the app's preferences.
settings = getSharedPreferences(GlobalConstants.prefsName, 0);
// Extracting the TCPdump binary to the app folder.
if (RootTools.installBinary(Main.this, R.raw.tcpdump, "tcpdump") == false) {
new AlertDialog.Builder(Main.this)
.setTitle(R.string.extraction_error)
.setMessage(R.string.extraction_error_msg)
.setNeutralButton(R.string.ok, null).show();
}
// Creating a new TCPdump object.
tcpdump = new TCPdump();
// Creating a TCPdump handler for the TCPdump object created after.
tcpDumpHandler = new TCPdumpHandler(tcpdump, this, this, true);
// Obtaining the command from the options that were saved last time
// Shark was running.
tcpDumpHandler.generateCommand();
start_button.setOnClickListener(new OnClickListener() {
// Setting the action to perform when the start button is pressed.
public void onClick(View v) {
startTCPdump();
}
});
stop_button.setOnClickListener(new OnClickListener() {
// Setting the action to perform when the stop button is pressed.
public void onClick(View v) {
stopTCPdump();
}
});
read_button.setOnClickListener(new OnClickListener() {
// Setting the action to perform when the open in reader button is
// pressed.
public void onClick(View v) {
launchReader();
}
});
BroadcastReceiver connectionReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Setting the action to be performed when the network status
// changes.
if ((tcpDumpHandler.checkNetworkStatus() == false)
&& (tcpdump.getProcessStatus())) {
stopTCPdump();
new AlertDialog.Builder(Main.this)
.setTitle(
getString(R.string.network_connection_down))
.setMessage(
getString(R.string.network_connection_down_msg))
.setNeutralButton(getString(R.string.ok), null)
.show();
}
}
};
// Registering the BroadcastReceiver and associating it with the
// connectivity change event.
registerReceiver(connectionReceiver, new IntentFilter(
"android.net.conn.CONNECTIVITY_CHANGE"));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Setting the action to perform when returning to this activity from
// another activity which had been called.
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == 1) {
if (tcpdump.getProcessStatus()) {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.settings_changed))
.setMessage(getString(R.string.settings_changed_msg))
.setNeutralButton(getString(R.string.ok), null).show();
}
tcpDumpHandler.generateCommand();
}
}
#Override
public void onDestroy() {
// Setting the action to perform when the Android O.S. kills this
// activity.
if (tcpdump.getProcessStatus()) {
stopTCPdump();
}
}
public boolean onCreateOptionsMenu(Menu menu) {
// This code makes the activity to show a menu when the device's menu
// key is pressed.
menu.add(0, 0, 0, getString(R.string.options_text));
menu.add(0, 1, 0, getString(R.string.about_text));
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
// Setting the action to perform when an option from the menu is
// selected.
switch (item.getItemId()) {
case 0:
optionsIntent = new Intent(Main.this, Options.class);
startActivityForResult(optionsIntent, 1);
return true;
case 1:
new AlertDialog.Builder(Main.this).setTitle(R.string.about_text)
.setMessage(getString(R.string.about_shark))
.setNeutralButton(getString(R.string.ok), null).show();
return true;
}
return false;
}
/**
* Calls TCPdumpHandler to try start the packet capture.
*/
private void startTCPdump() {
if (tcpDumpHandler.checkNetworkStatus()) {
switch (tcpDumpHandler.start(parameters.getText().toString())) {
case 0:
Toast.makeText(Main.this, getString(R.string.tcpdump_started),
Toast.LENGTH_SHORT).show();
break;
case -1:
Toast.makeText(Main.this,
getString(R.string.tcpdump_already_started),
Toast.LENGTH_SHORT).show();
break;
case -2:
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.device_not_rooted_error))
.setMessage(
getString(R.string.device_not_rooted_error_msg))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -4:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.command_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -5:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.outputstream_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
default:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.unknown_error))
.setNeutralButton(getString(R.string.ok), null).show();
}
} else {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.network_connection_error))
.setMessage(
getString(R.string.network_connection_error_msg))
.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
startActivity(new Intent(
Settings.ACTION_WIRELESS_SETTINGS));
}
}).setNegativeButton(getString(R.string.no), null)
.show();
}
}
/**
* Calls TCPdumpHandler to try to stop the packet capture.
*/
private void stopTCPdump() {
switch (tcpDumpHandler.stop()) {
case 0:
Toast.makeText(Main.this, getString(R.string.tcpdump_stoped),
Toast.LENGTH_SHORT).show();
break;
case -1:
Toast.makeText(Main.this,
getString(R.string.tcpdump_already_stoped),
Toast.LENGTH_SHORT).show();
break;
case -2:
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.device_not_rooted_error))
.setMessage(getString(R.string.device_not_rooted_error_msg))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -4:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.command_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -5:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.outputstream_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -6:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.close_shell_error))
.setNeutralButton(getString(R.string.ok), null).show();
break;
case -7:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.process_finish_error))
.setNeutralButton(getString(R.string.ok), null).show();
default:
new AlertDialog.Builder(Main.this).setTitle("Error")
.setMessage(getString(R.string.unknown_error))
.setNeutralButton(getString(R.string.ok), null).show();
}
}
/**
* Tries to launch the reader activity.
*/
private void launchReader() {
readerIntent = new Intent(Main.this, Reader.class);
if (FileManager.checkFile(GlobalConstants.dirName,
settings.getString("fileText", "shark_capture.pcap"))) {
if (tcpdump.getProcessStatus() == false) {
startActivity(readerIntent);
} else {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.capture_in_progress_error))
.setMessage(
getString(R.string.capture_in_progress_error_msg))
.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0,
int arg1) {
stopTCPdump();
startActivity(readerIntent);
}
})
.setNegativeButton(getString(R.string.no), null).show();
}
} else {
new AlertDialog.Builder(Main.this)
.setTitle(getString(R.string.file_error))
.setMessage(getString(R.string.file_error_msg))
.setNeutralButton(getString(R.string.ok), null).show();
}
}
}
when I run this Eclipse, I receive an error in the log cat the following errors. I tried a lot of solution that has been suggested, even then I couldn't get solution.
08-21 15:38:01.483: D/AndroidRuntime(499): Shutting down VM
08-21 15:38:01.483: W/dalvikvm(499): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
08-21 15:38:01.504: E/AndroidRuntime(499): FATAL EXCEPTION: main
08-21 15:38:01.504: E/AndroidRuntime(499): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shark/com.shark.Main}: java.lang.NullPointerException
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.os.Handler.dispatchMessage(Handler.java:99)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.os.Looper.loop(Looper.java:123)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-21 15:38:01.504: E/AndroidRuntime(499): at java.lang.reflect.Method.invokeNative(Native Method)
08-21 15:38:01.504: E/AndroidRuntime(499): at java.lang.reflect.Method.invoke(Method.java:521)
08-21 15:38:01.504: E/AndroidRuntime(499): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-21 15:38:01.504: E/AndroidRuntime(499): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-21 15:38:01.504: E/AndroidRuntime(499): at dalvik.system.NativeStart.main(Native Method)
08-21 15:38:01.504: E/AndroidRuntime(499): Caused by: java.lang.NullPointerException
08-21 15:38:01.504: E/AndroidRuntime(499): at com.shark.TCPdumpHandler.generateCommand(TCPdumpHandler.java:322)
08-21 15:38:01.504: E/AndroidRuntime(499): at com.shark.Main.onCreate(Main.java:93)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-21 15:38:01.504: E/AndroidRuntime(499): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
08-21 15:38:01.504: E/AndroidRuntime(499): ... 11 more
I found where exactly the error is occurring. According that, the "closeShell" is returning null in the following code. which further loops back to three classes.
public class RootShell {
protected Process process = null;
protected DataOutputStream os = null;
protected DataInputStream is = null;
private boolean deviceRooted = false;
/**
* RootShell class constructor. Checks if the device is rooted.
*/
public RootShell() {
deviceRooted = checkRootStatus();
}
/**
* RootShell class destructor. Closes the shell if its not already closed.
*/
protected void finalize() {
if (process != null)
closeShell();
}
/**
* Opens a root shell and waits for commands.
*
* #return 0 Everything went OK.<br>
* -1 The shell has already been opened.<br>
* -2 The device isn't rooted.<br>
* -3 IOException when running the su command.
*/
public int openShell() {
if (process == null) {
if (deviceRooted) {
// Trying to get root access.
try {
process = Runtime.getRuntime().exec("su");
} catch (IOException e) {
return -3;
}
// Getting an output stream to the root shell for introducing
// commands.
os = new DataOutputStream(process.getOutputStream());
// Getting an input stream to the root shell for displaying
// results.
is = new DataInputStream(process.getInputStream());
return 0;
} else
return -2;
} else
return -1;
}
/**
* Runs the command in the root shell.
*
* #param command
* The command which will be executed in the root shell.
* #return 0 Everything went OK.<br>
* -1 The shell wasn't opened.<br>
* -2 The device isn't rooted.<br>
* -4 IOException when running the user command.<br>
* -5 IOException when flushing the DataOutputStream.
*/
public int runCommand(String command) {
if (process != null) {
if (deviceRooted) {
try {
os.writeBytes(command + "\n");
} catch (IOException e) {
return -4;
}
try {
os.flush();
} catch (IOException e) {
return -5;
}
return 0;
} else
return -2;
} else
return -1;
}
/**
* Closes a shell which is already open.
*
* #return -1 The shell wasn't opened.<br>
* -2 The device isn't rooted.<br>
* -6 IOException when running the exit command.<br>
* -7 InterruptedException when waiting for the process to stop.
*/
public int closeShell() {
if (process != null) {
if (deviceRooted) {
try {
os.writeBytes("exit\n");
} catch (IOException e1) {
return -6;
}
try {
process.waitFor();
} catch (InterruptedException e) {
return -7;
}
process.destroy();
process = null;
os = null;
is = null;
return 0;
} else
return -2;
} else
return -1;
}
/**
* Checks if an Android device is rooted or not.<br>
* Code borrowed from: http://www
* .stealthcopter.com/blog/2010/01/android-requesting-root-access-in
* -your-app/
*
* #return true: The device is rooted.<br>
* false: The device isn't rooted.
*/
private static boolean checkRootStatus() {
Process p;
try {
// Preform su to get root privileges
p = Runtime.getRuntime().exec("su");
// Attempt to write a file to a root-only
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");
// Close the terminal
os.writeBytes("exit\n");
os.flush();
try {
p.waitFor();
if (p.exitValue() != 255) {
return true;
} else {
return false;
}
} catch (InterruptedException e) {
return false;
}
} catch (IOException e) {
return false;
}
}
/**
* #return A DataInputStream to the root shell.
*/
public DataInputStream getInputStream() {
return is;
}
/**
* #return A DataOutputStream to the root shell.
*/
public DataOutputStream getOutputStream() {
return os;
}
/**
* #return true if the shell is opened.<br>
* false if the shell isn't opened.
*/
public boolean getProcessStatus() {
if (process != null)
return true;
else
return false;
}
}
I also found that, it is giving "08-22 19:05:19.701: I/System.out(275): e1java.io.IOException: Broken pipe", the it enters try catch in "closeshell".
What is R in your R.id.start_button and multiple other places?
The error refers to tcpDumpHandler.generateCommand() but you don't provide the code for it.