I'm writing a code for a client on an android device to send messages to a server and the server is supposed to reply to it. the layout is composed of an edit text field, a button and a text view. When the button is pressed the message should be taken from the edit text field and sent to the server, when the server receives the message it should reply with a message stating that it has received it and then that reply message is to be received by the client and written on the text view. The problem is that the message is sent to the server when I press on button twice and then when I press the third time the server crashes. Any help on what's the problem would really be appreciated. Thanks in advance.
This is the logcat error that I get
02-04 04:18:38.065: I/Error51(32228): android.os.NetworkOnMainThreadException
MainActivity.java
package com.example.testclientandroid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
static Socket socket;
static final int SERVERPORT = 50000;
static final String SERVER_IP = "192.168.0.105";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
EditText editText = (EditText) findViewById(R.id.editText1);
TextView textView = (TextView) findViewById(R.id.textView2);
try {
String str = editText.getText().toString();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(str);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
textView.setText(in.readLine());
} catch (UnknownHostException e) {
Log.i("Error47", e.toString());
} catch (IOException e) {
Log.i("Error49", e.toString());
} catch (Exception e) {
Log.i("Error51", e.toString());
}
}
});
}
private static class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e) {
Log.i("Error64", e.toString());
} catch (IOException e) {
Log.i("Error65", e.toString());
}
}
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/editText1"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dp"
android:text="Send" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/button1"
android:layout_marginTop="53dp"
android:text="Response:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView1" />
</RelativeLayout>
Android Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testclientandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.testclientandroid.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
ServerClass.java
package mainPackage;
//Server
import java.net.*;
import java.io.*;
public class ServerClass
{
static final int PORTNUMBER = 50000;
public static void main(String[] args) throws IOException
{
new Thread(new ServerThread()).start();
}
public static class ServerThread implements Runnable {
ServerSocket serverSocket;
Socket clientSocket;
public void run() {
try {
serverSocket = new ServerSocket(PORTNUMBER);
clientSocket = serverSocket.accept();
new Thread(new CommunicationThread(clientSocket)).start();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public static class CommunicationThread implements Runnable {
Socket socket;
BufferedReader in;
PrintWriter out;
public CommunicationThread(Socket clientSocket) {
socket = clientSocket;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//out = new PrintWriter(clientSocket.getOutputStream(), true);
} catch (IOException e) {
System.out.println(e.toString());
}
}
public void run() {
try {
while(in.readLine() != null)
{
System.out.println(in.readLine());
out.println(in.readLine() + " Received");
}
} catch (IOException e) {
System.out.println(e.toString());
}
}
}
}
Update
I tried using asyncTask, I don't get a Logcat error anymore but now the server doesn't receive the message at all,
Here's the modified code:
package com.example.testclientandroid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
static Socket socket;
static final int SERVERPORT = 50000;
static final String SERVER_IP = "192.168.0.105";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
new CommunicationTask().execute();
}
});
}
private static class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e) {
Log.i("Error64", e.toString());
} catch (IOException e) {
Log.i("Error65", e.toString());
}
}
}
private class CommunicationTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
EditText editText = (EditText) findViewById(R.id.editText1);
String result;
try {
String str = editText.getText().toString();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(str);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
result = in.readLine();
return result;
} catch (UnknownHostException e) {
Log.i("Error47", e.toString());
} catch (IOException e) {
Log.i("Error49", e.toString());
} catch (Exception e) {
Log.i("Error51", e.toString());
}
return "Error";
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
TextView textView = (TextView) findViewById(R.id.textView2);
textView.setText(result);
}
}
}
Any operation that needs internet should be done on background. Try to read Asynctask to remove this error.
Try to use asynctask , its simple and easier.AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
Here is an example
private class DownloadFilesTask extends AsyncTask {
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");
}
}
Related
I intended to fetch data from ConnectionClass in background and then populate it into recyclerView.
Now, I have successfully fetched the data from url in json format, but my app is crashing when I am trying to display data using recyclerView.
Adapter Class for recyclerview
package com.example.mainapp;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import Model.PersonDetails;
public class PersonDetailsAdapter extends RecyclerView.Adapter<PersonDetailsAdapter.ViewHolder> {
private List<PersonDetails> personDetails;
PersonDetailsAdapter(List<PersonDetails>details)
{
personDetails = details;
}
#NonNull
#Override
public PersonDetailsAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d("create view " , personDetails.toString());
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context) ;
View personView = inflater.inflate(R.layout.person_details_view , parent , true) ;
ViewHolder view = new ViewHolder(personView) ;
return view;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
PersonDetails details = personDetails.get(position);
holder.nameTextView.setText(details.getName());
holder.aliasTextView.setText(details.getAlias());
}
#Override
public int getItemCount() {
return personDetails.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView nameTextView;
public TextView aliasTextView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
nameTextView = (TextView) itemView.findViewById(R.id.nameHolder);
aliasTextView = (TextView) itemView.findViewById(R.id.aliasHolder);
}
}
}
MainActivity.java
package com.example.mainapp;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.example.mainapp.Utility.ConnectionClass;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.net.MalformedURLException;
import java.util.List;
import Model.PersonDetails;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button getButton = findViewById(R.id.get);
Button postButton = findViewById(R.id.post);
Context context = this.getBaseContext();
getButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ConnectionClass conn = null;
try {
conn = new ConnectionClass("URL", context);
conn.execute();
} catch (MalformedURLException e) {
System.out.println("connection not set ");
e.printStackTrace();
}
}
});
postButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postRequest();
}
}
);
}
public void updateView( List<PersonDetails> personDetails ) {
Log.d("1" , "******************************************called fro");
RecyclerView rView = (RecyclerView)findViewById(R.id.recyclerViewPerson);
Log.d("2" , "******************************************iosdjdsa");
PersonDetailsAdapter adapter = new PersonDetailsAdapter(personDetails);
rView.setLayoutManager(new GridLayoutManager(this, 5));
rView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
private void postRequest() {
}
}
ConnectionClass.java
package com.example.mainapp.Utility;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import com.example.mainapp.MainActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import Model.PersonDetails;
public class ConnectionClass extends AsyncTask<Void, Void, Void> {
private URL url ;
private HttpURLConnection conn;
private String response ;
private Context context ;
public ConnectionClass() {
super();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.d("onPost", "*****************************************postexe");
Toast.makeText(context, "Records fetched",Toast.LENGTH_SHORT);
List<PersonDetails> details = new ArrayList<>();
try {
JSONArray arr = new JSONArray(response);
for( int i = 0; i < arr.length() ; ++i )
{
JSONObject jObject = arr.getJSONObject(i);
PersonDetails record = new PersonDetails(jObject.getString("name"),jObject.getString("alias") );
details.add(record);
}
} catch (JSONException e) {
Log.d("t","json exception");
e.printStackTrace();
}
Log.d( "detalis", "**************************************"+details.toString());
MainActivity activity = new MainActivity();
activity.updateView(details);
}
public ConnectionClass(String url, Context context) throws MalformedURLException {
this.url = new URL (url);
conn = null ;
this.context = context;
}
// public void sendRequest(){
// try {
// System.out.println("\n\n***************************************hello**********************\n\n");
// conn = (HttpURLConnection) url.openConnection();
// conn.setDoOutput(false);
// conn.setDoInput(true);
// conn.setUseCaches(false);
// conn.setRequestMethod("GET");
// conn.setRequestProperty("Content-Type", "application/json");
// conn.connect();
// // handle the response
// System.out.println("\n\n***************************************here**********************\n\n");
//
// int status = conn.getResponseCode();
// System.out.println(status);
//
// if (status != 200)
// throw new IOException("Request not completed");
// else
// {
// BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// String inputLine ;
// StringBuilder builder = new StringBuilder() ;
// while((inputLine = in.readLine()) != null )
// builder.append(inputLine);
// in.close();
// response = builder.toString();
// }
//
// }
// catch (IOException e) {
// e.printStackTrace();
// }
// finally{
// if( conn != null )
// conn.disconnect();
// }
// }
public void setUrl(String url) throws MalformedURLException {
this.url = new URL(url);
}
public String getResponse() {
return response;
}
#Override
protected Void doInBackground(Void... voids) {
try {
conn = (HttpURLConnection) url.openConnection();
Log.d("conn", "***************************************************************************connectioon set " ) ;
} catch (IOException e) {
e.printStackTrace();
}
try {
conn.setRequestMethod("GET");
} catch (ProtocolException e) {
e.printStackTrace();
}
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setDoOutput(true);
try {
conn.connect();
Log.d("conn " , "**********************************************************************connected ");
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
try{
br =new BufferedReader(new InputStreamReader(url.openStream()));
char[] buffer = new char[1024];
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
Log.d("sb" , String.valueOf(sb));
}
catch (IOException e)
{
e.printStackTrace();
}
finally{
Log.d("finally ", "*****************************************************************************************finally");
response = sb.toString();
System.out.println("JSON: " + response);
conn.disconnect();
}
return null ;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentTop="true"
android:layout_marginTop="-3dp">
<TextView
android:id="#+id/nameText"
android:layout_width="141dp"
android:layout_height="45dp"/>
<TextView
android:id="#+id/aliasText"
android:layout_width="141dp"
android:layout_height="45dp"
android:layout_marginLeft="119dp"
android:layout_toRightOf="#+id/nameText" />
<Button
android:id="#+id/post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="-11dp"
android:layout_marginBottom="2dp"
android:text="POST" />
<Button
android:id="#+id/get"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="1dp"
android:layout_marginBottom="3dp"
android:text="GET" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewPerson"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#972A2A" />
</RelativeLayout>
xml for RecyclerView content
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="50dp"
android:padding="10dp">
<TextView
android:id="#+id/nameHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="TextView" />
<TextView
android:id="#+id/aliasHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="TextView" />
</LinearLayout>
Application is crashing when control reaches updateView()?
Add your AsyncTask code at the bottom of your MainActivity and then update the recyclerview like this:
updateView(details);
Let me clarify #sdex answer:
When you create an instance of Activity - in your case MainActivity - it doesn't have a view, it is not visible to the user and it's not added to the Activity stack. You could say - this activity is "Dead"
In order to display the result to your currently running MainActivity, so it's displayed to the user, you need to pass the instance of it to the ConnectionClass class. For example - pass it to the constructor of the ConnectionClass.
By the way - please consider moving away from AsyncTask, it's been deprecated and could be a reason for the Context leaks, meaning - you'll have massive objects, that are no more visible to the user are retaining in the memory.
In order to avoid leaking the Activity reference, please store it as the "WeakReference"
MainActivity activity = new MainActivity();
activity.updateView(details);
You can't instantiate activity like this; if you want to call a method in the activity within the AsynkTask class ConnectionClass; you can pass a listener to it and implement this listener in the activity, and then invoke the callback of that listener when you want to call some functionality in the activity.
interface ConnectionClassListener {
void onPostExecuteFinished(List<PersonDetails> personDetails);
}
Pass the class to the AsyncTask constructor
public class ConnectionClass extends AsyncTask<Void, Void, Void> {
ConnectionClassListener mConnectionClassListener;
public ConnectionClass(String url, Context context, ConnectionClassListener listener) throws MalformedURLException {
this.url = new URL (url);
conn = null ;
this.context = context;
mConnectionClassListener = listener;
}
Implement the listener by the activity
public class MainActivity extends AppCompatActivity implements ConnectionClassListener {
#Override
void onPostExecuteFinished(List<PersonDetails> personDetails) {
// Do here what you want when the ConnectionClass calls `onPostExecuteFinished()`
updateView(personDetails);
}
}
add this when creating the AsynkTask class
conn = new ConnectionClass("URL", context, this);
And finally call onPostExecuteFinished() in your ConnectionClass
public class ConnectionClass extends AsyncTask<Void, Void, Void> {
// ...
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// ...
mConnectionClassListener.onPostExecuteFinished(details);
MainActivity activity = new MainActivity();
You cannot just create the instance using the constructor. You should pass a reference of MainActivity to make it work. You need just to change a few lines of the code:
In ConnectionClass replace field private Context context; by private MainActivity activity; and change the constructor accordingly:
public ConnectionClass(String url, MainActivity activity) throws MalformedURLException {
this.url = new URL (url);
conn = null ;
this.activity = activity;
}
After that, you will be able to call activity.updateView(details);.
And don't forget to remove MainActivity activity = new MainActivity();
Further reading:
Proper use of AsyncTask
AsyncTask deprecation and alternatives
i am building a bluetooth chat application in android platform. everything is going fine but i have slight bug in my application . when i am trying to connect with a remote device which is present in my paired devices list and not available currently as a nearby device, then it throws "service discovery failed" exception and my application gets terminated automatically .
To prevent this automatic termination i have also put the condition like if such a exception occurs then start the "accept thread" again but it is not working.
mainActivity.java source code
package simpleweather.bluetooth_test1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.lang.InterruptedException;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TabHost;
import android.widget.TextView;
import java.util.Set;
import android.widget.Toast;
import java.util.ArrayList;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.view.View;
import android.widget.ArrayAdapter;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_ENABLE_BT = 1;
BluetoothAdapter bluetoothAdapter;
private UUID myUUID;
private String myName;
Button Refresh;
ListView NewDevices;
ArrayList<String> ScanNewList;
ArrayAdapter<String> ScanNewAdapter;
server serverconnection=null;
ArrayList<String> conversation;
ArrayAdapter<String> sessionchat;
ListView MsgList;
ArrayList<String> pairedDeviceArrayList;
ListView listViewPairedDevice;
ArrayAdapter<String> pairedDeviceAdapter;
client clientconnection=null;
communication datatransfer=null;
EditText input;
FloatingActionButton sent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NewDevices=(ListView)findViewById(R.id.newDevices);
ScanNewList=new ArrayList<String>();
Refresh=(Button)findViewById(R.id.refresh);
ScanNewAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,ScanNewList);
NewDevices.setAdapter(ScanNewAdapter);
sent=(FloatingActionButton)findViewById(R.id.send);
input=(EditText)findViewById(R.id.input);
MsgList=(ListView)findViewById(R.id.msglist);
conversation=new ArrayList<String>();
sessionchat = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, conversation);
MsgList.setAdapter(sessionchat);
TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
tabHost.setup();
TabHost.TabSpec tabSpec=tabHost.newTabSpec("paireddevices");
tabSpec.setContent(R.id.pairedDevices);
tabSpec.setIndicator("Paired Devices");
tabHost.addTab(tabSpec);
tabSpec=tabHost.newTabSpec("msgArea");
tabSpec.setContent(R.id.chatArea);
tabSpec.setIndicator("Start Chat");
tabHost.addTab(tabSpec);
tabSpec=tabHost.newTabSpec("newdiscovered_devices");
tabSpec.setContent(R.id.newdevices);
tabSpec.setIndicator("Scan Devices");
tabHost.addTab(tabSpec);
listViewPairedDevice=(ListView)findViewById(R.id.listView);
sent.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if(datatransfer!=null){
byte[] bytesToSend = input.getText().toString().getBytes();
datatransfer.write(bytesToSend,input.getText().toString());
input.setText("");
}
}});
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(getBaseContext(),"FEATURE_BLUETOOTH NOT support",Toast.LENGTH_SHORT).show();
finish();
return;
}
myUUID = UUID.fromString("ec79da00-853f-11e4-b4a9-0800200c9a66");
myName = myUUID.toString();
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(getBaseContext(),"Bluetooth is not supported on this hardware platform",Toast.LENGTH_SHORT).show();
finish();
return;
}
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}else{
server_start();
client_start();
}
Refresh.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
}
});
// start discovery for new devices
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // registering broadcast reciever for retrieving information of new devices
registerReceiver(mReceiver, filter);
NewDevices.setOnItemClickListener(new OnItemClickListener() { // list of newly scaned devices
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
String info = ((TextView) view).getText().toString();
String address = info.substring(info.length() - 17);
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
Toast.makeText(MainActivity.this,"Name: " + device.getName() + "\n" + "Address: " + device.getAddress(), Toast.LENGTH_SHORT).show();
clientconnection = new client(device);
clientconnection.start();
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// check if the request code is same as what is passed here it is 1
if(requestCode==1) {
Log.d("Shashank","Bluetooth turned on ");
server_start();
client_start();
}
}
private synchronized void server_start() {
if(clientconnection!=null)
{
clientconnection.cancel();
clientconnection=null;
}
if(datatransfer!=null){
datatransfer.cancel();
datatransfer=null;
}
if(serverconnection!=null) {
serverconnection.cancel();
serverconnection = null;
}
serverconnection = new server();
serverconnection.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
if(bluetoothAdapter!=null){
bluetoothAdapter.cancelDiscovery();
}
unregisterReceiver(mReceiver);
if(serverconnection!=null){
serverconnection.cancel();
serverconnection=null;
}
if(clientconnection!=null){
clientconnection.cancel();
clientconnection=null;
}
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
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(!ScanNewList.contains(device.getName()+"\n"+device.getAddress())) {
ScanNewList.add(device.getName() + "\n" + device.getAddress());
ScanNewAdapter.notifyDataSetChanged();
}
}
}
};
private class server extends Thread {
private BluetoothServerSocket bluetoothServerSocket = null;
public server() {
try {
bluetoothServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(myName, myUUID);
Toast.makeText(getBaseContext(),"Waiting\n" + "bluetoothServerSocket :\n" + bluetoothServerSocket,Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
server_start();
}
}
#Override
public void run() {
BluetoothSocket bluetoothSocket = null;
if(bluetoothServerSocket!=null){
try {
bluetoothSocket = bluetoothServerSocket.accept();
BluetoothDevice remoteDevice = bluetoothSocket.getRemoteDevice();
final String strConnected = "Connected:\n" + remoteDevice.getName() + "\n" +remoteDevice.getAddress();
//connected
runOnUiThread(new Runnable(){
#Override
public void run() {
Toast.makeText(getBaseContext(),strConnected,Toast.LENGTH_SHORT).show();
}});
start_communication(bluetoothSocket,remoteDevice.getName());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
final String eMessage = e.getMessage();
runOnUiThread(new Runnable(){
#Override
public void run() {
Toast.makeText(getBaseContext(),"something wrong: \n" + eMessage,Toast.LENGTH_SHORT).show();
}});
server_start();
}
}else{
runOnUiThread(new Runnable(){
#Override
public void run() {
Toast.makeText(getBaseContext(),"bluetoothServerSocket == null",Toast.LENGTH_SHORT).show();
}});
}
}
public void cancel() {
Toast.makeText(getBaseContext(),"close bluetoothServerSocket", Toast.LENGTH_SHORT).show();
try {
bluetoothServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void client_start() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
findViewById(R.id.listView).setVisibility(View.VISIBLE);
pairedDeviceArrayList = new ArrayList<String>();
pairedDeviceAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, pairedDeviceArrayList);
for (BluetoothDevice device : pairedDevices) {
pairedDeviceArrayList.add(device.getName()+"\n"+device.getAddress());
}
pairedDeviceAdapter.notifyDataSetChanged();
listViewPairedDevice.setAdapter(pairedDeviceAdapter);
listViewPairedDevice.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
String info = ((TextView) view).getText().toString();
String address = info.substring(info.length() - 17);
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
Toast.makeText(MainActivity.this,"Name: " + device.getName() + "\n"+ "Address: " + device.getAddress(),Toast.LENGTH_SHORT).show();
clientconnection = new client(device);
clientconnection.start();
}});
}
}
private class client extends Thread {
private BluetoothSocket bluetoothSocket = null;
private final BluetoothDevice bluetoothDevice;
public client(BluetoothDevice device) {
bluetoothDevice = device;
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
Toast.makeText(getBaseContext(),"bluetoothSocket: \n" + bluetoothSocket,Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
server_start();
}
}
#Override
public void run() {
boolean success = false;
try {
bluetoothSocket.connect();
success = true;
} catch (IOException e) {
e.printStackTrace();
final String eMessage = e.getMessage();
runOnUiThread(new Runnable(){
#Override
public void run() {
Toast.makeText(getBaseContext(),"something wrong bluetoothSocket.connect(): \n" + eMessage,Toast.LENGTH_SHORT).show();
}});
try {
bluetoothSocket.close();
}
catch (IOException e2){
e2.printStackTrace();
server_start();
}
}
if(success){
//connect successful
runOnUiThread(new Runnable(){
#Override
public void run() {
Toast.makeText(getBaseContext(),"connection successfull",Toast.LENGTH_SHORT).show();
}});
start_communication(bluetoothSocket,bluetoothDevice.getName());
}else{
//fail
Toast.makeText(getBaseContext(),"Could not connected with the device!",Toast.LENGTH_SHORT).show();
server_start();
}
}
public void cancel() {
Toast.makeText(getBaseContext(), "Closed bluetoothSocket", Toast.LENGTH_SHORT).show();
try {
bluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void start_communication(BluetoothSocket socket,String chater){
datatransfer = new communication(socket,chater);
datatransfer.start();
}
private class communication extends Thread {
private final BluetoothSocket connectedBluetoothSocket;
private final InputStream connectedInputStream;
private final OutputStream connectedOutputStream;
String deviceName;
public communication(BluetoothSocket socket,String chater) {
connectedBluetoothSocket = socket;
deviceName=chater;
InputStream in = null;
OutputStream out = null;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connectedInputStream = in;
connectedOutputStream = out;
}
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = connectedInputStream.read(buffer);
String strReceived = new String(buffer, 0, bytes);
final String msgReceived =strReceived;
runOnUiThread(new Runnable(){
#Override
public void run() {
conversation.add(deviceName+" : "+msgReceived);
sessionchat.notifyDataSetChanged();
}});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
final String msgConnectionLost = "Connection lost:\n" + e.getMessage();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(), msgConnectionLost, Toast.LENGTH_SHORT).show();
server_start();
}
});
break;
}
}
}
public void write(byte[] buffer,String sendmsg) {
try {
connectedOutputStream.write(buffer);
conversation.add("Me : "+sendmsg);
sessionchat.notifyDataSetChanged();
} catch (IOException e) {
// TODO Auto-generated catch block
server_start();
}
}
public void cancel() {
try {
connectedBluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
and this is activity layout file
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="simpleweather.bluetooth_test1.MainActivity"
tools:showIn="#layout/activity_main">
<TabHost
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/tabHost"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/textView2"
android:layout_alignEnd="#+id/textView2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="340dp"
android:layout_height="wrap_content"></TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="392dp"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/chatArea"
android:layout_width="361dp"
android:layout_height="541dp"
android:weightSum="1">
<ListView
android:layout_width="match_parent"
android:layout_height="380dp"
android:id="#+id/msglist"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
android:layout_weight="0.87"
android:layout_above="#+id/send" />
<EditText
android:layout_width="230dp"
android:layout_height="wrap_content"
android:id="#+id/input"
android:hint="Type Message"
android:layout_marginBottom="41dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="#+id/send"
android:layout_toLeftOf="#+id/send"
android:layout_marginRight="0dp" />
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/ic_dialog_email"
android:id="#+id/send"
android:layout_gravity="center_horizontal"
android:layout_alignBottom="#+id/input"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="20dp" />
</RelativeLayout>
<LinearLayout
android:id="#+id/newdevices"
android:layout_width="355dp"
android:layout_height="516dp"
android:orientation="vertical"
android:weightSum="1">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh Scan"
android:id="#+id/refresh"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp" />
<ListView
android:layout_width="match_parent"
android:layout_height="379dp"
android:id="#+id/newDevices"
android:layout_marginTop="30dp"
android:layout_weight="0.47" />
</LinearLayout>
<LinearLayout
android:id="#+id/pairedDevices"
android:layout_width="374dp"
android:layout_height="500dp"
android:orientation="vertical"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Tap over the Listed Devices to start Connection"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Paired Devices"
android:id="#+id/textView2"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal" />
<ListView
android:layout_width="350dp"
android:layout_height="450dp"
android:id="#+id/listView"
android:layout_below="#+id/textView2"
android:layout_alignRight="#+id/textView"
android:layout_alignEnd="#+id/textView" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
</RelativeLayout>
</ScrollView>
i have screenshot showing the bug .
screenshot showing the bug
I am confused why all this happening . I searched for the similar questions but i didn't found the situation like my bug . Please help me .
I meant that if your connection failed with an exception, then the error path is executed.
The code to show the "Toast" in the error path is different from all the other Toast calls. (ie. its probably not called on the UI thread), so that might be the issue.
Or there might be an issue somewhere within the server.start() call.
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
NetworkOnMainThreadException [duplicate]
(5 answers)
Closed 8 years ago.
When running the line
echoSocket = new Socket(serverHostname, 10008); My app crashes with error, NetworkOnMainThreadException error.
From what i have seen this related to trying to run Sockets on the UI thread. so how can i change my code (below) so it works?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Build;
public class MainActivity extends ActionBarActivity {
Button Bgo;
private static TextView TV1;
EditText Text;
String userInput;
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
String Responce = null;
String serverHostname;
int section = 0;
Boolean keepgoing = true;
Boolean g1o = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bgo = (Button) findViewById(R.id.Go);
TV1 = (TextView) findViewById(R.id.tv1);
Text = (EditText) findViewById(R.id.Inputtext);
onclick();
}
public void send() {
// System.out.println("type the host name"); ->>updating
// serverHostname = new String(stdIn.readLine());
serverHostname = new String("192.168.1.105");
System.out.println("Attemping to connect to host " + serverHostname
+ " on port 10008.");
try {
echoSocket = new Socket(serverHostname, 10008);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
TV1.setText("Don't know about host: " + serverHostname);
} catch (IOException e) {
TV1.setText("Couldn't get I/O for " + "the connection to: "
+ serverHostname);
}
TV1.setText("type VIEW-LOG for last 5 enteries (newset first) or DC to dissconect");
}
public void onclick() {
Bgo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (g1o = true) {
TV1.setText("conecting");
g1o = false;
send();
} else {
userInput = Text.getText().toString();
try {
if (userInput.equals("VIEW-LOG")) {
out.println(userInput);
int i = 0;
while (i < 5) {
Responce = in.readLine();
System.out.println(Responce);//this will be replace once this is working
i++;
}
} else if (userInput.equals("DC")) {
keepgoing = false;
System.out.println("dc");
out.println(userInput);
} else {
out.println(userInput);
System.out.println(in.readLine());
}
} catch (IOException e) {
}
}
}
});
}
public void Close() {
try {
out.close();
in.close();
echoSocket.close();
} catch (IOException e) {
}
}
}
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PlaceHolder"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/Inputtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/Go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go" />
</LinearLayout>
What this dose: one one button press it runs send(); that make the conection to a server. when it is pressed again it send the test in the edittext to the server and if it is DC it disconects from the server, if it is VIEW-LOG the server sends 5 lots of strings
This exception raises when you perform some network operation on main thread which android does not allow to do. Move your send method call to non-UI thread or better move your code into AsyncTask.
You should not perform any network related operation on main thread.
Either use a Handler http://developer.android.com/reference/android/os/Handler.html
OR
an AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
i get error An exception occurred: android.os.NetworkOnMainThreadException even when i already use AsyncTask. Error is on LongOperation.java at the line
while ((line = reader.readLine()) != null) {
here is the code:
AsyncTaskActivity.java:
package com.example.myfirstapp;
import java.util.concurrent.ExecutionException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(this);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button1:
try {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(new LongOperation().execute("http://search.twitter.com/search.json?q=javacodegeeks").get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip" >
</ProgressBar>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView
android:id="#+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace" />
</LinearLayout>
LongOperation.java:
package com.example.myfirstapp;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import android.os.AsyncTask;
import android.util.Log;
public class LongOperation extends AsyncTask<String, Void, String> {
InputStream is = null;
#Override
protected String doInBackground(String... urls) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(urls[0]);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
HttpConnectionParams.setSoTimeout(myParams, 10000);
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
return is.toString();
}
#Override
protected void onPostExecute(String result) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
// System.out.println("Result = " + result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
is there anyone can help?
onPostExecute() and onPreExecute() run on the main UI thread. Move network operations to doInBackground().
new LongOperation().execute("http://search.twitter.com/search.json?q=javacodegeeks").get()
Calling get() does not make it asynchronous anymore. Blocks the ui thread.
public final Result get ()
Waits if necessary for the computation to complete, and then retrieves its result.
You need
new LongOperation().execute("http://search.twitter.com/search.json?q=javacodegeeks")
I would use a interface as a callback to communicate the result back to the activity.
Something like the answer by blackbelt in the below link
How do I return a boolean from AsyncTask?
Also move all your network related operation to doInbackground and update ui in onPostExecute
Example:
public class MainActivity extends Activity implements LongOperation.callBack {
Button btn;
TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.textView1);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new LongOperation(MainActivity.this).execute("http://search.twitter.com/search.json?q=javacodegeeks");
}
});
}
#Override
public void returnText(String value) {
// TODO Auto-generated method stub
txt.setText(value);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Button" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dp"
android:text="TextView" />
</RelativeLayout>
LongOperation.java
public class LongOperation extends AsyncTask<String, Void, String> {
InputStream is = null;
String _response;
callBack cb;
ProgressDialog pd;
interface callBack
{
public void returnText(String value);
};
public LongOperation(Context context) {
// TODO Auto-generated constructor stub
cb = (callBack) context;
pd = new ProgressDialog(context);
pd.setMessage("LongOperation...");
}
#Override
protected String doInBackground(String... urls) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(urls[0]);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
HttpConnectionParams.setSoTimeout(myParams, 10000);
HttpEntity resEntity = response.getEntity();
_response=EntityUtils.toString(resEntity);
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
return _response;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pd.dismiss();
if(cb!=null)
{
cb.returnText(result);
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd.show();
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
I am able to properly send my data through UDP socket , but when I receive data it keeps on waiting at receive command I don't know what is causing this.
Please have a look at my code below.
I am able to properly receive data at server side from android device, but when I send data from server side to android device it doesn't receive. but when I send data from server to any other client e.g PC application it receive and displays data properly.
class Task implements Runnable {
#Override
public void run() {
try {
String messageStr = "feed";
int server_port = 8888;
InetAddress local = InetAddress.getByName("10.0.2.2");
int msg_length = messageStr.length();
byte[] message = messageStr.getBytes();
DatagramSocket s = new DatagramSocket();
//
DatagramPacket p = new DatagramPacket(message, msg_length, local, server_port);
s.send(p);//properly able to send data. i receive data to server
for (int i = 0; i <= 20; i++) {
final int value = i;
message = new byte[30000];
p = new DatagramPacket(message,message.length );
s.receive(p); //keeps on waiting here but i am sending data back from server, but it never receives
final byte[] data = p.getData();;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
progressBar.setProgress(value);
imageView.setImageBitmap(BitmapFactory.decodeByteArray(data,0,data.length));
}
});
}
}
catch(Exception ex)
{
}
}
}
Documentation in Eclipse:
Receives a packet from this socket and stores it in the argument pack.
All fields of pack must be set according to the data received. If the
received data is longer than the packet buffer size it is truncated.
This method blocks until a packet is received or a timeout has
expired.
The "s.receive(p);" command blocks the thread until it receices data or the timeout set with setSoTimeout(timeout) is over.
I have made 2 classes to make my communication happen.
First UDP-Server:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
public class UDP_Server
{
private AsyncTask<Void, Void, Void> async;
private boolean Server_aktiv = true;
#SuppressLint("NewApi")
public void runUdpServer()
{
async = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... params)
{
byte[] lMsg = new byte[4096];
DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
DatagramSocket ds = null;
try
{
ds = new DatagramSocket(Main.SERVER_PORT);
while(Server_aktiv)
{
ds.receive(dp);
Intent i = new Intent();
i.setAction(Main.MESSAGE_RECEIVED);
i.putExtra(Main.MESSAGE_STRING, new String(lMsg, 0, dp.getLength()));
Main.MainContext.getApplicationContext().sendBroadcast(i);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (ds != null)
{
ds.close();
}
}
return null;
}
};
if (Build.VERSION.SDK_INT >= 11) async.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else async.execute();
}
public void stop_UDP_Server()
{
Server_aktiv = false;
}
}
I send the received data to an BroadcastReceiver and there you can do what ever you want to with the data.
And now my client to send the data. In this code I send a broadcast, but I think it will be no problem to change the code for sending to a direct IP or something.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Build;
public class UDP_Client
{
private AsyncTask<Void, Void, Void> async_cient;
public String Message;
#SuppressLint("NewApi")
public void NachrichtSenden()
{
async_cient = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... params)
{
DatagramSocket ds = null;
try
{
ds = new DatagramSocket();
DatagramPacket dp;
dp = new DatagramPacket(Message.getBytes(), Message.length(), Main.BroadcastAddress, Main.SERVER_PORT);
ds.setBroadcast(true);
ds.send(dp);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (ds != null)
{
ds.close();
}
}
return null;
}
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
};
if (Build.VERSION.SDK_INT >= 11) async_cient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else async_cient.execute();
}
And here is how you instantiate the classes from your main class.
//start UDP server
Server = new UDP_Server();
Server.runUdpServer();
//UDP Client erstellen
Client = new UDP_Client();
And here how to send a message with the client.
//Set message
Client.Message = "Your message";
//Send message
Client.NachrichtSenden();
To stop the UDP_Server, just set Server.Server_aktiv to false.
To set the message above u can also write a "setMessage(String message)" methode or something like that.
Here, in this post you will find the detailed code for establishing socket between devices or between two application in the same mobile.
You have to create two application to test below code.
In both application's manifest file, add below permission
<uses-permission android:name="android.permission.INTERNET" />
1st App code: UDP Client Socket
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:id="#+id/tr_send_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="11dp">
<EditText
android:id="#+id/edt_send_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:hint="Enter message"
android:inputType="text" />
<Button
android:id="#+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="Send" />
</TableRow>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/tr_send_message"
android:layout_marginTop="25dp"
android:id="#+id/scrollView2">
<TextView
android:id="#+id/tv_reply_from_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
UDPClientSocketActivity.java
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* Created by Girish Bhalerao on 5/4/2017.
*/
public class UDPClientSocketActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextViewReplyFromServer;
private EditText mEditTextSendMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSend = (Button) findViewById(R.id.btn_send);
mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
buttonSend.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send:
sendMessage(mEditTextSendMessage.getText().toString());
break;
}
}
private void sendMessage(final String message) {
final Handler handler = new Handler();
Thread thread = new Thread(new Runnable() {
String stringData;
#Override
public void run() {
DatagramSocket ds = null;
try {
ds = new DatagramSocket();
// IP Address below is the IP address of that Device where server socket is opened.
InetAddress serverAddr = InetAddress.getByName("xxx.xxx.xxx.xxx");
DatagramPacket dp;
dp = new DatagramPacket(message.getBytes(), message.length(), serverAddr, 9001);
ds.send(dp);
byte[] lMsg = new byte[1000];
dp = new DatagramPacket(lMsg, lMsg.length);
ds.receive(dp);
stringData = new String(lMsg, 0, dp.getLength());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
handler.post(new Runnable() {
#Override
public void run() {
String s = mTextViewReplyFromServer.getText().toString();
if (stringData.trim().length() != 0)
mTextViewReplyFromServer.setText(s + "\nFrom Server : " + stringData);
}
});
}
});
thread.start();
}
}
2nd App Code - UDP Server Socket
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btn_stop_receiving"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="STOP Receiving data"
android:layout_alignParentTop="true"
android:enabled="false"
android:layout_centerHorizontal="true"
android:layout_marginTop="89dp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/btn_stop_receiving"
android:layout_marginTop="35dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<TextView
android:id="#+id/tv_data_from_client"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<Button
android:id="#+id/btn_start_receiving"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="START Receiving data"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp" />
</RelativeLayout>
UDPServerSocketActivity.java
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* Created by Girish Bhalerao on 5/4/2017.
*/
public class UDPServerSocketActivity extends AppCompatActivity implements View.OnClickListener {
final Handler handler = new Handler();
private Button buttonStartReceiving;
private Button buttonStopReceiving;
private TextView textViewDataFromClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving);
buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving);
textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client);
buttonStartReceiving.setOnClickListener(this);
buttonStopReceiving.setOnClickListener(this);
}
private void startServerSocket() {
Thread thread = new Thread(new Runnable() {
private String stringData = null;
#Override
public void run() {
byte[] msg = new byte[1000];
DatagramPacket dp = new DatagramPacket(msg, msg.length);
DatagramSocket ds = null;
try {
ds = new DatagramSocket(9001);
//ds.setSoTimeout(50000);
ds.receive(dp);
stringData = new String(msg, 0, dp.getLength());
updateUI(stringData);
String msgToSender = "Bye Bye ";
dp = new DatagramPacket(msgToSender.getBytes(), msgToSender.length(), dp.getAddress(), dp.getPort());
ds.send(dp);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
});
thread.start();
}
private void updateUI(final String stringData) {
handler.post(new Runnable() {
#Override
public void run() {
String s = textViewDataFromClient.getText().toString();
if (stringData.trim().length() != 0)
textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData);
}
});
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start_receiving:
startServerSocket();
buttonStartReceiving.setEnabled(false);
buttonStopReceiving.setEnabled(true);
break;
case R.id.btn_stop_receiving:
//Add logic to stop server socket yourself
buttonStartReceiving.setEnabled(true);
buttonStopReceiving.setEnabled(false);
break;
}
}
}