I ve made a Service for Socket connection, send and return, and sometimes, It receive an information and block my thread, I don't know what.
At beginning, my thread status is RUNNABLE, and once, It become a loop and I ve BLOCKED status
If anyone have an idea or a remark on my service, I m don't sur if all is very good, but that's the better way I found for send and receive sockets messages..
Thanks
public class SocketService extends Service{
private final int SERVER_PORT = 6040;
static final int MSG_ID = 0x1337;
private final String TAG = SocketService.class.getSimpleName();
private final IBinder mBinder = new SocketBinder();
private String mClientMsg;
private String serverHost = Fonctions.getTxtIp() ; // server address
private Socket socket; // socket for the connection
private ServerSocket ss = null;
private serverListenerThread listenServerThread; // thread for listening to the server
private boolean connected = false;
private PrintWriter out;
private MainActivity main;
public class SocketBinder extends Binder{
public SocketService getService(){
return SocketService.this;
}
}
/**
* Thread d'Ècoute du port SERVER_PORT
*
*/
private class serverListenerThread extends Thread implements Runnable{
private boolean end = false; // Booleen pour finir le thread
public void run(){
Log.i(TAG, "Run ServerListenerThread " + SERVER_PORT);
Socket s = null;
try {
ss = new ServerSocket(SERVER_PORT );
} catch (IOException e) {
e.printStackTrace();
}
Log.i(TAG, listenServerThread.getState().toString() );
while(!end ){
Message m = new Message();
m.what = MSG_ID;
Log.i(TAG, listenServerThread.getState().toString() );
try {
if (s == null)
s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String st = null;
st = input.readLine();
mClientMsg = st;
if(mClientMsg != null)
notifyMsg(mClientMsg);
Log.i(TAG, "Reception Message : " + mClientMsg);
}catch(IOException e){
Log.i(TAG, e.getMessage() );
}
catch (Exception e) {
Log.i(TAG, "connection lost" + e.getMessage() );
}
}
}
public void end(){
Log.w(TAG, "End du Thread!");
end = true;
}
}
/***
* Notifier msg
*/
private void notifyMsg(String msg)
{
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pIntent);
mNotificationManager.notify(0, mBuilder.getNotification());
}
/**
* Connection au Server pour l'envoi d'un message
* #param host
*/
public void start(String host){
new Thread(new Runnable(){
public void run() {
listenServerThread = new serverListenerThread();
listenServerThread.start();
if(! connected){
if(connectServer())
{
Log.i(TAG, "Serverhost Ca Galope");
connected = true;
Log.i(TAG, listenServerThread.getState().toString() );
}
}
else {
Log.i(TAG, "Connected : " + connected);
connected = false;
}
}
}).start();
}
/**
* Connection au Server pour l'envoi d'un message
* #return Booleen
*/
private boolean connectServer(){
try {
InetAddress serverAddr = InetAddress.getByName(serverHost);
socket = new Socket(serverAddr, SERVER_PORT);
/* out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true );
out.println("0|ImHere");
out.flush();*/
Log.w(TAG, "Ouverture socket");
}catch (UnknownHostException e) {
Log.i(TAG, "Erreur connectServer()" + e.getMessage() );
e.printStackTrace();
}
catch (IOException e) {
Log.i(TAG, "Erreur connectServer()" + e.getMessage() );
return false;
}
return true;
}
/**
* Envoi du message via un PrintWriter
* #param msg
*/
public void sendMsg(final String msg){
new Thread(new Runnable() {
public void run() {
Log.i(TAG, "SendMsg : " + msg + connected);
if(!connected)
connectServer();
try {
Log.i(TAG, "print writer");
out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true );
out.println(msg);
out.flush();
} catch (IOException e) {
e.printStackTrace() ;
Log.i(TAG, e.getMessage() );
}
}
}).start();
}
public void setMainActivity(MainActivity main)
{
this.main = main;
}
public String getMessage(){
return mClientMsg;
}
public int onStartCommand(Intent intent)
{
Log.i(TAG, "Start command Service");
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return this.mBinder;
}
/**
* Is Connected?
* #return Booleen
*/
public boolean isConnected() {
Log.i(TAG, "isConnected : " + connected);
return connected;
}
/**
* Methode appelÈe ‡ la destruction du service
*/
public void onDestroy()
{
Log.i(TAG, "Destruction Service");
super.onDestroy();
}
/**
*
*/
public void end(){
Log.i(TAG, "Deconnexion Server");
listenServerThread.end();
connected = false;
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Related
I have foreground service acting as MQTT client. I'm using MqttAsyncClient mqttClient for this purpose.
I'm using QoS=1 on subscribe to topic:
mqttClient.subscribe("sensors/s1/", 1);
But in case my phone gets offline for some period of time it miss current period messages. Whole code is below.
Im my another application I'm using MqttAndroidClient mqttAndroidClient and in this case QoS=1 brings all missed messages.
mqttAndroidClient.subscribe(topic, 1, null, new IMqttActionListener() {...})
Why subscription with MqttAsyncClient with QoS=1 not retrieves all messages?
Whole code :
public class MqttGndService extends Service {
private String ip="ssl:myserver",port="8887";
private final IBinder mBinder = new LocalBinder();
private Handler mHandler;
private static final String TAG = "mqttservice";
private static boolean hasWifi = false;
private static boolean hasMmobile = false;
private ConnectivityManager mConnMan;
private volatile IMqttAsyncClient mqttClient;
private String uniqueID;
class MQTTBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
IMqttToken token;
boolean hasConnectivity = false;
boolean hasChanged = false;
NetworkInfo infos[] = mConnMan.getAllNetworkInfo();
for (int i = 0; i < infos.length; i++) {
if (infos[i].getTypeName().equalsIgnoreCase("MOBILE")) {
if ((infos[i].isConnected() != hasMmobile)) {
hasChanged = true;
hasMmobile = infos[i].isConnected();
}
Timber.tag(Utils.TIMBER_TAG).v( infos[i].getTypeName() + " is " + infos[i].isConnected());
} else if (infos[i].getTypeName().equalsIgnoreCase("WIFI")) {
if ((infos[i].isConnected() != hasWifi)) {
hasChanged = true;
hasWifi = infos[i].isConnected();
}
Timber.tag(Utils.TIMBER_TAG).v(infos[i].getTypeName() + " is " + infos[i].isConnected());
}
}
hasConnectivity = hasMmobile || hasWifi;
Timber.tag(Utils.TIMBER_TAG).v( "hasConn: " + hasConnectivity + " hasChange: " + hasChanged + " - " + (mqttClient == null || !mqttClient.isConnected()));
if (hasConnectivity && hasChanged && (mqttClient == null || !mqttClient.isConnected())) {
Timber.tag(Utils.TIMBER_TAG).v("Ready to connect");
doConnect();
Timber.tag(Utils.TIMBER_TAG).v("do connect done");
} else
{
Timber.tag(Utils.TIMBER_TAG).v("Connection not possible");
}
}
}
public class LocalBinder extends Binder {
public MqttGndService getService() {
// Return this instance of LocalService so clients can call public methods
return MqttGndService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void publish(String topic, MqttMessage message) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);// we create a 'shared" memory where we will share our preferences for the limits and the values that we get from onsensorchanged
try {
mqttClient.publish(topic, message);
} catch (MqttException e) {
e.printStackTrace();
}
}
#Override
public void onCreate() {
Timber.tag(Utils.TIMBER_TAG).v("Creating MQTT service");
mHandler = new Handler();//for toasts
IntentFilter intentf = new IntentFilter();
setClientID();
intentf.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new MQTTBroadcastReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
Timber.tag(Utils.TIMBER_TAG).v( "onConfigurationChanged()");
android.os.Debug.waitForDebugger();
super.onConfigurationChanged(newConfig);
}
#Override
public void onDestroy() {
super.onDestroy();
Timber.tag(Utils.TIMBER_TAG).v("Service onDestroy");
}
private void setClientID() {
uniqueID = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
Timber.tag(Utils.TIMBER_TAG).v("uniqueID=" + uniqueID);
}
private void doConnect() {
String broker = ip + ":" + port;
Timber.tag(Utils.TIMBER_TAG).v("mqtt_doConnect()");
IMqttToken token;
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setMaxInflight(100);//handle more messages!!so as not to disconnect
options.setAutomaticReconnect(true);
options.setConnectionTimeout(1000);
options.setKeepAliveInterval(300);
options.setUserName("cc50e3e91bf4");
options.setPassword("b".toCharArray());
try {
options.setSocketFactory(SocketFactoryMQ.getSocketFactory(this,""));
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
}
Timber.tag(Utils.TIMBER_TAG).v("set socket factory done");
try {
mqttClient = new MqttAsyncClient(broker, uniqueID, new MemoryPersistence());
token = mqttClient.connect(options);
token.waitForCompletion(3500);
mqttClient.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable throwable) {
try {
mqttClient.disconnectForcibly();
mqttClient.connect();
} catch (MqttException e) {
e.printStackTrace();
}
}
#Override
public void messageArrived(String topic, MqttMessage msg) throws Exception {
Timber.tag(Utils.TIMBER_TAG).v("Message arrived from topic " + topic+ " msg: " + msg );
}
#Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("published");
}
});
Timber.tag(Utils.TIMBER_TAG).v("will subscribe");
mqttClient.subscribe("sensors/s1/", 1);
} catch (MqttSecurityException e) {
Timber.tag(Utils.TIMBER_TAG).v("general connect exception");
e.printStackTrace();
} catch (MqttException e) {
switch (e.getReasonCode()) {
case MqttException.REASON_CODE_BROKER_UNAVAILABLE:
mHandler.post(new ToastRunnable("WE ARE OFFLINE BROKER_UNAVAILABLE!", 1500));
break;
case MqttException.REASON_CODE_CLIENT_TIMEOUT:
mHandler.post(new ToastRunnable("WE ARE OFFLINE CLIENT_TIMEOUT!", 1500));
break;
case MqttException.REASON_CODE_CONNECTION_LOST:
mHandler.post(new ToastRunnable("WE ARE OFFLINE CONNECTION_LOST!", 1500));
break;
case MqttException.REASON_CODE_SERVER_CONNECT_ERROR:
Timber.tag(Utils.TIMBER_TAG).v( "c " + e.getMessage());
e.printStackTrace();
break;
case MqttException.REASON_CODE_FAILED_AUTHENTICATION:
Intent i = new Intent("RAISEALLARM");
i.putExtra("ALLARM", e);
Timber.tag(Utils.TIMBER_TAG).v("b " + e.getMessage());
break;
default:
Timber.tag(Utils.TIMBER_TAG).v( "a " + e.getMessage() +" "+ e.toString());
}
}
mHandler.post(new ToastRunnable("WE ARE ONLINE!", 500));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timber.tag(Utils.TIMBER_TAG).v("onStartCommand");
String input = intent.getStringExtra(INTENT_ID);
Timber.tag(Utils.TIMBER_TAG).v("onStartCommand "+ input);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Example Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag");
wakeLock.acquire();
return START_STICKY;
}
}
You are setting cleansession to true (options.setCleanSession(true)); from the docs for setCleanSession:
If set to true the client and server will not maintain state across restarts of the client, the server or the connection. This means
Message delivery to the specified QOS cannot be maintained if the client, server or connection are restarted
The server will treat a subscription as non-durable
I think that the mqtt specs state this more clearly:
If CleanSession is set to 1, the Client and Server MUST discard any previous Session and start a new one. This Session lasts as long as the Network Connection. State data associated with this Session MUST NOT be reused in any subsequent Session
So when your application looses the connection the session is discarded and new messages will not be queued up for delivery. In addition unless you resubscribe when the connection comes back up you will not receive any additional messages.
However be aware that if you set cleansession to false then any new messages received while your client is offline will be queued for delivery (subject to the configuration of the broker) and this might not be what you want to happen if the client could be offline for a long time.
I'm trying to recieve/send data to arduino board using bluetooth, and I can connect to board from one activity. I know that I can make my other activities connect with bluetooth using service but I don't know how to make bluetooth as service. and i don't know how to send and recieve from it.
my Paired Devices code:
public class BTConnect extends AppCompatActivity {
private static final String TAG = "BTConnect";
ListView IdLista;
public static String EXTRA_DEVICE_ADDRESS = "device_address";
private BluetoothAdapter mBtAdapter;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_btconnect);
}
#Override
public void onResume()
{
super.onResume();
//---------------------------------
VerificarEstadoBT();
//
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.btconnect_nombre);
IdLista = (ListView)findViewById(R.id.Id2);
IdLista.setAdapter(mPairedDevicesArrayAdapter);
IdLista.setOnItemClickListener(mDeviceClickListener);
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
if (pairedDevices.size() > 0)
{
for (BluetoothDevice device: pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView av, View v, int arg2, long arg3) {
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
Intent i = new Intent(BTConnect.this, device.class);
i.putExtra(EXTRA_DEVICE_ADDRESS, address);
startActivity(i);
}
};
private void VerificarEstadoBT() {
mBtAdapter= BluetoothAdapter.getDefaultAdapter();
if(mBtAdapter==null) {
Toast.makeText(getBaseContext(), "the device can't connect to BT", Toast.LENGTH_SHORT).show();
} else {
if (mBtAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth Activation...");
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}}
And my first activity 'device' :
public class device extends AppCompatActivity {
Button IdEncender, IdApagar,IdDesconectar,IdReset;
ArrayList<String> addArray = new ArrayList<String>();
ListView show;
//-------------------------------------------
Handler bluetoothIn;
final int handlerState = 0;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder DataStringIN = new StringBuilder();
private ConnectedThread MyConexionBT;
// Identificador unico de servicio - SPP UUID
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String para la direccion MAC
private static String address = null;
//-------------------------------------------
#SuppressLint("HandlerLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device);
IdEncender = (Button) findViewById(R.id.IdEncender);
IdApagar = (Button) findViewById(R.id.IdApagar);
IdDesconectar = (Button) findViewById(R.id.IdDisconectar);
show = (ListView) findViewById(R.id.LIST1) ;
IdReset=(Button)findViewById(R.id.IdReset);
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
String readMessage = (String) msg.obj;
DataStringIN.append(readMessage);
int endOfLineIndex = DataStringIN.indexOf("#");
if (endOfLineIndex > 0) {
String dataInPrint = DataStringIN.substring(0, endOfLineIndex);
String newline = "\r\n";
DataStringIN.delete(0, DataStringIN.length());
//--List adapter--//
addArray.add(dataInPrint);
ArrayAdapter<String> adapter =new ArrayAdapter<String>(device.this, android.R.layout.simple_list_item_1, addArray);
show.setAdapter(adapter);
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
VerificarEstadoBT();
IdEncender.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
MyConexionBT.write("1");
}
});
IdApagar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MyConexionBT.write("0");
}
});
IdDesconectar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (btSocket!=null)
{
try {btSocket.close();}
catch (IOException e)
{ Toast.makeText(getBaseContext(), "Error", Toast.LENGTH_SHORT).show();;}
}
finish();
}
});
configurebutton();
}
private void configurebutton() {
Button startbutton = (Button)findViewById(R.id.Start);
startbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(device.this,chart.class));
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException
{
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}
#Override
public void onResume()
{
super.onResume();
Intent intent = getIntent();
address = intent.getStringExtra(BTConnect.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try
{
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "fail", Toast.LENGTH_LONG).show();
}
try
{
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {}
}
MyConexionBT = new ConnectedThread(btSocket);
MyConexionBT.start();
}
#Override
public void onPause()
{
super.onPause();
try
{
btSocket.close();
} catch (IOException e2) {}
}
private void VerificarEstadoBT() {
if(btAdapter==null) {
Toast.makeText(getBaseContext(), "error in bluetooth connection", Toast.LENGTH_LONG).show();
} else {
if (btAdapter.isEnabled()) {
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
public void savefile(String file, String text){
try {
FileOutputStream fos = openFileOutput(file, Context.MODE_APPEND);
fos.write(text.getBytes());
fos.close();
Toast.makeText(device.this, "saved!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(device.this,"error",Toast.LENGTH_LONG).show();
}
}
//Crea la clase que permite crear el evento de conexion
private class ConnectedThread extends Thread
{
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket)
{
InputStream tmpIn = null;
OutputStream tmpOut = null;
try
{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run()
{
byte[] buffer = new byte[256];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(String input)
{
try {
mmOutStream.write(input.getBytes());
}
catch (IOException e)
{
Toast.makeText(getBaseContext(), "fail to connect", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
If shortly move your connection/message_exchange logic to Thread/Runnable and start it from Service. You can exchange data between Service and Activity/Activities with BroadcastReceivers or Messenger. I also recommend you to use Bluetooth lib:
implementation 'me.aflak.libraries:bluetooth:1.3.4' this one already have inside thread so it is become easy to embed in your service.
Example code of service which use this lib and Messenger:
private ArrayList<Messenger> mClients = new ArrayList<>();
final private Messenger inComingMessenger = new Messenger(mIncomingHandler);
#SuppressLint("HandlerLeak")
final Handler mIncomingHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
Log.d(TAG, "handleMessage: new client connected. Total: " + mClients.size());
break;
case Constants.MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
Log.d(TAG, "handleMessage: client disconnected. Total: " + mClients.size());
break;
case Constants.MSG_YOUR_MESSAGE_TYPE:
String val = (String) msg.obj;
// stuff to do
break;
}
}
};
/**
* Send message to connected activities
*/
public void sendMessageToClients(int msgSignal, Object obj) {
if (mClients.size() == 0)
return;
sendMessage(mClients.get(0), Message.obtain(null, msgSignal, obj));
for (int i = 1; i < mClients.size(); i++) {
if (mClients.get(i) == null)
continue;
sendMessage(mClients.get(i), Message.obtain(null, msgSignal, obj));
}
}
/**
* Send message to binded activity
*/
private void sendMessage(Messenger msgr, Message msg) {
try {
msgr.send((msg));
} catch (RemoteException e) {
Log.e(TAG, "can't send message", e);
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d(TAG, "onStartCommand");
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return inComingMessenger.getBinder();
}
#Override
public void onCreate() {
super.onCreate();
bleDevices = new ArrayList<>();
if(bluetooth == null) {
bluetooth = new Bluetooth(this);
bluetooth.setBluetoothCallback(new BluetoothCallback() {
#Override
public void onBluetoothTurningOn() {}
#Override
public void onBluetoothOn() {}
#Override
public void onBluetoothTurningOff() {
bluetooth = null;
}
#Override
public void onBluetoothOff() { }
#Override
public void onUserDeniedActivation() {
// when using bluetooth.showEnableDialog()
// you will also have to call bluetooth.onActivityResult()
}
});
bluetooth.setDiscoveryCallback(new DiscoveryCallback() {
#Override public void onDiscoveryStarted() {
}
#Override public void onDiscoveryFinished() {
bleDevices.clear();
}
#Override public void onDeviceFound(BluetoothDevice device) {
if(bleDevices.indexOf(device)<0) {
bleDevices.add(device);
Log.d(TAG, "Found new device while scanning: "+device.getAddress());
sendMessageToClients(Constants.MSG_BLE_DEVICE_FOUND, device);
}
}
#Override public void onDevicePaired(BluetoothDevice device) {}
#Override public void onDeviceUnpaired(BluetoothDevice device) {}
#Override public void onError(String message) {
Log.e(TAG, "DiscoveryCallback onError "+message);
}
});
bluetooth.setDeviceCallback(new DeviceCallback() {
#Override public void onDeviceConnected(BluetoothDevice device) { }
#Override public void onDeviceDisconnected(BluetoothDevice device, String message) { }
#Override public void onMessage(String message) {
// Handle your message
yourHandleFunction(message.replaceAll(" ",""));
Log.d(TAG, message);
}
#Override public void onError(String message) {
Log.e(TAG, "DeviceCallback onError "+message);
}
#Override public void onConnectError(BluetoothDevice device, String message) { }
});
bluetooth.onStart();
}
connectToSavedDevice();
}
}
private void connectToSavedDevice() {
Log.d(TAG, "connectToSavedDevice state="+getState());
if(getState() != STATE_DISCONNECTED) return;
SharedPreferences pref = getSharedPreferences(App.TAG, 0);
String address = pref.getString(Constants.PREF_AUTO_CONNECT_TO_ADDRESS, null);
if(address == null) {
Log.d(TAG, "saved address==null start scan for devices");
scanDevices();
return;
}
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if(device!=null) {
Log.d(TAG, "device found try to connect/bound, connect to Arduino");
bluetooth.connectToAddress(address,false);
}
}
In activity implement ServiceConnection interface:
protected synchronized void unbindService() {
if (!isBound()) {
return;
}
// lock object (prevents access to service while disconnecting)
synchronized (outComingMessenger) {
sendMessageToService(Message.obtain(null, Constants.MSG_UNREGISTER_CLIENT));
unbindService(this);
outComingMessenger = null;
}
}
protected void bindService() {
bindService(mServiceIntent, this, BIND_AUTO_CREATE);
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
outComingMessenger = new Messenger(service);
final Message msg = Message.obtain(null, Constants.MSG_REGISTER_CLIENT);
msg.replyTo = inComingMessenger;
msg.obj = getClass().getSimpleName();
sendMessageToService(msg);
sendMessageToService(Constants.MSG_CHECK_IS_CONNECTION_READY);
}
#Override
public void onServiceDisconnected(ComponentName name) {
outComingMessenger = null;
bindService();
}
/**
* Send message to service
*/
protected void sendMessageToService(Message msg) {
if (!isBound()) {
return;
}
try {
msg.replyTo = inComingMessenger;
outComingMessenger.send(msg);
} catch (RemoteException e) {
}
}
/**
* Send simple message to connected service
* #param messageId
*/
protected void sendMessageToService(int messageId) {
sendMessageToService(Message.obtain(null, messageId));
}
/**
* Send simple message to connected service
* #param messageId
*/
protected void sendMessageToService(int messageId, Object obj) {
sendMessageToService(Message.obtain(null, messageId, obj));
}
/**
* Service is connected?
*/
protected final boolean isBound() {
return outComingMessenger != null;
}
#SuppressLint("HandlerLeak")
private final Handler mIncomingHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_YOUR_MESSAGE:
int res = (int) msg.obj;
break;
case Constants.MSG_CONNECTION_READY:
isReady = (boolean) msg.obj;
if(isReady) {
// show toast or what you want to do with the UI
} else {
// do something else
}
break;
case Constants.MSG_BLE_DEVICE_FOUND:
BluetoothDevice device = (BluetoothDevice)msg.obj;
SharedPreferences pref = getSharedPreferences(App.TAG, 0);
String deviceAddress = pref.getString(Constants.PREF_AUTO_CONNECT_TO_ADDRESS, null);
break;
}
}
};
final private Messenger inComingMessenger = new Messenger(mIncomingHandler);
I have the following implementation of ToyVpnService which I got frome here
public class ToyVpnService extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "ToyVpnService";
private Handler mHandler;
private Thread mThread;
private ParcelFileDescriptor mInterface;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The handler is only used to show messages.
if (mHandler == null) {
mHandler = new Handler(this);
}
// Stop the previous session by interrupting the thread.
if (mThread != null) {
mThread.interrupt();
}
// Start a new session by creating a new thread.
mThread = new Thread(this, "ToyVpnThread");
mThread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
if (mThread != null) {
mThread.interrupt();
}
}
#Override
public boolean handleMessage(Message message) {
if (message != null) {
Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
}
return true;
}
#Override
public synchronized void run() {
Log.i(TAG, "running vpnService");
try {
runVpnConnection();
} catch (Exception e) {
e.printStackTrace();
//Log.e(TAG, "Got " + e.toString());
} finally {
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = null;
mHandler.sendEmptyMessage(R.string.disconnected);
Log.i(TAG, "Exiting");
}
}
private boolean runVpnConnection() throws Exception {
configure();
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);
// We keep forwarding packets till something goes wrong.
while (true) {
// Assume that we did not make any progress in this iteration.
boolean idle = true;
// Read the outgoing packet from the input stream.
int length = in.read(packet.array());
if (length > 0) {
Log.i(TAG, "************new packet");
System.exit(-1);
while (packet.hasRemaining()) {
Log.i(TAG, "" + packet.get());
//System.out.print((char) packet.get());
}
packet.limit(length);
// tunnel.write(packet);
packet.clear();
// There might be more outgoing packets.
idle = false;
}
Thread.sleep(50);
}
}
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
Log.i(TAG, "****** INET ADDRESS ******");
Log.i(TAG, "address: " + inetAddress.getHostAddress());
Log.i(TAG, "hostname: " + inetAddress.getHostName());
Log.i(TAG, "address.toString(): " + inetAddress.getHostAddress().toString());
if (!inetAddress.isLoopbackAddress()) {
//IPAddresses.setText(inetAddress.getHostAddress().toString());
Log.i(TAG, "IS NOT LOOPBACK ADDRESS: " + inetAddress.getHostAddress().toString());
return inetAddress.getHostAddress().toString();
} else {
Log.i(TAG, "It is a loopback address");
}
}
}
} catch (SocketException ex) {
String LOG_TAG = null;
Log.e(LOG_TAG, ex.toString());
}
return null;
}
private void configure() throws Exception {
// If the old interface has exactly the same parameters, use it!
if (mInterface != null) {
Log.i(TAG, "Using the previous interface");
return;
}
// Configure a builder while parsing the parameters.
Builder builder = new Builder();
builder.setMtu(1500);
builder.addAddress(getLocalIpAddress(), 24);
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = builder.establish();
}
}
It seems to be receiving packets but I have no idea on how to read the data in the paclkets. the code seems to be incomplete (hence the tunnel.write(packet) that's commented out cause there isn't a variable tunnel). Is this the right way? or is there a better way of doing this?
I have been trying to connect to the MCU motherboard NOT using arduino to code, embedded with the Bluetooth ICU chips HC-06. I have successfully got good connection between my android device to the board. After that , I try to send "26 24 54 02 c9 00" as pure string. But, after for a long time, there is no response from the device. I have even checked with the AT command s to sent such as AT+NAMExyz , and AT. There is still no response from the device. Would you please tell me is there another any way out ? What else programming work I have to do besides onto Android devices? If I am not using the Arduino device to connected with,What else I have to observe and conduct the research? The below is my code.
The below is my logcat message
07-29 16:45:50.701: D/dalvikvm(26944): Late-enabling CheckJNI
07-29 16:45:50.721: I/dalvikvm(26944): Enabling JNI app bug workarounds for target SDK version 7...
07-29 16:45:53.501: D/BluetoothCommandService(26944): start
07-29 16:45:53.501: D/BluetoothCommandService(26944): setState() 0 -> 1
07-29 16:45:55.361: D/dalvikvm(26944): GC_FOR_ALLOC freed 100K, 1% free 17103K/17236K, paused 14ms, total 14ms
07-29 16:46:04.211: D/BluetoothCommandService(26944): connect to: 00:14:01:22:18:12
07-29 16:46:04.211: D/BluetoothCommandService(26944): setState() 1 -> 2
07-29 16:46:04.211: I/BluetoothCommandService(26944): BEGIN mConnectThread
07-29 16:46:04.211: W/BluetoothAdapter(26944): getBluetoothService() called with no BluetoothManagerCallback
07-29 16:46:04.211: D/BluetoothSocket(26944): connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[53]}
07-29 16:46:06.241: D/BluetoothCommandService(26944): connected
07-29 16:46:06.241: D/BluetoothCommandService(26944): create ConnectedThread
07-29 16:46:06.241: I/BluetoothCommandService(26944): BEGIN mConnectedThread
07-29 16:46:06.241: D/BluetoothCommandService(26944): setState() 2 -> 3
07-29 16:46:09.851: D/commmand(26944): &$R\x00\xc9
07-29 16:46:13.241: D/commmand(26944): &$R\x00\xc9
07-29 16:46:19.581: D/commmand(26944): &$V\x00\xcd
07-29 16:46:39.811: D/dalvikvm(26944): Debugger has detached; object registry had 1 entries
07-29 16:46:39.871: D/dalvikvm(26944): GC_CONCURRENT freed 48K, 1% free 17522K/17616K, paused 6ms+1ms, total 57ms
07-29 16:47:23.631: D/commmand(26944): &$R\x00\xc9
07-29 16:47:24.911: D/commmand(26944): &$R\x00\xc9
07-29 16:47:25.651: D/commmand(26944): &$R\x00\xc9
07-29 16:47:26.401: D/commmand(26944): &$V\x00\xcd
07-29 16:47:26.961: D/commmand(26944): &$R\x00\xc9
07-29 16:47:27.771: D/commmand(26944): &$R\x00\xc9
07-29 16:47:28.601: D/commmand(26944): &$R\x00\xc9
07-29 16:47:35.171: D/commmand(26944): &$R\x00\xc9
07-29 16:47:35.991: D/commmand(26944): &$R\x00\xc9
07-29 16:47:36.441: D/commmand(26944): &$R\x00\xc9
07-29 16:47:37.141: D/commmand(26944): &$V\x00\xcd
07-29 16:47:37.921: D/commmand(26944): &$V\x00\xcd
07-29 16:47:38.281: D/commmand(26944): &$V\x00\xcd
07-29 16:47:38.581: D/commmand(26944): &$V\x00\xcd
07-29 16:47:40.001: D/commmand(26944): &$R\x00\xc9
package com.example.android.BluetoothChat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
CUrrent:
The below is my code:
BluetoothCommandService.java
public class BluetoothCommandService {
private static final String TAG = "BluetoothCommandService";
private static final boolean D = true;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// private BluetoothDevice mSavedDevice;
// private int mConnectionLostCount;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
// Constants that indicate command to computer
public static final int EXIT_CMD = -1;
public static final int VOL_UP = 1;
public static final int VOL_DOWN = 2;
public static final int MOUSE_MOVE = 3;
public static Context ctx ;
/**
* Constructor. Prepares a new BluetoothChat session.
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public BluetoothCommandService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
//mConnectionLostCount = 0;
ctx = context;
mHandler = handler;
}
private synchronized void setState(int state) {
if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(RemoteBluetooth.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state. */
public synchronized int getState() {
return 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() {
if (D) Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
setState(STATE_LISTEN);
}
public synchronized void connect(BluetoothDevice device) {
if (D) Log.d(TAG, "connect to: " + device);
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (D) Log.d(TAG, "connected");
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(RemoteBluetooth.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (D) Log.d(TAG, "stop");
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
setState(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) {
ConnectedThread r;
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
r.write(out);
}
public void write(int out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(RemoteBluetooth.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(RemoteBluetooth.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(RemoteBluetooth.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
setName("ConnectThread");
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
mmSocket.connect();
} catch (IOException e) {
e.printStackTrace();
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
// Start the service over to restart listening mode
BluetoothCommandService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothCommandService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
public static String slurp(final InputStream is, final int bufferSize)
{
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
try {
final Reader in = new InputStreamReader(is, "UTF-8");
try {
for (;;) {
int rsz = in.read(buffer, 0, buffer.length);
if (rsz < 0)
break;
out.append(buffer, 0, rsz);
}
}
finally {
in.close();
}
}
catch (UnsupportedEncodingException ex) {
/* ... */
}
catch (IOException ex) {
/* ... */
}
return out.toString();
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
while (true) {
try {
int bytes = mmInStream.read(buffer);
Log.d( "message" , slurp(mmInStream, 1024));
Toast.makeText(ctx, slurp(mmInStream, 1024), Toast.LENGTH_SHORT).show();
mHandler.obtainMessage(RemoteBluetooth.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void write(int out) {
try {
mmOutStream.write(out);
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmOutStream.write(EXIT_CMD);
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
RemoteBluetooth.java
public class RemoteBluetooth extends Activity {
private TextView mTitle;
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
// 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;
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
private String mConnectedDeviceName = null;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothCommandService mCommandService = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.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;
}
}
#Override
protected void onStart() {
super.onStart();
// If BT is not on, request that it be enabled.
// setupCommand() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
// otherwise set up the command service
else {
if (mCommandService==null)
setupCommand();
}
}
#Override
protected void onResume() {
super.onResume();
if (mCommandService != null) {
if (mCommandService.getState() == BluetoothCommandService.STATE_NONE) {
mCommandService.start();
}
}
}
private void setupCommand() {
mCommandService = new BluetoothCommandService(this, mHandler);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mCommandService != null)
mCommandService.stop();
}
private void ensureDiscoverable() {
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);
}
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothCommandService.STATE_CONNECTED:
mTitle.setText(R.string.title_connected_to);
mTitle.append("HC-06");
break;
case BluetoothCommandService.STATE_CONNECTING:
mTitle.setText(R.string.title_connecting);
break;
case BluetoothCommandService.STATE_LISTEN:
case BluetoothCommandService.STATE_NONE:
mTitle.setText(R.string.title_not_connected);
break;
}
break;
case MESSAGE_DEVICE_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;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
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 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
// Attempt to connect to the device
mCommandService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
setupCommand();
} else {
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scan:
Intent serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
ensureDiscoverable();
return true;
}
return false;
}
public static String hexadecimal(String input, String charsetName)
throws UnsupportedEncodingException {
if (input == null) throw new NullPointerException();
return asHex(input.getBytes(charsetName));
}
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
public static String asHex(byte[] buf)
{
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
try{
String syncCommand = "&$";
String descriptor = "R";
int datalength = 0;
String data = "";
if(datalength > 0 ){
String data1 = hexadecimal(String.valueOf(datalength) , "UTF-8");
String data2 = hexadecimal(String.valueOf(data) , "UTF-8");
data = data1 + data2;
}else{
data = "\\x00" ;
}
int checksum = 0x77;
String descHex = hexadecimal(String.valueOf(descriptor) , "UTF-8");
checksum += ( Integer.parseInt(descHex,16) );
String checkSumString = "\\x" + Integer.toHexString(checksum);
String fullCommand = syncCommand + descriptor + data + checkSumString;
Log.d("commmand" , fullCommand);
mCommandService.write(fullCommand.getBytes());
}catch(Exception e){
e.printStackTrace();
}
return true;
}
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
try{
String syncCommand = "&$";
String descriptor = "V";
int datalength = 0;
String data = "";
if(datalength > 0 ){
String data1 = hexadecimal(String.valueOf(datalength) , "UTF-8");
String data2 = hexadecimal(String.valueOf(data) , "UTF-8");
data = data1 + data2;
}else{
data = "\\x00" ;
}
int checksum = 0x77;
String descHex = hexadecimal(String.valueOf(descriptor) , "UTF-8");
// String dataHex = datalength == 0 ? "\\x00" : hexadecimal(String.valueOf(datalength) , "UTF-8");
// Log.d("descHex" , descHex);
// Log.d("dataHex" , dataHex);
checksum += ( Integer.parseInt(descHex,16) );
String checkSumString = "\\x" + Integer.toHexString(checksum);
String fullCommand = syncCommand + descriptor + data + checkSumString;
Log.d("commmand" , fullCommand);
mCommandService.write(fullCommand.getBytes());
}catch(Exception e){
e.printStackTrace();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}
Original one:
public class BluetoothChat extends Activity implements OnClickListener {
Button Connect;
ToggleButton OnOff;
TextView Result;
private String dataToSend;
private static final String TAG = "Jon";
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private static String address = "00:1a:a1:22:11:12";
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private InputStream inStream = null;
Handler handler = new Handler();
byte delimiter = 100;
boolean stopWorker = false;
int readBufferPosition = 0;
byte[] readBuffer = new byte[1024];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Connect = (Button) findViewById(R.id.conne
ct);
OnOff = (ToggleButton) findViewById(R.id.tgOnOff);
Result = (TextView) findViewById(R.id.msgJonduino);
Connect.setOnClickListener(this);
OnOff.setOnClickListener(this);
CheckBt();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.e("Jon", device.toString());
}
#Override
public void onClick(View control) {
switch (control.getId()) {
case R.id.connect:
Connect();
break;
case R.id.tgOnOff:
if (OnOff.isChecked()) {
dataToSend = "26 24 54 02 c9 00";
Log.e("JonS", dataToSend);
writeData(dataToSend);
} else if (!OnOff.isChecked()) {
dataToSend = "26245200c900";
Log.e("JonS", dataToSend);
writeData(dataToSend);
}
break;
}
}
private void resetConnection() {
// setState(STATE_NONE);
Log.d(TAG, "reset connection");
if (inStream != null) {
try {
inStream.close();
} catch (Exception e) {
Log.d(TAG,"exception in closing inputstream - " + e.getMessage());
}
inStream = null;
}
if (outStream != null) {
try {
outStream.close();
} catch (Exception e) {
Log.d(TAG,"exception in closing outputstream - " + e.getMessage());
}
outStream = null;
}
if (btSocket != null) {
try {
btSocket.close();
} catch (Exception e) {
Log.d(TAG,"exception in closing socket - " + e.getMessage());
}
btSocket = null;
}
Connect();
}
private void CheckBt() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(), "Bluetooth Disabled !",
Toast.LENGTH_SHORT).show();
}
if (mBluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),
"Bluetooth null !", Toast.LENGTH_SHORT)
.show();
}
}
public void Connect() {
Log.d(TAG, address);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.d(TAG, "Connecting to ... " + device);
mBluetoothAdapter.cancelDiscovery();
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect();
Log.d(TAG, "Connection made.");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
Log.d(TAG, "Unable to end the connection");
}
Log.d(TAG, "Socket creation failed");
}
beginListenForData();
}
private void writeData(String data) {
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "Bug BEFORE Sending stuff", e);
}
String message = data;
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "Bug while sending stuff", e);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
if(btSocket!=null){
btSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void beginListenForData() {
try {
inStream = btSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
Thread workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = inStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
inStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
//US-ASCII
final String data = new String(encodedBytes, "UTF-8");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
if(Result.getText().toString().equals("..")) {
Result.setText(data);
} else {
Result.append("\n"+data);
}
/* You also can use Result.setText(data); it won't display multilines
*/
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
ex.printStackTrace();
stopWorker = true;
}
}
}
});
workerThread.start();
}
}
From the logs seems Pairing and connection establishment to the remote device is successful.To debug further why application is not receiving the data you need to find whether response from remote device is receiving at Bluetooth Stack and then sending it to application. For this you need to capture snoop logs.On JB and later versions it will found under /sdcard/btsnoop_hci.log after enabling in setting.
I'm pretty new to Android. Right now I'm trying to make a two-player Pong game using the Bluetooth API. I've more or less tried to copy the BluetoothChat tutorial on the Android website, but I still get an error where the socket immediately disconnects after I switch over to the ConnectedThread. Would anyone have any idea why this is?
I have each of the three types of threads as a private class on a screen of a menu. ConnectThread is split into reading and writing, and is placed inside the screen of the game.
public abstract class FindScreen extends EngineView {
private GUIFactory guiFact;
private TextButton backButton;
private ScrollingList buttonList;
public ConnectThread connectThread;
private BluetoothAdapter adapter;
public FindScreen(Context c, AndroidView aView) {
super(c, aView, 1);
adapter = BluetoothAdapter.getDefaultAdapter();
guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X,
EngineConstants.CENTER_Y), 8, 8, EngineConstants.VIRTUAL_W,
EngineConstants.VIRTUAL_H, EngineConstants.VIRTUAL_W / 32);
GUITask backTask = new GUITask() {
public void execute() {
goBack();
}
};
backButton = guiFact.newGradientTextButton(1, 6, 7, 7, backTask, "Back");
this.add(backButton, 0);
buttonList = guiFact.newScrollingList(1,1,7,6);
this.add(buttonList, 0);
}
#Override
public boolean onTouchEvent(MotionEvent e) {
backButton.executeIfContained(e.getX(), e.getY());
buttonList.executeIfContained(e.getX(), e.getY());
return true;
}
public void onIn() {
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(receiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
context.registerReceiver(receiver, filter);
buttonList.clearButtons();
if(!adapter.startDiscovery()) { // if discovery doesn't start successfully, leave the screen
goBack();
}
}
public void onOut() {
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
context.unregisterReceiver(receiver);
if (connectThread != null) {
connectThread.cancel();
}
}
/**
* Return to the previous screen, the menu screen
*/
public abstract void goBack();
/**
* Do something after we've connected
* #param socket
*/
public abstract void connected(BluetoothSocket socket);
/**
* Broadcast receiver;
* Listens for discovered devices
* When discovery is finished, changes the list of discovered devices
* When discoverability is changed, changes text
*/
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
buttonList.addButton(device.getName(), new ConnectTask(device.getAddress()));
// }
// doDiscovery();
}
}
};
private class ConnectTask extends GUITask {
private String address;
public ConnectTask(String addr) {
address = addr;
}
#Override
public void execute() {
BluetoothDevice device = adapter.getRemoteDevice(address);
if (connectThread != null) {
connectThread.cancel();
}
connectThread = new ConnectThread(device);
connectThread.start();
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket socket;
private final BluetoothDevice device;
public ConnectThread(BluetoothDevice dev) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
device = dev;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(EngineConstants.MY_UUID);
} catch (IOException e) { }
socket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
socket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
socket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
connected(socket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
socket.close();
} catch (IOException e) { }
}
}
public abstract class HostScreen extends EngineView {
private GUIFactory guiFact;
private TextButton backButton;
private TextLabel waitText;
private BluetoothAdapter adapter;
public AcceptThread acceptThread;
private static final int DISCOVERY_LENGTH = 300;
public HostScreen(Context c, AndroidView aView) {
super(c, aView, 1);
adapter = BluetoothAdapter.getDefaultAdapter();
guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X,
EngineConstants.CENTER_Y), 8, 8, EngineConstants.VIRTUAL_W,
EngineConstants.VIRTUAL_H, EngineConstants.VIRTUAL_W / 32);
GUITask backTask = new GUITask() {
public void execute() {
goBack();
}
};
backButton = guiFact.newGradientTextButton(1, 6, 7, 7, backTask, "Back");
this.add(backButton, 0);
waitText = guiFact.newLabel(2, 3, 6, 4, Color.WHITE, "...");
this.add(waitText, 0);
}
public void onIn() {
if (adapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERY_LENGTH);
((Activity) context).startActivityForResult(discoverableIntent, EngineConstants.REQUEST_DISCOVERABLE);
}
if (!adapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivity(enableIntent);
}
}
public void onOut() {
if (acceptThread != null) {
acceptThread.cancel();
}
}
public void discoverableAccepted() {
if (acceptThread != null) {
acceptThread.cancel();
}
acceptThread = new AcceptThread();
acceptThread.start();
}
public void discoverableDeclined() {
goBack();
}
/**
* Do something after we've connected
* #param socket
*/
public abstract void connected(BluetoothSocket socket);
#Override
public boolean onTouchEvent(MotionEvent e) {
backButton.executeIfContained(e.getX(), e.getY());
return true;
}
/**
* Return to the previous screen, the menu screen
*/
public abstract void goBack();
private class AcceptThread extends Thread {
private final BluetoothServerSocket serverSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = adapter.listenUsingRfcommWithServiceRecord(EngineConstants.NAME, EngineConstants.MY_UUID);
} catch (IOException e) { }
serverSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
connected(socket);
try {
serverSocket.close();
} catch (IOException e) {
android.util.Log.d("Accept thread", "Could not close serverSocket");
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
serverSocket.close();
} catch (IOException e) { }
}
}
}
public class GameScreen extends EngineView {
public ConnectedThread connectedThread;
public ConnectedWriteThread writeThread;
private PacketHandler handler;
private final static int N_LAYERS = 4;
// layer 0 = walls
// layer 1 = puck
// layer 2 = paddles
// layer 3 = GUI
public Paddle enemyPaddle, playerPaddle;
public Puck puck;
private GUIFactory guiFact;
private TextLabel playerLabel, enemyLabel;
public int playerScore = 0, enemyScore = 0;
private boolean isHeld;
private float startX, startTouchX, moveToX;
private final static float MIN_X = Paddle.RADIUS, MAX_X = EngineConstants.VIRTUAL_W - MIN_X;
public float myPaddlePrevPosX;
public boolean enemyScoreChanged = false;
private final static long PACKET_RATE = 200;
private long packetTime = 0;
public GameScreen(Context c, final AndroidView aView) {
super(c, aView, N_LAYERS);
enemyPaddle = new Paddle(new Vector2d(EngineConstants.CENTER_X, EngineConstants.VIRTUAL_H/8f), 255, 255, 100, 100);
playerPaddle = new Paddle(new Vector2d(EngineConstants.CENTER_X, EngineConstants.VIRTUAL_H*7f/8f), 255, 100, 255, 100);
puck = new Puck();
this.add(enemyPaddle, 2);
this.add(playerPaddle, 2);
this.add(puck, 1);
guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X, EngineConstants.CENTER_Y), 8, 10, EngineConstants.VIRTUAL_W, EngineConstants.VIRTUAL_H, 0);
playerLabel = guiFact.newLabel(2, 4, 3, 5, Color.rgb(100, 150, 100), "0");
enemyLabel = guiFact.newLabel(7, 3, 8, 4, Color.rgb(150, 100, 100), "0");
this.add(playerLabel, 3);
this.add(enemyLabel, 3);
this.constraints.add(new BoxConstraint(puck, false, false, 0 + Puck.RADIUS));
this.constraints.add(new BoxConstraint(puck, false, true, EngineConstants.VIRTUAL_W - Puck.RADIUS));
myPaddlePrevPosX = playerPaddle.pos.x;
}
public void onOut() {
if (connectedThread != null) {
connectedThread.cancel();
}
if (writeThread != null) {
writeThread.cancel();
}
}
public void update(long interval) {
super.update(interval);
EngineFunctions.collide(playerPaddle, puck);
EngineFunctions.collide(enemyPaddle, puck);
if (puck.pos.y < 0) {
score(true);
} else if (puck.pos.y > EngineConstants.VIRTUAL_H) {
score(false);
}
packetTime += interval;
if (packetTime > PACKET_RATE) {
// android.util.Log.d("fillQueue", "called");
packetTime = 0;
writeThread.fillQueue();
}
}
private void score(boolean isPlayer) {
if (isPlayer) {
playerScore++;
playerLabel.setText(String.valueOf(playerScore));
} else {
enemyScore++;
enemyLabel.setText(String.valueOf(enemyScore));
enemyScoreChanged = true;
}
puck.pos.x = EngineConstants.CENTER_X;
puck.pos.y = EngineConstants.CENTER_Y;
puck.prevPos.x = EngineConstants.CENTER_X;
puck.prevPos.y = EngineConstants.CENTER_Y;
}
#Override
public boolean onTouchEvent(MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
if (playerPaddle.touching(e.getX(), e.getY())) {
isHeld = true;
startX = playerPaddle.pos.x;
startTouchX = e.getX();
}
break;
case MotionEvent.ACTION_MOVE:
if (isHeld) {
myPaddlePrevPosX = playerPaddle.pos.x;
moveToX = startX + (e.getX() - startTouchX);
if (moveToX < MIN_X) {
moveToX = MIN_X;
} else if (moveToX > MAX_X) {
moveToX = MAX_X;
}
playerPaddle.pos.x = moveToX;
playerPaddle.prevPos.x = moveToX;
}
break;
case MotionEvent.ACTION_UP:
isHeld = false;
break;
}
return true;
}
public void startNewConnectedThread(BluetoothSocket soc, boolean isServer) {
if (connectedThread != null) {
connectedThread.cancel();
}
connectedThread = new ConnectedThread(soc, handler);
connectedThread.start();
if (writeThread != null) {
writeThread.cancel();
}
writeThread = new ConnectedWriteThread(soc, handler, isServer);
writeThread.start();
}
public void setHandler(PacketHandler h) {
handler = h;
}
public class ConnectedThread extends Thread {
private final BluetoothSocket socket;
private final InputStream inStream;
private final BufferedReader in;
private PacketHandler handler;
public ConnectedThread(BluetoothSocket soc, PacketHandler pHandler) {
socket = soc;
handler = pHandler;
InputStream tmpIn = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
}
inStream = tmpIn;
in = new BufferedReader(new InputStreamReader(inStream));
}
public void run() {
/*
// Keep listening to the InputStream until an exception occurs
android.util.Log.d("connectedThread", "started");
String str;
try {
inStream.read();
inStream.read();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
android.util.Log.d("connectedThread", "normal read is fine");
while (true) {
try {
// Read from the InputStream
str = in.readLine();
byte type = Byte.valueOf(str);
android.util.Log.d("connectedThread", "read");
handler.handlePacket(in, type);
} catch (IOException e) {
break;
}
}*/
for (int i = 0; i < 20; i++) {
try {
String str = in.readLine();
android.util.Log.d("read", str + " ");
} catch (IOException e) {
// TODO Auto-generated catch block
android.util.Log.d("io exception", e.getMessage() + " " + e.getLocalizedMessage() + " " + e.getCause());
}
}
while (true) {
}
}
/* Call this from the main Activity to shutdown the connection */
public void cancel() {
try {
socket.close();
} catch (IOException e) { }
}
}
public class ConnectedWriteThread extends Thread {
public ConcurrentLinkedQueue<String> que;
private final BluetoothSocket socket;
private final OutputStream outStream;
private final BufferedWriter out;
private PacketHandler handler;
private boolean isServ;
public ConnectedWriteThread(BluetoothSocket soc, PacketHandler pHandler, boolean isServer) {
socket = soc;
handler = pHandler;
isServ = isServer;
OutputStream tmpOut = null;
que = new ConcurrentLinkedQueue<String>();
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
outStream = tmpOut;
out = new BufferedWriter(new OutputStreamWriter(outStream));
}
public void run() {
// Keep listening to the InputStream until an exception occurs
android.util.Log.d("connectedThread", "started");
/*
try {
if (isServ) {
out.write(String.valueOf(EngineConstants.PACKET_SYNC) + '\n');
out.write(String.valueOf(0) + '\n');
}
} catch (IOException e1) {
android.util.Log.d("connectedThread", "io exception " + e1.getMessage() + " " + e1.getLocalizedMessage() + " " + e1.getCause());
}
//android.util.Log.d("connectedThread", "sent initial packet");
while (true) {
if (!que.isEmpty()) {
try {
out.write(que.poll());
out.flush();
// android.util.Log.d("connectedThread", "sent packet");
} catch (IOException e) {
android.util.Log.d("write thread", "io exception " + e.getMessage());
}
}
}*/
try {
outStream.write(3);
out.write("343567\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
}
}
public void fillQueue() {
// android.util.Log.d("fillQueue", "in method");
handler.queuePacket(que);
}
/* Call this from the main Activity to send data to the remote device */
public void write(String str) {
try {
out.write(str);
} catch (IOException e) { }
}
/* Call this from the main Activity to shutdown the connection */
public void cancel() {
try {
socket.close();
} catch (IOException e) { }
}
}
Try to use reflection:
try {
BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice("MAC of remote device");
Method m = mDevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mSocket = (BluetoothSocket) m.invoke(mDevice, Integer.valueOf(1));
mSocket.connect();
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
} catch (Exception e) {}
And after some time in your thread
mInStream = mSocket.getInputStream();
mOutStream = mSocket.getOutputStream();
mInStream is InputStream() and mOutStream is OutputStream().
I came across this problem when used bluetooth connection on HTC device.