I'm trying to develop an Android application which transfers images from one device to another. The received image would then be shown on the ImageView inside my application. To achieve my task, I thought to send a byte array of the bitmap. I'm able to get the first image on the imageview. But, as soon as I click on the button to send another image the application fails to send the bitmap. It shows me an exception "java.io.IOException: Service fiscovery failed." To send any image successfully I need to restart my application on the receiving/remote device. Can anyone please suggest a solution to mu problem. The logcat has also been included below.
Code to establish the connection:
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
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("bluetoothSocketInThread failed");
try
{
bluetoothSocket.close();
}
catch(IOException cancelIOException)
{
}
return;
}
manageConnectedSocket(bluetoothSocket);
}
public void cancel()
{
try
{
bluetoothSocket.close();
}
catch(IOException ioException)
{
}
}
}
Code to accept the connection:
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
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();
}
System.out.println("accept");
}
catch(IOException 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){
}
}
}
Code to manage the connection:
private class ManageConnectedDevicesThread extends Thread
{
private final BluetoothSocket connectedBluetoothSocket;
public ManageConnectedDevicesThread(BluetoothSocket socket) {
// TODO Auto-generated constructor stub
connectedBluetoothSocket=socket;
InputStream tempInputStream=null;
OutputStream tempOutputStream=null;
try
{
tempInputStream=socket.getInputStream();
tempOutputStream=socket.getOutputStream();
}
catch(IOException ioException)
{
}
inputStream=tempInputStream;
outputStream=tempOutputStream;
}
#Override
public void run() {
// TODO Auto-generated method stub
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);
}
catch(IOException ioException){
System.out.println("exception in wrie tatement of managing connections");
}
}
public void close()
{
try {
connectedBluetoothSocket.close();
} catch (IOException e) {
// TODO: handle exception
}
}
}
Code to reset the connection:
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)
{
System.out.println("start wala active tha");
startConnectionThread.cancel();
}
if(acceptConnectionThread!=null)
{
System.out.println("accept wala active tha");
acceptConnectionThread.cancel();
}
if(manageConnectedDevicesThread!=null)
{
System.out.println("manage wala active tha");
manageConnectedDevicesThread.close();
}
}
}
code for handler is shown below:
private final Handler handler=new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_READ:
System.out.println("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();
Bitmap bitmap1=BitmapFactory.decodeByteArray(readBuf, 0, readBuf.length);
imageView.setImageBitmap(bitmap1);
break;
}
};
The logcat shows the following:
01-25 14:49:31.800: D/dalvikvm(9451): Debugger has detached; object registry had 1 entries
01-25 14:49:38.380: V/BluetoothSocket.cpp(9451): initSocketNative
01-25 14:49:38.380: V/BluetoothSocket.cpp(9451): ...fd 40 created (RFCOMM, lm = 26)
01-25 14:49:38.380: V/BluetoothSocket.cpp(9451): initSocketFromFdNative
01-25 14:49:40.420: D/BluetoothUtils(9451): isSocketAllowedBySecurityPolicy start : device null
01-25 14:49:41.680: I/System.out(9451): bluetoothSocketInThread failed
01-25 14:49:41.680: V/BluetoothSocket.cpp(9451): abortNative
01-25 14:49:41.680: V/BluetoothSocket.cpp(9451): ...asocket_abort(40) complete
01-25 14:49:41.680: V/BluetoothSocket.cpp(9451): destroyNative
01-25 14:49:41.680: V/BluetoothSocket.cpp(9451): ...asocket_destroy(40) complete
Thanks in advance.
Maybe you can try adding thread.sleep for a second? See this discussion:
"The only way I've been able to fix the problem is by adding a
thread.sleep for a second before closing the connection."
also see dan's two consecutive comments on this thread:
"I was able to get this to run only after separating the calls to
findBT(); openBT();
Otherwise, mmSocket.connect(); throws an exception, “Service discovery
failed”
but if I put findBT() in onCreate() and just use the button for
openBT(); it works fine.
Or, if I make a second button, one for each, it works fine.
Suggestions?"
the excerpts from the second comment:
Set pairedDevices = mBluetoothAdapter.getBondedDevices();
mmDevice = mBluetoothAdapter.getRemoteDevice(“00:06:66:46:5A:91″);
if (pairedDevices.contains(mmDevice))
{
statusText.setText(“Bluetooth Device Found, address: ” + mmDevice.getAddress() );
Log.d(“ArduinoBT”, “BT is paired”);
}
where I entered the address of my Bluetooth device. The original code
finds the device and returns the correct address, but
mmSocket.connect(); generates an exception “java.io.IOException:
Service discovery failed”
Suggestions?
Related
I am trying to sending and receiving image to display in ImageView using Server-socket, I want to decrypt image using server-socket but its not working.
Image url like this :
http://localhost:4545/sdcard0/emulated/test.img;
Service :
public class ImageDecrptService extends Service {
private ServerSocket serverSocket;
private Socket socket;
void acceptRequestNDecryptFile() {
try {
try {
serverSocket = new ServerSocket(4545);
} catch (Exception e) {
}
while (true) {
Log.e("", "thread called true");
socket = serverSocket.accept();
//some thing code
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
acceptRequestNDecryptFile();
Log.e("", "thread called ");
} catch (Exception e) {
e.printStackTrace();
}
}
});
#Override
public void onCreate() {
super.onCreate();
try {
thread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
How can pass image url to server socket?
Note : I do not want use Bitmap to display image.
If you have a http url of an image on a webserver then you would need a client to grab the image.
So your ServerSocket is of no use.
Also a client-Socket would not be the right way to go.
You need to use a http component or library to download the image.
Or invoke the DownloadManager.
I want to write audio data that comes from the microphone to a file.
I have 2 threads: one "listen" for the audio data and send it to the second thread(the consumer) which stores it in a queue. The consumer thread constantly polls the queue and writes on the file the audioData as byte[].
I use RandomAccessFile for the writing. Considering that everything is syncronized in my code, should I use some non-thread-safe class like FileChannel?
below is some code snippets:
Read audio data
private void read(){
// fill the buffer with the mic input
readFully(buffer, 0, buffer.length);
// creates audioData from this buffer
WAVData audioData = new WAVData(buffer.length);
audioData.arrayCopy(buffer);
// add it to the consumer
mAudioWritter.add(audioData);
}
Write audio data - the consumer clas
public void add(WAVEntity audioEntity){
mQueue.add(audioEntity);
synchronized (mLock) {
mLock.notify();
}
}
#Override
public void run() {
synchronized (mLock) {
while(!isFinalized){
//wait if queue is empty
while(mQueue.isEmpty()){
try {
mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
WAVEntity entity = mQueue.poll();
if(entity != null){
try {
entity.writeOnFile(file);
} catch (AudioRecorderError e) {
// error handling
}
}
}
}
callback.threadFinished(this);
// try closing this file
try {
file.close();
} catch (IOException e) {
Log.e(getClass().getName(), e.getMessage(), e);
}
}
#Override
public boolean writeOnFile(RandomAccessFile fWriter) throws AudioRecorderError {
synchronized (data) {
//write on the file
try {
fWriter.write(data);
} catch (Exception e) {
AudioRecorderError error = new AudioRecorderError(e, "Data chunck was not written. See stack trace.");
throw error;
}
}
return false;
}
I am pogramming a bluetooth device. I found when I tried to disconnect, the app will hang for some devices.
public class ConnectionThread extends Thread {
....
#Override
public void run() {
bReading = true;
while (bReading) {
try {
if (mInStream==null) break;
bytes = mInStream.read(buffer);
} catch (IOException e) {
cancel();
break;
}
}
}
public void cancel() {
bReading = false;
if (mInStream != null) {
try {
mInStream.close();
} catch (Exception e) {
e.printStackTrace();
}
mInStream = null;
}
So I call the cancel function to stop the while loop.
For above logic, there will be "thread dead" event, which is not good. For some device, the "thead dead" event will even cause the app hangs.
However, I dont know what wrong is the above code. I am not sure if it is caused any synchronous issue? How to improve the flow to remove the potential hang issue. any kind of advice is highly appreciated. Thanks.
To stop the communication you can close the socket :
"
while (true) {
try {
if (mInStream==null) break;
bytes = mInStream.read(buffer);
} catch (IOException e) {
break;
}
}
"
public void cancel(){
try{
mmSocket.close();
if(DEBUG_MODE){
Log.i(TAG, "socket closed");
}
}catch(IOException e){
Log.e(TAG, "socket close failed", e);
}
}
When the socket close the loop will naturally break, since the read will fail
I am trying to run audios one after another with a time gap of 5 seconds. However I dont really see that happening. My third audio in the list is played and others are skipped. This means while debugging only music3 is being played and others are not. I would love alternate methods of doing this. Moreover I used prepare method just like that. Makes no difference while running though.
for(int j=0;j<3;j++)
{
if(j==0)
{
xnp = MediaPlayer.create(this,R.raw.ticktock);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try {
xnp.prepare();
xnp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
xnp.stop();
}
if(j==1)
{
xnp = MediaPlayer.create(this,R.raw.music2);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try {
xnp.prepare();
xnp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
xnp.stop();
}
else if (j==2)
{
xnp = MediaPlayer.create(this,R.raw.music3);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try {
xnp.prepare();
xnp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
xnp.stop();
intenter();
}
}
Your current implementation does not work because the media playback is not done on the main thread, so you are immediately playing all 3 media resources, so only the third one is heard.
I think you might want to call MediaPlayer#setOnCompletionListener on your MediaPlayer object. In the completion listener, you can then postDelayed onto your Handler to queue up the next resource to play.
I'm attempting to run some commands over ssh from my app. I have a door unlocker and a script that takes lock or unlock.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new Runnable()
{
public void run()
{
connectSSH();
}
}).start();
}
I setup the session in a separate thread as you cannot do networking in the main UI thread on android.
private void connectSSH()
{
JSch jsch = new JSch();
try {
session = jsch.getSession("door", "my server",22);
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
session.setPassword("pass");
session.setConfig("StrictHostKeyChecking", "no");
try {
session.connect(40000);
channel = session.openChannel("exec");
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
From here I just have button listeners:
public void unlock(View view) {
((ChannelExec)channel).setCommand("python /home/door/doorUnlocker.py unlock");
try {
channel.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
channel.disconnect();
}
public void lock(View view) {
((ChannelExec)channel).setCommand("python /home/door/doorUnlocker.py lock");
try {
channel.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
channel.disconnect();
}
I can unlock, then lock the door but after that the session just closes so when it attempts to connect to the channel it throws an exception.
Thanks for any help you can provide.