问题
I'm developing an android application that transfers images from one device to another. The received image will be stored in the local database of my application created by help of SQLite. To achieve my goals, I've converted the bitmap into byte[] and transferred it to another device by help of outputStream. I did achieve success from the above implementation but, failed in transferring the second image on the connected device.
The problem which I am facing is the following: The first transfer of any image is successful with a single outputStream.write() and single inputStream.read() but, the successive transfer of the same/another image fails with a single outputStream.Write() and multiple inoutStream.read() method calls.
I would like to know the fault in implementation of input and output streams in my code.
Thanks in advance.
The code for thread to start a connection is as follows:
private class StartConnectionThread extends Thread{
private final BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
public StartConnectionThread(BluetoothDevice device){
BluetoothSocket tempBluetoothSocket=null;
bluetoothDevice=device;
try
{
System.out.println(uuid);
tempBluetoothSocket=device.createRfcommSocketToServiceRecord(uuid);
}
catch(IOException ioException)
{
}
bluetoothSocket=tempBluetoothSocket;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("StartConnectionThread Run");
bluetoothAdapter.cancelDiscovery();
try
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bluetoothSocket.connect();
}
catch(IOException ioException)
{
System.out.println(ioException);
try
{
bluetoothSocket.close();
}
catch(IOException cancelIOException)
{
}
return;
}
manageConnectedSocket(bluetoothSocket);
}
public void cancel()
{
try
{
bluetoothSocket.close();
}
catch(IOException ioException)
{
}
}
}
The code for thread to accept a connection is as follows:
private class AcceptConnectionThread extends Thread
{
private final BluetoothServerSocket bluetoothServerSocket;
public AcceptConnectionThread() {
// TODO Auto-generated constructor stub
System.out.println("constructor");
BluetoothServerSocket tempBluetoothServerSocket=null;
try
{
tempBluetoothServerSocket=bluetoothAdapter.listenUsingRfcommWithServiceRecord("My Souvenirs", uuid);
}
catch(IOException ioException)
{
}
bluetoothServerSocket=tempBluetoothServerSocket;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("AcceptConnectionThread Run");
BluetoothSocket bluetoothSocket=null;
while(true)
{
try
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(bluetoothServerSocket);
if(bluetoothServerSocket!=null)
{
bluetoothSocket=bluetoothServerSocket.accept();
}
else {
System.out.println("bluetoothserversocket==null");
}
System.out.println("accept");
}
catch(IOException ioException){
System.out.println("exception after accept");
System.out.println(ioException);
break;
}
if(bluetoothSocket!=null)
{
manageConnectedSocket(bluetoothSocket);
try {
bluetoothServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
public void cancel()
{
try{
bluetoothServerSocket.close();
}
catch(IOException ioException){
}
}
}
The code for manageConnectedSocket() method called in the above threads is as follows:
public void manageConnectedSocket(BluetoothSocket bluetoothSocket)
{
manageConnectedDevicesThread=new ManageConnectedDevicesThread(bluetoothSocket);
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.request);
ByteArrayOutputStream baos= new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,baos);
byte[] bytes=baos.toByteArray();
manageConnectedDevicesThread.write(bytes);
System.out.println("manageConnectedSocket() method called");
manageConnectedDevicesThread.start();
System.out.println("success");
Intent intent=new Intent();
intent.setAction("received");
sendBroadcast(intent);
}
The code for thread to manage the connected devices is as follows:
private class ManageConnectedDevicesThread extends Thread
{
private final BluetoothSocket connectedBluetoothSocket;
InputStream tempInputStream=null;
OutputStream tempOutputStream=null;
public ManageConnectedDevicesThread(BluetoothSocket socket) {
// TODO Auto-generated constructor stub
connectedBluetoothSocket=socket;
try
{
tempInputStream=socket.getInputStream();
tempOutputStream=socket.getOutputStream();
}
catch(IOException ioException)
{
}
inputStream=tempInputStream;
outputStream=tempOutputStream;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("ManageConnectedDevicesThread Run");
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream baos= new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,baos);
byte[] buffer=new byte[1024*8];
int bytes;
while(true)
{
try
{
bytes=inputStream.read(buffer);
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
System.out.println("handler");
}
catch(IOException ioException)
{
System.out.println("for handler:" +ioException);
break;
}
}
}
public void write(byte[] bytes)
{
try
{
outputStream.write(bytes,0,bytes.length);
}
catch(IOException ioException){
System.out.println("exception in write statement of managing connections");
}
}
public void close()
{
try {
connectedBluetoothSocket.close();
} catch (IOException e) {
// TODO: handle exception
}
}
}
The code for handler implemented in my application is as follows:
private final Handler handler=new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 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);
byte[] b=readMessage.getBytes();
if(sendingDeviceFlag==0)
{
Intent intent=new Intent();
intent.setAction("received");
sendBroadcast(intent);
bluetoothDatabase.open();
bluetoothDatabase.insert_slam(readMessage, readBuf);
writeCount++;
System.out.println("write count = "+writeCount);
Cursor cursor=bluetoothDatabase.getSlam();
if(cursor!=null)
{
cursor.moveToFirst();
while(cursor.moveToNext())
{
byte[] barray=cursor.getBlob(cursor.getColumnIndex("img"));
Bitmap bitmap1=BitmapFactory.decodeByteArray(barray, 0, barray.length);
imageView.setImageBitmap(bitmap1);
}
System.out.println("Count = "+cursor.getCount());
}
else {
System.out.println("cursor null");
}
bluetoothDatabase.close();
}
break;
}
};
The code to reset the connection is as follows:
void resetConnection()
{
if(inputStream!=null)
{
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(outputStream!=null)
{
try {
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(startConnectionThread!=null) //my changes
{
System.out.println("start wala active tha");
startConnectionThread.cancel();
}
if(acceptConnectionThread!=null)
{
System.out.println("accept wala active tha");
acceptConnectionThread.cancel();
acceptConnectionThread.interrupt();
acceptConnectionThread=new AcceptConnectionThread();
acceptConnectionThread.start();
}
if(manageConnectedDevicesThread!=null)
{
System.out.println("manage wala active tha");
manageConnectedDevicesThread.close();
}
}
}
The user will click on the paired or found device in a listview to send the image. The code for the click event on listview is as follows:
devicesListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
if(startConnectionThread!=null)
{
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.request);
ByteArrayOutputStream baos= new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,baos);
byte[] bytes=baos.toByteArray();
manageConnectedDevicesThread.write(bytes);
Intent intent=new Intent();
intent.setAction("received");
sendBroadcast(intent);
}
else {
System.out.println("click on list view");
sendingDeviceFlag=1;
writeCount=0;
System.out.println("after reset");
bluetoothAdapter.cancelDiscovery();
String address=new String();
address=arrayAdapter.getItem(arg2);
selectedBluetoothDevice=bluetoothAdapter.getRemoteDevice(address.substring(address.length()-17));
startConnectionThread=new StartConnectionThread(selectedBluetoothDevice);
startConnectionThread.start();
}
}
});
来源:https://stackoverflow.com/questions/21568601/successive-transfer-of-bitmap-via-bluetooth-generate-multiple-inputstream-read