Android Socket Client Receiving data - java

I am creating a basic test application for android that can connect to a socket server and send and receive data. i have been able to get the sending of data from the client to the server working but seem to have a problem getting the android to receive data. the server works as i have been able to test that using a external application.
here is my code
package com.socket_sending_and_receving_test;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Looper;
import android.os.Message;
import android.widget.Button;
import android.widget.TextView;
import android.os.Handler;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class Sending_And_Receiving extends Activity {
private Socket socket;
String message = "";
String mClientMsg;
TextView text;
final Handler myHandler = new Handler();
int count = 0;
public static String SERVERPORT;
public static int SERVERPORT2;
public static String SERVER_IP;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sending_and_receaving);
text = (TextView) findViewById(R.id.textView);
text.setText("0");
}
Handler myUpdateHandler = new Handler() {
public void handleMessage(Message msg) {
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText(mClientMsg);
super.handleMessage(msg);
}
};
class CommsThread implements Runnable {
String st = null;
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Message m = new Message();
{
BufferedReader input = null;
try {
InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
BufferedReader reader = new BufferedReader(streamReader);
st = reader.readLine();
mClientMsg = st;
myUpdateHandler.sendMessage(m);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public void connect(View view) {
EditText ip = (EditText) findViewById(R.id.ip);
EditText port = (EditText) findViewById(R.id.port);
SERVER_IP = ip.getText().toString();
SERVERPORT = port.getText().toString();
new Thread(new ClientThread()).start();
new Thread(new CommsThread()).start();
}
public void Disconnect(View view) {
try {
socket.shutdownInput();
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.ko);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true
);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
SERVERPORT2 = Integer.parseInt(SERVERPORT);
socket = new Socket(serverAddr, SERVERPORT2);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
after the connection is made the application crashes. I don't think it is due to the UI updating but i think its due to the receiving of data.
here is the logcat
07-08 21:59:57.915 7041-7041/com.socket_sending_and_receving_test D/libEGL﹕ loaded /system/lib/egl/libEGL_mali.so
07-08 21:59:57.920 7041-7041/com.socket_sending_and_receving_test D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_mali.so
07-08 21:59:57.925 7041-7041/com.socket_sending_and_receving_test D/libEGL﹕ loaded /system/lib/egl/libGLESv2_mali.so
07-08 21:59:57.930 7041-7041/com.socket_sending_and_receving_test D/﹕ Device driver API match
Device driver API version: 10
User space API version: 10
07-08 21:59:57.930 7041-7041/com.socket_sending_and_receving_test D/﹕ mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Tue Oct 16 15:37:13 KST 2012
07-08 21:59:57.965 7041-7041/com.socket_sending_and_receving_test D/OpenGLRenderer﹕ Enabling debug mode 0
07-08 21:59:57.965 7041-7041/com.socket_sending_and_receving_test E/SensorManager﹕ thread start
07-08 21:59:57.970 7041-7041/com.socket_sending_and_receving_test D/SensorManager﹕ registerListener :: handle = 0 name= LSM330DLC 3-axis Accelerometer delay= 200000 Listener= android.view.OrientationEventListener$SensorEventListenerImpl#42b1cf38
07-08 21:59:58.080 7041-7041/com.socket_sending_and_receving_test E/SpannableStringBuilder﹕ SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
07-08 21:59:58.080 7041-7041/com.socket_sending_and_receving_test E/SpannableStringBuilder﹕ SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
07-08 22:00:03.235 7041-7193/com.socket_sending_and_receving_test W/dalvikvm﹕ threadid=13: thread exiting with uncaught exception (group=0x41e792a0)
07-08 22:00:03.240 7041-7193/com.socket_sending_and_receving_test E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-2791
java.lang.NullPointerException
at com.socket_sending_and_receving_test.Sending_And_Receiving$CommsThread.run(Sending_And_Receiving.java:74)
at java.lang.Thread.run(Thread.java:856)
07-08 22:00:03.320 7041-7041/com.socket_sending_and_receving_test D/SensorManager﹕ unregisterListener:: Listener= android.view.OrientationEventListener$SensorEventListenerImpl#42b1cf38
07-08 22:00:03.320 7041-7041/com.socket_sending_and_receving_test D/Sensors﹕ Remain listener = Sending .. normal delay 200ms
07-08 22:00:03.320 7041-7041/com.socket_sending_and_receving_test I/Sensors﹕ sendDelay --- 200000000
07-08 22:00:03.320 7041-7041/com.socket_sending_and_receving_test D/SensorManager﹕ JNI - sendDelay
07-08 22:00:03.320 7041-7041/com.socket_sending_and_receving_test I/SensorManager﹕ Set normal delay = true
07-08 22:00:09.870 7041-7041/com.socket_sending_and_receving_test I/Choreographer﹕ Skipped 392 frames! The application may be doing too much work on its main thread.
07-08 22:00:11.680 7041-7193/com.socket_sending_and_receving_test I/Process﹕ Sending signal. PID: 7041 SIG: 9
Any help on this problem would be greatly appreciated
Cheers :)

Your socket is NULL. This is because of a race condition:
new Thread(new ClientThread()).start();
new Thread(new CommsThread()).start();
Both threads are started here, but ClientThread will initialise the socket while CommsThread tries to use it. But it is not initialised at this point.
You may call CommsThread's run() right after socket=... or if you really need a 2nd thread, start it there.

Your CommsThread is running before your ClientThread has completed the connection. So, 'socket' is still null and you get an NPE.
There is absolutely no reason for these to be two different threads. Combine them, so that the connection is made first and then the I/O starts. Using two threads to perform tasks that must be sequential is basically inane.

Related

Whenever Iam not entering anything in EditText the app is crashes [duplicate]

This question already has answers here:
Can't create handler inside thread that has not called Looper.prepare()
(30 answers)
Closed 2 years ago.
Iam making a weather app but whenever Iam not entering or entering wrong city name in EditText the app crashes even though I have used try and catch blocks for error handling.The below is the java,xml code and the logs where it is showing a runtime error.
Java
package com.atul.whatstheweather;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
EditText cityName;
TextView weatherInfo;
public class Content extends AsyncTask<String, Void ,String>
{
#Override
protected String doInBackground(String... urls) {
URL url;
HttpURLConnection urlConnection = null;
String result = "";
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while(data != -1)
{
char current = (char)data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject jsonObject = new JSONObject(result);
String weatherData = jsonObject.getString("weather");
JSONArray array = new JSONArray(weatherData);
for(int i=0;i<array.length();i++)
{
JSONObject jsonPart = array.getJSONObject(i);
String main = jsonPart.getString("main");
String description = jsonPart.getString("description");
weatherInfo.setText("Weather: "+main+"\n\n"+"Description: "+description);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cityName = (EditText)findViewById(R.id.cityName);
weatherInfo = (TextView)findViewById(R.id.textView);
}
public void clicked(View view)
{
Content content = new Content();
content.execute("https://api.openweathermap.org/data/2.5/weather?q=" + cityName.getText().toString() + "&appid=c20cea76c84b519d67d4e6582064db92");
Log.i("clicked","is working");
}
}
In the Logs given below it is showing Runtime error
Run Logs
05/03 17:35:25: Launching app
Cold swapped changes.
$ adb shell am start -n "com.atul.whatstheweather/com.atul.whatstheweather.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 18757 on device xiaomi-redmi_note_3-9b51ac51
I/art: Late-enabling -Xcheck:jni
D/TidaProvider: TidaProvider()
W/ReflectionUtils: java.lang.NoSuchMethodException: android.os.MessageQueue#enableMonitor()#bestmatch
at miui.util.ReflectionUtils.findMethodBestMatch(ReflectionUtils.java:338)
at miui.util.ReflectionUtils.findMethodBestMatch(ReflectionUtils.java:375)
at miui.util.ReflectionUtils.callMethod(ReflectionUtils.java:800)
at miui.util.ReflectionUtils.tryCallMethod(ReflectionUtils.java:818)
at android.os.BaseLooper.enableMonitor(BaseLooper.java:47)
at android.os.Looper.prepareMainLooper(Looper.java:111)
at android.app.ActivityThread.main(ActivityThread.java:5586)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
W/ResourceType: No package identifier when getting name for resource number 0x00000000
W/System: ClassLoader referenced unknown path: /data/app/com.atul.whatstheweather-1/lib/arm64
I/InstantRun: Instant Run Runtime started. Android package is com.atul.whatstheweather, real application class is null.
W/System: ClassLoader referenced unknown path: /data/app/com.atul.whatstheweather-1/lib/arm64
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
D/AccessibilityManager: current package=com.atul.whatstheweather, accessibility manager mIsFinalEnabled=false, mOptimizeEnabled=false, mIsUiAutomationEnabled=false, mIsInterestedPackage=false
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance#9df51ef
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance#ce6e4fc
D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
I/Adreno: QUALCOMM build : a7823f5, I59a6815413
Build Date : 09/23/16
OpenGL ES Shader Compiler Version: XE031.07.00.00
Local Branch : mybranch22028469
Remote Branch : quic/LA.BR.1.3.3_rb2.26
Remote Branch : NONE
Reconstruct Branch : NOTHING
I/OpenGLRenderer: Initialized EGL, version 1.4
E/HAL: hw_get_module_by_class: module name gralloc
E/HAL: hw_get_module_by_class: module name gralloc
I/clicked: is working
I/DpmTcmClient: RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.atul.whatstheweather, PID: 18757
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:356)
at android.widget.Toast.<init>(Toast.java:101)
at android.widget.Toast.makeText(Toast.java:266)
at com.atul.whatstheweather.MainActivity$Content.doInBackground(MainActivity.java:60)
at com.atul.whatstheweather.MainActivity$Content.doInBackground(MainActivity.java:31)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
I/Process: Sending signal. PID: 18757 SIG: 9
Application terminated.
App crashes because you are calling Toast in background thread.
Replace your Toast line in catch block Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show(); with :
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show();
}
});
Just delete the Toast.makeText

AsyncTask and socket not working in android java

I'm making a simple app client-server in java, i want my phone to receive and send messages to my pc, i'm on same LAN and my pc's ip is 192.168.1.8, my serverSocket is running on port 7777.
for some reason my client android cant connect i think it is because i created a socket in a thread, i have read that i should use AsyncTask or Handle, i tried with that too but i get an exception too.
Class server:
public class MyServer implements Runnable{
private ServerSocket server;
private ObjectInputStream in;
private ObjectOutputStream out;
private Socket clientedConnected;
public ExampleServerZNuC(){
try {
server= new ServerSocket(7777);
System.out.println("server opened on port 7777");
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendMessage(String message){
try {
out.writeObject(message);
out.flush();
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendNotifiy(){
try {
out.writeObject("Send Notify");
out.flush();
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String getMessage(){
return "";
}
public void run(){
System.out.println("method run started");
System.out.println("Waiting for a client to connect");
try {
Socket clientedConnected;
clientedConnected = server.accept();
System.out.println("A client connected : "+clientedConnected.getInetAddress().getHostAddress());
in= new ObjectInputStream(clientedConnected.getInputStream());
out = new ObjectOutputStream(clientedConnected.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("End of method Run");
} }
this is the output i get when i create run the server:
server opened on port 7777
method run started
Waiting for a client to connect
client android:
class to connect to my server( atm i just want it to receive the message):
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class MyConnect implements Runnable{
private Socket myconnect=null ;
private TextView txtMessage;
private ObjectInputStream in;
private ObjectOutputStream out;
public MyConnect( ){
try {
// this is my pc's IP, my phone is connected to same LAN
Log.d("inizializating socket","");
myconnect= new Socket("192.168.1.8",7777);
in = new ObjectInputStream(myconnect.getInputStream());
out = new ObjectOutputStream(myconnect.getOutputStream());
} catch (UnknownHostException e) {
Log.d("My Error connecting",e.getMessage());
} catch (IOException e) {
Log.d("My Error connecting",e.getMessage());
}
}
#Override
public void run() {
try {
String message = (String)in.readObject();
Log.d("messaged recived",message);
} catch (OptionalDataException e) {
Log.d("My Error connecting",e.getMessage());
} catch (ClassNotFoundException e) {
Log.d("Error My ClassNotFoundException",e.getMessage());
} catch (IOException e) {
Log.d("Error My IOEXCEPTION",e.getMessage());
}
}
}
this is the error that i get when i click on a button that should create the socket:
on create i use connect= new MyConnect();
and on onclick event i use:
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnExample:
new Thread(connect).start();
break;
}
}
error message :
05-29 19:02:05.905: E/AndroidRuntime(6520): FATAL EXCEPTION: main
05-29 19:02:05.905: E/AndroidRuntime(6520): android.os.NetworkOnMainThreadException
05-29 19:02:05.905: E/AndroidRuntime(6520): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
05-29 19:02:05.905: E/AndroidRuntime(6520): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
05-29 19:02:05.905: E/AndroidRuntime(6520): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
05-29 19:02:05.905: E/AndroidRuntime(6520): at libcore.io.IoBridge.connect(IoBridge.java:112)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.Socket.startupSocket(Socket.java:566)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.Socket.tryAllAddresses(Socket.java:127)
EDIT:
class MySyncTask extends AsyncTask<Integer, Integer, String>{
String advice;
#Override
protected String doInBackground(Integer... params) {
try {
s = new Socket("192.168.1.8",7777);
Log.d("socket connected","");
ObjectInputStream streamReader = new ObjectInputStream(s.getInputStream());
advice = (String)streamReader.readObject();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
protected void onPostExecute(String result) {
txtMessage.setText("you got a message: " + advice);
}
protected void onPreExecute() {
Log.d("my started","start");
}
}
and i used
MySyncTask asyncTask=new MySyncTask ();
asyncTask.execute();
on onCreate() method but for some reason it is not connecting to my server
LogCat with AsyncTask:
05-29 19:46:21.900: D/my started(26169): start
05-29 19:46:22.020: D/libEGL(26169): loaded /system/lib/egl/l ibEGL_mali.so
05-29 19:46:22.030: D/libEGL(26169): loaded /system/lib/egl/libGLESv1_CM_mali.so
05-29 19:46:22.040: D/libEGL(26169): loaded /system/lib/egl/libGLESv2_mali.so
05-29 19:46:22.080: D/OpenGLRenderer(26169): Enabling debug mode 0
EDIT PROBLEM SOLVED
after searching on internet why socket was not connecting i found someone who had a similar problem and i found the answer here Android Socket not being instantiated
i had to initializate the socket first and then use connect
This is happening because you are trying to perform a networking operation on the main thread. This is bad design, you do not want to lock up the user interface while you run a process that can take long time to execute.
Put your network method in an AsyncTask or Service.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Like Eduardo points out,
NetworkOnMainThreadException
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
Use Asynctask for your connection
Be sure to have
<uses-permission android:name="android.permission.INTERNET" />
into your AndroidManifest.xml
Have you set the proper permissions in the manifest? If yes, is the phone on the same network as your PC (if they are on same wifi network is good)? Try running through debugger and putting a break point.
Here is a nice tutorial that explains client/server communication in android.
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
Good luck
-Raghu

android emulator memory options stop my app from running

I seem to be having major problems with my eclipse emulator and don't know if it's the ram size or my code. In my opinion, my code should run, as it does so in my java netbeans project.
Everytime I run my application and push the connect button, I want to get the string that the server sends back and then do something with it. I have a "Process Connection" method that reads in the string, but when I return it and actually use what is being returned, my emulator crashes
My code is as follows:
package za.nmmu.wrap302.networks.example02;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView lstMessages;
private EditText txtMessage;
private ArrayList<String> messages;
private ArrayAdapter<String> adapter;
String message = "";
private ServerConnection connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get references to View objects
txtMessage = (EditText) findViewById(R.id.txtMessage);
lstMessages = (ListView) findViewById(R.id.lstMessages);
// set up adapter
messages = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, messages);
lstMessages.setAdapter(adapter);
// attach event listener
txtMessage.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_ENTER)
&& (event.getAction() == KeyEvent.ACTION_DOWN)) {
try {
onTxtMessageEnterPressed();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
return false;
}
});
}
public void onBtnConnectClicked(View view) {
clearMessages();
connection = new ServerConnection();
connection.start();
}
public void onTxtMessageEnterPressed() throws IOException {
if (connection != null) {
String message = txtMessage.getText().toString();
txtMessage.getText().clear();
connection.sendData(message);
}
}
public void addMessage(String message) {
adapter.add(message);
}
public void clearMessages() {
adapter.clear();
}
// the thread that will be communicating with the server
public class ServerConnection extends Thread {
// the I/O streams that will be receiving/sending data from/to the
// server
private ObjectOutputStream output;
private ObjectInputStream input;
private Socket client;
#Override
public void run() {
try {
// Step 1: Create a Socket to make connection
connectToServer();
// Step 2: Get the input and output streams
getStreams();
// Step 3: Process connection
processConnection();
// Step 4: Close connection
//closeConnection();
} catch (IOException e) {
Log.e("CONNECTION", e.getMessage());
}
}
public void addMessage(final String message) {
runOnUiThread(new Runnable() {
#Override
public void run() {
MainActivity.this.addMessage(message);
}
});
}
private void connectToServer() throws IOException {
addMessage("Attempting connection\n");
client = new Socket("10.0.0.7", 5001);
addMessage("Connected to: " + client.getInetAddress().getHostName());
}
private void getStreams() throws IOException {
output = new ObjectOutputStream(client.getOutputStream());
output.flush();
input = new ObjectInputStream(client.getInputStream());
addMessage("Got I/O streams");
}
//I would like to call the message below and return it to anywhere else in the code
private String processConnection() throws IOException
{
do {
try {
message = (String) input.readObject();
addMessage(message);
return message;
}
catch (ClassNotFoundException classNotFoundException)
{
addMessage("ERROR: Unknown object type received");
}
return message;
} while (!message.equals("SERVER>>> TERMINATE"));
}
private void sendData(String message) {
try {
output.writeObject(message);
output.flush();
addMessage("CLIENT>>>" + message);
} catch (IOException ioException) {
addMessage("ERROR: Error writing object");
}
}
private void closeConnection() throws IOException {
addMessage("Closing connection");
output.close();
input.close();
client.close();
}
}
}
My application seems to just crash whenever I call the processConnection method from anywhere.
My server picks up that I've sent the message, but my client doesn't read.
http://i.stack.imgur.com/cNu7m.png
My logcat shows:
06-13 08:18:00.460: D/dalvikvm(1145): GC_FOR_ALLOC freed 45K, 4% free 3076K/3204K, paused 293ms, total 296ms
06-13 08:18:00.460: I/dalvikvm-heap(1145): Grow heap (frag case) to 3.687MB for 635812-byte allocation
06-13 08:18:00.530: D/dalvikvm(1145): GC_FOR_ALLOC freed 1K, 4% free 3695K/3828K, paused 55ms, total 55ms
06-13 08:18:02.220: I/Choreographer(1145): Skipped 172 frames! The application may be doing too much work on its main thread.
06-13 08:18:02.240: D/gralloc_goldfish(1145): Emulator without GPU emulation detected.
06-13 08:18:03.100: I/Choreographer(1145): Skipped 198 frames! The application may be doing too much work on its main thread.
06-13 08:18:27.660: E/InputEventSender(1145): Exception dispatching finished signal.
06-13 08:18:27.660: E/MessageQueue-JNI(1145): Exception in MessageQueue callback: handleReceiveCallback
Does the ram in the emulator affect this? What am I doing wrong?
You need to use Async task to spawn off uploading to a different thread. Android works on a single thread model and using the same thread to make HTTPRequest can result in FATAL exception. Create an Async task and spawn off the upload to it.
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute(<pass the required parameters here for file upload>);
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
//Call the function to upload the file here
}
This is what the logcat is telling you by Main thread is doing too many tasks.

Android BluetoothSocket::connect() throws an exception

I can not initiate the bluetooth connection between Java server(using bluecove 2.1.1 on Windows 7 x64, external bluetooth dongle) and Android client(OS version 2.3.6).
Device discovery works normally, but I cannot connect to service running on PC(BluetoothSocket::connect() throw an exception). Below is a very primitive version of server and client(I use MAC address of bluetooth dongle for reducing code length):
Java Server
import java.io.*;
import javax.microedition.io.*;
import javax.bluetooth.*;
public class RFCOMMServer {
public static void main(String args[]) {
try {
StreamConnectionNotifier service = (StreamConnectionNotifier) Connector
.open("btspp://localhost:"
+ new UUID("0000110100001000800000805F9B34FB",
false).toString() + ";name=helloService");
StreamConnection conn = (StreamConnection) service.acceptAndOpen();
System.out.println("Connected");
DataInputStream in = new DataInputStream(conn.openInputStream());
DataOutputStream out = new DataOutputStream(conn.openOutputStream());
String received = in.readUTF(); // Read from client
System.out.println("received: " + received);
out.writeUTF("Echo: " + received); // Send Echo to client
conn.close();
service.close();
} catch (IOException e) {
System.err.print(e.toString());
}
}
}
Android Client
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.UUID;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.widget.LinearLayout;
import android.widget.ArrayAdapter;
public class AndroidBluetoothEchoClientActivity extends ListActivity {
LinearLayout layout;
private ArrayAdapter<String> mArrayAdapter;
final Handler handler = new Handler();
final Runnable updateUI = new Runnable() {
public void run() {
mArrayAdapter.add(bluetoothClient.getBluetoothClientData());
}
};
BluetoothClient bluetoothClient;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mArrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1);
this.setListAdapter(mArrayAdapter);
bluetoothClient = new BluetoothClient(handler, updateUI);
bluetoothClient.start();
}
}
class BluetoothClient extends Thread {
BluetoothAdapter mBluetoothAdapter;
private String data = null;
final Handler handler;
final Runnable updateUI;
public BluetoothClient(Handler handler, Runnable updateUI) {
this.handler = handler;
this.updateUI = updateUI;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
public String getBluetoothClientData() {
return data;
}
public void run() {
BluetoothSocket clientSocket = null;
// Client knows the MAC address of server
BluetoothDevice mmDevice = mBluetoothAdapter
.getRemoteDevice("00:15:83:07:CE:27");
try {
clientSocket = mmDevice.createRfcommSocketToServiceRecord(UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB"));
mBluetoothAdapter.cancelDiscovery();
clientSocket.connect();
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
out.writeUTF("Hello"); // Send to server
data = in.readUTF(); // Read from server
handler.post(updateUI);
} catch (Exception e) {
}
}
}
Here is core of the problem(I guess):
BluetoothDevice mmDevice = mBluetoothAdapter
.getRemoteDevice("00:15:83:07:CE:27");//normally get device
try {
clientSocket = mmDevice.createRfcommSocketToServiceRecord(UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB"));//here also no problem
mBluetoothAdapter.cancelDiscovery();
clientSocket.connect();//here throw an exception
I try to use reflection:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
clientSocket = (BluetoothSocket) m.invoke(device, 1);
but it also not work.
For over a week I can not solve this problem, I would be grateful if you help with the decision.
Here is the log file:
02-27 08:32:33.656: W/ActivityThread(10335): Application edu.ius.rwisman.AndroidBluetoothEchoClient is waiting for the debugger on port 8100...
02-27 08:32:33.687: I/System.out(10335): Sending WAIT chunk
02-27 08:32:33.882: I/System.out(10335): Debugger has connected
02-27 08:32:33.882: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:34.085: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:34.289: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:34.492: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:34.687: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:34.890: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:35.093: I/System.out(10335): waiting for debugger to settle...
02-27 08:32:35.296: I/System.out(10335): debugger has settled (1493)
02-27 08:32:35.390: I/ApplicationPackageManager(10335): cscCountry is not German : SER
02-27 08:32:35.875: D/dalvikvm(10335): threadid=9: still suspended after undo (sc=1 dc=1)
02-27 08:32:45.351: D/BluetoothSocket(10335): create BluetoothSocket: type = 1, fd = -1, uuid = [00001101-0000-1000-8000-00805f9b34fb], port = -1
02-27 08:32:45.351: D/BLZ20_WRAPPER(10335): blz20_init: initializing...
02-27 08:32:45.351: D/BTL_IFC_WRP(10335): wsactive_init: init active list
02-27 08:32:45.460: D/BLZ20_WRAPPER(10335): blz20_init: success
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_sock_create: CTRL
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_alloc_new_sock: wrp_alloc_new_sock sub 1
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_sock_create: 43
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_sock_connect: wrp_sock_connect brcm.bt.btlif:9000 (43)
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_sock_connect: BTLIF_MAKE_LOCAL_SERVER_NAME return name: brcm.bt.btlif.9000
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_sock_connect: wrp_sock_connect ret:-1 server name:brcm.bt.btlif.9000
02-27 08:32:45.460: E/BTL_IFC_WRP(10335): ##### ERROR : wrp_sock_connect: connect failed (Connection refused)#####
02-27 08:32:45.460: E/BTL_IFC(10335): ##### ERROR : btl_ifc_ctrl_connect: control channel failed Connection refused#####
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wrp_close_full: wrp_close (43:-1) [brcm.bt.btlif]
02-27 08:32:45.460: D/BTL_IFC_WRP(10335): wsactive_del: delete wsock 43 from active list [ad3bc380]
Problem solved, simply verification code on my device and on PC was different, but Windows shown device in paired devices list. I repair device and it works.

Thread.interrupt () doesn't work

Hy!
My Thread.interrupt doesn't work.
Code (us is global):
//Call
us = new UpdateState(params, hup);
us.start();
//Interupt
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== R.id.stopthread)
{
Log.e("Kill", "Kill");
us.interrupt();
}
return super.onOptionsItemSelected(item);
}
Class:
package android.skiptvad;
import java.util.List;
import org.apache.http.NameValuePair;
import android.os.Handler;
import android.os.Message;
import android.text.NoCopySpan.Concrete;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
public class UpdateState extends Thread {
public List<NameValuePair> params;
public Handler handler;
public Handler ins;
public UpdateState(List<NameValuePair> params, final Handler handler) {
this.handler = handler;
this.params = params;
this.ins = new Handler (){
#Override
public void handleMessage(Message msg) {
if (msg.obj.toString()!= null)
{
JSONParse json = null;
try
{
Message msg2 =new Message();
Log.e("Channel_State_Update",msg.obj.toString());
json = new JSONParse(msg.obj.toString());
String state = json.getChannelState();
Log.e("Channel_State_Send",state);
msg2.obj = state;
handler.sendMessage(msg2);
}
catch (final Exception e)
{
e.printStackTrace();
}
}
}
};
}
#Override
public void run() {
while (true)
{
if (!this.isInterrupted())
{
HttpConnection con = new HttpConnection(params, "http://surfkid.redio.de/getChannelState", this.ins);
con.start();
try {
Log.e("Sleep", "Begin");
UpdateState.this.sleep(5000);
Log.e("Sleep", "End");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.e("Sleep", "Error");
e.printStackTrace();
}
}
//super.run();
}
}
}
Please help
Log:
02-15 18:50:30.317: ERROR/Sleep(10696): End
02-15 18:50:30.347: ERROR/Sleep(10696): Begin
02-15 18:50:30.677: ERROR/Channel_State_Update(10696): {"responseData":{"channelState":"0"},"responseDetails":null,"responseStatus":200}
02-15 18:50:30.677: ERROR/Channel_State_Send(10696): 0
02-15 18:50:30.677: ERROR/UPDATE(10696): 0
02-15 18:50:35.347: ERROR/Sleep(10696): End
02-15 18:50:35.357: ERROR/Sleep(10696): Begin
02-15 18:50:35.897: ERROR/Channel_State_Update(10696): {"responseData":{"channelState":"0"},"responseDetails":null,"responseStatus":200}
02-15 18:50:35.897: ERROR/Channel_State_Send(10696): 0
02-15 18:50:35.897: ERROR/UPDATE(10696): 0
02-15 18:50:36.868: ERROR/Kill(10696): Kill
02-15 18:50:36.878: ERROR/Sleep(10696): Error
02-15 18:50:36.908: ERROR/Sleep(10696): Begin
02-15 18:50:37.427: ERROR/Channel_State_Update(10696): {"responseData":{"channelState":"0"},"responseDetails":null,"responseStatus":200}
02-15 18:50:37.427: ERROR/Channel_State_Send(10696): 0
02-15 18:50:37.427: ERROR/UPDATE(10696): 0
02-15 18:50:41.909: ERROR/Sleep(10696): End
02-15 18:50:41.927: ERROR/Sleep(10696): Begin
You need to break a loop when thread is interrupted:
#Override
public void run() {
while (!this.isInterrupted()) { // Exit when thread's interrupt flag is set
HttpConnection con = new HttpConnection(params, "http://surfkid.redio.de/getChannelState", this.ins);
con.start();
try {
Log.e("Sleep", "Begin");
UpdateState.this.sleep(5000);
Log.e("Sleep", "End");
} catch (InterruptedException e) {
Log.e("Sleep", "Error");
e.printStackTrace();
// Restore interrupt flag after catching InterruptedException
// to make loop condition false
Thread.currentThread().interrupt();
}
}
}
What do you expect to happen? You have the interrupt exception in a massive while loop :) You need to write break; inside the exception part for it to exit the loop. The if !this.isInterrupted() line only makes the loop extremely tight by eliminating the code inside, but the loop is still there on the outside.

Categories

Resources