threads to AsyncTask( android, Modbus/TCP) - android

I'm working a connection to a PLC via TCP / Modbus and Jamod library, therefore I use and work with threads. I'm using to handle AsyncTask thread function, but when running my code the application is not responding and closes automatically. Thanks for the help in advance =)
package com.JR.scada;
import java.net.InetAddress;
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.net.TCPMasterConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main extends Activity{
TextView text, depurar;
EditText IP;
Button boton;
TCPMasterConnection con = null; //the TCP connection
ModbusTCPTransaction trans = null; //the Modbus transaction
InetAddress addr = null; //direccion del esclavo
int port = Modbus.DEFAULT_PORT;//puerto por defecto 502
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.lblRegistro);
IP = (EditText) findViewById(R.id.txtIp);
depurar = (TextView) findViewById(R.id.txtdepurar);
boton = (Button)findViewById(R.id.btnVerRegistro);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
protected void onStop() {
super.onStop();
//Close the TCP connection
con.close();
}
public class conectar extends AsyncTask<String,String,Integer>{
protected Integer doInBackground(String... urls) {
try {
text.setText("Entro en el try");
//IP address;
addr = InetAddress.getByName("212.170.50.238");
// Open the connection
con = new TCPMasterConnection(addr);
con.setPort(port);
con.connect ();
} catch (Exception e) {
Log.d("MODBUS","connection error", e);
depurar.setText("no conecta");
return 1;
}
return 0;
}
protected void onPostExecute(Integer bytes) {
depurar.setText("conecta");
}
}
public void onClick(View v) {
conectar conectamos = new conectar();
conectamos.execute("hola");
}
see any errors?

We can't touch UI during onBackground()
depurar.setText("no conecta");
Use UI thread or put it on onPost().

Related

Building a chat client Android app, how should I approach recieving messages?

I'm making an Android application that connects to my computer, with this I am trying to make it so I can send messages back and forth. As of right now messages can be sent and recieved server-side but for my Android application I don't know how to constantly check for messages and update the UI. I'm using a BufferedReader for input and I want to display the messages on a TextView. Here's what I have so far:
package com.example.david.chatclient;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.ExecutionException;
/**
* After connecting to server, how can i recieive messages, append it, and then reloop through it
*/
public class MainActivity extends AppCompatActivity {
private String IP;
private int portNumber;
private Socket clientSocket;
private PrintWriter writer;
private BufferedReader reader;
private Button connectButton;
private Button sendButton;
private EditText userMessage;
private TextView chatHistory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 10.0.2.2 = Android Emulator IP Address (Reaches development machine, not emulator itself)
IP = "10.0.2.2";
portNumber = 25565;
connectButton = (Button) findViewById(R.id.connect_button);
sendButton = (Button) findViewById(R.id.send_button);
userMessage = (EditText) findViewById(R.id.user_message);
chatHistory = (TextView) findViewById(R.id.chat_history);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void connectClient(View view) {
ConnectToServer task = new ConnectToServer();
task.execute();
} // end connectClient
public void sendMessage(View view) {
String message = userMessage.getText().toString() + "\n";
writer.write(message);
writer.flush();
chatHistory.append("CLIENT: " + message);
userMessage.setText("");
}
private class ConnectToServer extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... params) {
try{
clientSocket = new Socket(IP, portNumber);
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
writer = new PrintWriter(clientSocket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Toast.makeText(MainActivity.this, "Successfuly connected, streams are esablished", Toast.LENGTH_SHORT).show();
}
} // end ConnectToServer
} // end MainActivity
Here's what the UI looks like:
https://gyazo.com/dbf99c78ca7874939a404ef7d23d8ff8
There are two aproaches.
Checking periodically if new message awaits on server this method is called Fetch - this is very battery and data unfriendly.
Keeping open connection all time aka push messaging - that's the modern way to go. Google handles this on android and ios with GCM

Getting NetworkOnMainThreadException creating socket in AsyncTask

how is possible that I am getting android.os.NetworkOnMainThreadException when I try to create a socket calling bulb.connectToHW() if I do it from the doInBackground() method of my asycTask?
This is the code of the AsyncTask:
package com.example.bulbcontrol2;
import java.net.InetAddress;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.widget.TextView;
public class AsyncConnection extends AsyncTask<Object, String, String> {
private TextView textV;
private Context context;
private String message;
private Device bulb;
public AsyncConnection(TextView textViewToUpdate,Context context)
{
this.textV = textViewToUpdate;
this.context = context;
}
#Override
protected String doInBackground(Object... params) {
bulb = new Device((InetAddress) params[0],(Integer) params[1]);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("open_connection"))
{
System.out.println(bulb.connectToHW());
message = "Connected";
System.out.println(bulb.dataTransferHW("hello"));
textV.setText(message);
}
if (intent.getAction().equals("close_connection"))
{
message = "Disconnected";
System.out.println(bulb.dataTransferHW("bye"));
bulb.closeConexHW();
}
}
};
IntentFilter filter = new IntentFilter("open_connection");
context.registerReceiver(receiver, filter);
filter.addAction("close_connection");
context.registerReceiver(receiver, filter);
return message;
}
/* protected void onProgressUpdate(String... progress) {
//textV.setText(progress[0]);
}*/
}
And this is the code of the UIThread :
package com.example.bulbcontrol2;
import java.net.InetAddress;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;
public class MainActivity extends Activity
{
Intent broadcastIntent = new Intent();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bulbActions();
}
public void bulbActions()
{
final ToggleButton buttonBulb = (ToggleButton) findViewById(R.id.ToggleBulb);
final ToggleButton buttonLDR = (ToggleButton) findViewById(R.id.ToggleLDRValues);
final TextView txtLDR = (TextView) findViewById(R.id.TxtLDRValues);
byte [] hostBytes = new byte[] {(byte)192,(byte)168,(byte)0,(byte)12};
int port = 5006;
InetAddress host = null;
try
{
host = InetAddress.getByAddress(hostBytes);
}
catch (UnknownHostException e)
{
System.out.println("\nError with server address");
e.printStackTrace();
}
new AsyncConnection((TextView)findViewById(R.id.TxtLDRValues),this.getApplicationContext()).execute(host,port);
buttonBulb.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
if (buttonBulb.isChecked())
{
System.out.println("Pulsado");
broadcastIntent.setAction("open_connection");
MainActivity.this.sendBroadcast(broadcastIntent);
}
else
{
System.out.println("NO Pulsado");
broadcastIntent.setAction("close_connection");
MainActivity.this.sendBroadcast(broadcastIntent);
}
}
});
}
}
Your doInBackground is just defining a BroadcastReceiver and registering it. All the code inside onReceive will run in the main thread when the system calls it following your onClick.
I don't know why you need a BroadcastReceiver if you're just triggering it from a button.
Instead you could do the network stuff directly on your doInBackground and then actually start the AsyncTask inside onClick.
On a case you do need a BroadcastReceiver what you wanna do is start a service from onReceive and do all the network job in the service.
After API11 you can also use goAsync() in the receiver as described here and start a Thread.

Connecting to the network

I'm starting with android, my question is regarding to this official tutorial:
http://developer.android.com/training/basics/network-ops/connecting.html
In the "Perform network operations on a Separate Thread", I have the exact same code in eclipse and I get the following error in eclipse:
The type MainActivity.DownloadWebpageText must implement the inherited abstract method AsyncTask.doInBackground(Object...)
I understand that to override doInBackground() it must get an object as parameter and I expecting and String...
How do i solve that?
I'm pretty confused, because this code is in the main android training section.
Thank you very much and merry christmas!
EDIT: Here's my code. Same code that the guide i linked:
package com.example.com.example.networkoperations;
import java.io.IOException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
final String LOG_TAG = "Connectivity tests (chux)";
Button btn;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(this);
tv = (TextView) findViewById(R.id.textView1);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onClick(View arg0) {
tvText("Clicado!");
ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()){
new DownloadWebpageText().execute("http://mydomain.com");
}
else
tvText("No hay conexión a internet");
}
private void tvText(String text){
String oldText = tv.getText().toString() + "\n";
tv.setText(oldText + text);
}
private class DownloadWebpageText extends AsyncTask{
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
tv.setText(result);
}
}
}
Change the you class deceleration of downloading from
private class DownloadWebpageText extends AsyncTask{
}
to be like
private class DownloadWebpageText extends AsyncTask<String,Void,String>{
}

Sending strings over UDP socket

I am trying to make my test application send strings through a UDP socket. It keeps on throwing AndroidRuntime error on line soc.send(pac);. I already have required permissions set in the android_manifest file.
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
private EditText editText1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1);
editText1 = (EditText) findViewById(R.id.editText1);
button1.setOnClickListener(new View.OnClickListener() {
String text= editText1.toString();
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
udpmsg(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public void udpmsg(String text) throws java.io.IOException
{
InetAddress to = InetAddress.getByName("192.168.0.105");
int port=55505;
DatagramSocket soc = new DatagramSocket();
byte[] data = text.getBytes();
DatagramPacket pac = new DatagramPacket(data, data.length, to, port);
soc.send(pac);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Please note that the send method of DatagramSocket can also throw java.lang.SecurityException which is a runtime exception and you're not catching it anywhere in your code.
As a quick check, replace catch (IOException e) { with catch (Exception e) { and tell us what is displayed in the log after this modification.

Android Image Downloader with progress bar and grid view (Android Runtime)

I'm new to Java and Android.
Here in this application I'm trying to Download multiple images with progress bar and display images in GridView. I'm not getting any error but some exceptions. When I run this code in eclipse, Emulator Just shows "Unfortunately Stopped". So please can anyone help me to sort out this problem??
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.kailash.imagedownloader/com.kailash.imagedownloader.MainActivity}: java.lang.InstantiationException: can't instantiate class com.kailash.imagedownloader.MainActivity; no empty constructor
newInstance failed: no ()
threadid=1: thread exiting with uncaught exception (group=0x40a13300)
Here's the Code:
package com.kailash.imagedownloader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ListAdapter;
public class MainActivity extends Activity{
Button btnShowProgress;
private ProgressDialog pDialog;
GridView grid_view;
public static final int progress_bar_type = 0;
protected static final String[] URLS = {
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_2944.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_2989.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3005.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3012.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3034.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3047.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3092.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3110.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3113.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3128.jpg",
"http://cdn.cs76.net/2011/spring/lectures/6/imgs/img_3160.jpg",
};
public MainActivity(MainActivity mainActivity) {
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridview = (GridView) findViewById(R.id.grid_view);
gridview.setAdapter((ListAdapter) new MainActivity(this));
btnShowProgress = (Button) findViewById(R.id.btnProgressBar);
grid_view = (GridView) findViewById(R.id.grid_view);
btnShowProgress.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new DownloadImages().execute(URLS);
}
});
//new DownloadImages().execute();
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type:
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(1000);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
return pDialog;
default:
return null;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class DownloadImages extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
protected Object doInBackground(Object... params) {
System.out.println("External Storage State = " + Environment.getExternalStorageState());
File directory=new File(Environment.getExternalStorageDirectory(), "/Images");
if (directory.exists()==false)
{
directory.mkdir();
}
for(int i = 0; i <URLS.length; i++) {
try {
File firstFile=new File(directory+"/" +i+ ".jpeg");
if(firstFile.exists()==false)
{
HttpClient httpClient =new DefaultHttpClient();
HttpGet httpGet =new HttpGet(URLS[i]);
HttpResponse resp = httpClient.execute(httpGet);
System.out.println("Status Code = " +resp.getStatusLine().getStatusCode());
if(resp.getStatusLine().getStatusCode()==200)
{
HttpEntity entity = resp.getEntity();
InputStream is = entity.getContent();
Boolean status = firstFile.createNewFile();
FileOutputStream foutS = new FileOutputStream(firstFile);
byte[] buffer = new byte[1024];
long total = 0;
int count;
while((count = is.read(buffer)) != -1){
total += count;
foutS.write(buffer, 0, count);
}
foutS.close();
is.close();
publishProgress(i);
}
}
}catch(MalformedURLException e){
e.printStackTrace();
}catch(ClientProtocolException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
return null;
}
protected void onProgressUpdate(String... progress) {
pDialog.setProgress(Integer.parseInt(progress[0]));
}
#SuppressWarnings("unchecked")
protected void onProgressUpdate(Object... values){
super.onProgressUpdate(values);
}
protected void onPostExecute(String file_url) {
dismissDialog(progress_bar_type);
String imagePath = Environment.getExternalStorageDirectory().toString() + "/Images";
grid_view.setBackgroundDrawable(Drawable.createFromPath(imagePath));
}
}
}
Thank You *please help*
java.lang.RuntimeException: Unable to instantiate activity
ComponentInfo{com.kailash.imagedownloader/com.kailash.imagedownloader.MainActivity}:
java.lang.InstantiationException: can't instantiate class
com.kailash.imagedownloader.MainActivity; no empty constructor
You should not create a constructor when extending Activity. As the system invokes the empty constructor, and creating another one causes the class to not have an empty constructor.
There is also no need to create one, as you shouldn't instantiate an activity by yourself at all. For some reason you instantiate your activity inside onCreate and cast it to ListAdapter, which is an error:
gridview.setAdapter((ListAdapter) new MainActivity(this));
You should use a different class which extends ListAdapter for this.

Categories

Resources