I need to develop an app with a service that is able to get data from a server when the app is in background. I used a thread in order to run ThreadWorker() for long time when the app is background. (Previously I did a thread in my app: when the app was onStop() the thread stopped and that was not good for me. So I decided to go for a Service)
public class ServiceBG extends Service
{
public class LocalBinder extends Binder {
ServiceBG getService() {
return ServiceBG.this;
}
}
private final IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
#Override
public void onCreate() {
InitializeVariable();
}
private void InitializeVariable()
{
this.mContext = this;
this.working = false;
this.canRun = true;
this.serverCOM = new ServerCOM(myUrl,departmentID);
ThreadWorker();
}
private void ThreadWorker()
{
thread = new Thread(new Runnable() {
#Override
public void run() {
int i=0 ;
while (canRun)
{
try {
while (!serverCOM.hasActiveInternetConnection(mContext)) {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list = serverCOM.GetFirmwareDeviceNameList();
}
catch (Exception e)
{
e.printStackTrace();
}
if(listDevice!=null) {
Log.d("serviceBG", String.valueOf(list.size()));
if (list.size() > 0) {
working = true;
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("DATAPASSED",list.get(0));
sendBroadcast(intent);
//complete action
}
}
try {
FirmwareUpdaterThread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
return Service.START_STICKY;
}
}
My ServerCOM object is made like this:
public class ServerCOM {
public List<String> GetFirmwareDeviceNameList()
{
AsyncGetNames asyncGetNames=new AsyncGetNames();
asyncGetNames.execute(URL);
try {
this.NameList =asyncGetNames.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return this.NameList;
}
public boolean hasActiveInternetConnection(Context context) {
if (isNetworkAvailable(context)) {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
Log.e(LOG_TAG, "Error checking internet connection", e);
}
} else {
Log.d(LOG_TAG, "No network available!");
}
return false;
}
private boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null;
}
private class AsyncGetNames extends AsyncTask<String, String, List<String>>
{
public AsyncGetNames()
{
}
#Override
public List<String> doInBackground(String... params){
List<String> list = null;
try {
URL url = new URL(params[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "*/*");
InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
//readStream(in);
String resultString = Operations.convertStreamToString(inputStream);
inputStream.close();
String[] list1 = new Gson().fromJson(resultString, String[].class);
list= Arrays.asList(list1);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
}
}
When I start this service I can get data from server. After more or less half an hour the service is not able to send requests anymore (I see this from Logcat in Android Studio). It seems that the request thread goes to sleep. Is there some possible interaction between this thread and AsyncTask request?
Related
I try to write an android program to check internet connection with two different methods. The first one is the most common method, CheckInternetConnection(), and the second method is through connecting to a website, ConnectGoogleTest().
The first one work perfectly, but in the second one my tablet hang! anybody knows why ?
The codes are:
public class myITClass {
private Context ctx ;
public myITClass(Context context){
this.ctx = context;
}
public boolean CheckInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
//NetworkInfo ni = cm.getActiveNetworkInfo();
if (cm.getActiveNetworkInfo() == null) {
// There are no active networks.
return false;
} else {
return true;
}
}
public boolean googlePingTest(){
boolean res = false ;
try {
URL url = new URL("http://www.google.com/");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(15000);
urlc.connect();
if (urlc.getResponseCode() == 200) { res = true; }
} catch (MalformedURLException e1) {
res = false;
} catch (IOException e) {
res = false ;
}catch (Exception e){
res = false ;
}
return res;
}
}
You can send a ping to http://www.google.com/ through HttpURLConnection. Please make sure that you doing it in the background thread. Creating a network task must be run in the background. There are 3 options to do that:
Using AsyncTask
Using IntentService
Using Service
In this time, we will use AsyncTask. So create a private class inside your Activity:
private boolean res = false;
private class PingTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... urlSite) {
HttpURLConnection urlc = null;
try {
URL url = new URL("http://www.google.com/");
urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(15000);
urlc.setRequestMethod("GET");
urlc.connect();
if (urlc.getResponseCode() == 200) { res = true; }
} catch (MalformedURLException e1) {
res = false;
} catch (IOException e) {
res = false ;
}catch (Exception e){
res = false ;
}finally{
if (urlc != null) {
try{
// close the connection
urlc.disconnect();
}catch (Exception e){
e.printStackTrace();
}
}
}
return null;
}
}
Don't forget to add this field in your class:
private boolean res = false;
Create a method to get the status:
public boolean getStatus(){
return status;
}
How to use?
Execute the PingTask first to check the status:
PingTask ping = new PingTask();
ping.execute();
Get the status:
// if the connection is available
if(getStatus()==true){
// do your thing here.
}
The second method calls network synchronously on main thread, and that blocks the UI. Try using AsyncTask for it.
I am trying to implement the following code:
public class CheckSomeStaff extends AsyncTask<String, String, String> {
private HttpURLConnection urlc;
public boolean hasActiveInternetConnection(Context context) {
try {
this.doInBackground();
if (urlc.getResponseCode() == 200) {
return true;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
if (isConnectingToInternet() == true) {
try {
urlc = (HttpURLConnection) (new URL(
"http://whatever.com/whatever_data_download/"
+ "myDB.db").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(500);
urlc.connect();
urlc.getResponseCode();
} catch (IOException e) {
Log.d(LOG_TAG, "Error checking internet connection", e);
}
return null;
} else {
Log.d(LOG_TAG, "No network available!");
}
return null;
}
}
It works fine on emulator but when I am trying to download my application to device it trows out NullPointerException at the following line:
if (urlc.getResponseCode() == 200) {
Why does the null pointer occur on a device?
if this block
if (isConnectingToInternet() == true) {
is false, the urlc is never initialized, thus you get a NullPointerException.
Try this way
public class CheckSomeStaff extends AsyncTask<Void, Void, Boolean> {
HttpURLConnection urlc;
int result = -1;
public boolean hasActiveInternetConnection() {
execute();
while (result == -1) {
}
if (result == 200) {
return true;
} else {
return false;
}
}
#Override
protected Boolean doInBackground(Void... arg0) {
try {
urlc = (HttpURLConnection) (new URL("http://whatever.com/whatever_data_download/" + "myDB.db").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(500);
urlc.connect();
return urlc.getResponseCode() == 200 ? true : false;
} catch (IOException e) {
}
return false;
}
#Override
protected void onPostExecute(Boolean result) {
try {
this.result = urlc.getResponseCode();
} catch (Exception e) {
this.result = -2;
}
super.onPostExecute(result);
}
}
Initialize "urlc" like-
URL url = new URL("Your URL");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
public static boolean SendMessage(final String response)
{
OutputStream out;
try {
out = socket.getOutputStream();
writeResponse(out,response);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
mRun=true;
return false;
}
return true;
here is my code for sending login message to tcp socket. I want to perform an asynchronous task for this activity. How can i do that.
try code like this and execute new MyAsync().execute(); whenever you want send sms
public class MyAsync extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... params) {
return SendMessage(response);
}
}
public static boolean SendMessage(final String response) {
OutputStream out;
try {
out = socket.getOutputStream();
writeResponse(out, response);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
mRun = true;
return false;
}
return true;
}
i've done an application in which the android application send datas to java desktop swing application as well as send datas from desktop to android using TCP socket programming through wifi.
Th application is a Hotel Kitchen order booking system
The problem describes that Dine_Tables class contains buttons which represents each tables in a hotel, on clicking table1 button for example it starts the BackgroundServers Asyntask which runs a server for receiving desktop application datas also it takes the activity from Dinein_Tables.java to Food_Customizer.java.
In Food_Customizer.java on clicking submit button it starts ServersendAsyncAction Asyntask which sends some datas to desktop swing application.
The desktop application after processing sends some datas to android application, The server that runs in the android application on receiving the datas goes again from Food_Customizer.java to Dinein_Tables.java activity in the BackgroundServers Asyntask onPostExecute method.
The problem is that when i do this process a two or three times the application stop due to address-in use and Null-Pointer exception at socket = serverSocket.accept(); in the BackgroundServers Asyntask.
Can anyone please tell me some solution for this problem
Dinein_Tables.java
public class Dinein_Tables extends Activity {
:
:
table1.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
new Handler().postDelayed(new Runnable() {
public void run() {
Food_Customizer.BackgroundServers ob = new Food_Customizer().new BackgroundServers(contexts);
ob.execute("");
Intent toAnotherActivity = new Intent(v.getContext(), Food_Customizer.class);
startActivity(toAnotherActivity);
finish();
}
}, 100L);
}
});
}
Food_Customizer.java
public class Food_Customizer extends Activity {
:
:
submit= (Button)findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pd = ProgressDialog.show(contexts, "Sending to Server...","Please Wait...", true, false);
new ServersendAsyncAction().execute();
}
});
:
:
/****************************** AsyncTask ********************************************************/
private class ServersendAsyncAction extends AsyncTask<String, Void, String> {
/****************************** AsyncTask doInBackground() ACTION ********************************/
protected String doInBackground(String... args) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
boolean flag = true;
while (flag) /******** If data is send flag turn to be false *******/
{
try {
socket = new Socket("192.168.1.74", 4444);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(datastosend);
flag = false;
} catch (UnknownHostException e) {
flag = true;
e.printStackTrace();
} catch (IOException e) {
flag = true;
e.printStackTrace();
}
/******** CLOSING SOCKET *****************/
finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/******** CLOSING DATAOUTPUTSTREAM *******/
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/******** CLOSING DATAINPUTSTREAM ********/
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
/******** returns what you want to pass to the onPostExecute() *******/
}
/****************************** AsyncTask onPostExecute() ACTION *********************************/
protected void onPostExecute(String result) {
}
/********************* ENDING OF ASYN TASK CLASS ServersendAsyncAction ***************************/
}
public Context con;
public static ServerSocket serverSocket = null;
public class BackgroundServers extends AsyncTask<String, Void, String> {
public BackgroundServers(Context context) {
con=context;
}
/****************************** AsyncTask doInBackground() ACTION ********************************/
protected String doInBackground(String... args) {
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
serverSocket = new ServerSocket(9999);
System.out.println("Listening :9999");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(
socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
System.out.println("ip: " + socket.getInetAddress());
String incoming_message=(dataInputStream.readUTF());
incoming_message=incoming_message.replace("/", "");
String recdatas[]=incoming_message.split("#");
if(recdatas[0].equalsIgnoreCase("success"))
{
DatabaseConnection dbs=new DatabaseConnection(con);
int status=dbs.update("UPDATE hotel_pub_tables SET status='occupied' WHERE tableno='"+recdatas[1]+"'");
if(status>0)
{
tabelstatus=1;
//msg.obj="Table status changed!!!";
System.out.println("Table status changed!!!");
if (true) {
System.out.println("entered 222");
System.out.println(tabelstatus);
if(tabelstatus==1)
{
System.out.println(tabelstatus);
Food_Customizer.pd.dismiss();
System.out.println("success");
}
else if(tabelstatus==2)
{
Food_Customizer.pd.dismiss();
Intent intent = new Intent(Food_Customizer.this, Dinein_Tables.class);
startActivity(intent);
finish();
}
}
}
else
tabelstatus=2;
dbs.close();
}
dataOutputStream.writeUTF("Hello!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
/******** returns what you want to pass to the onPostExecute() *******/
}
/****************************** AsyncTask onPostExecute() ACTION *********************************/
#Override
protected void onPostExecute(String result) {
System.out.println("eneterd on posttttttttttttttt");
con.startActivity(new Intent(con, Dinein_Tables.class));
finish();
}
}
}
/********************* ENDING OF ASYN TASK CLASS BackgroundServers ***************************/
}
Well it's obvious that you setup your server on port 9999:
serverSocket = new ServerSocket(9999);
But you connect with the server on port 4444:
socket = new Socket("192.168.1.74", 4444);
Make sure you connect to the correct port-number otherwise it wont work. Hope this helps.
I have a simple connection activity:
package com.example.conn08;
import ...;
public class MainActivity extends Activity
{
public static Socket clientSocket;
public static DataOutputStream outToServer;
public static PrintWriter outTest;
public static BufferedReader inToServer;
With PrintWriter outTest I test server's availability:
If the user has no Internet, or the server doesn't work, I put Thread on a pause with Boolean shouldContinue.
private Thread mThread;
private final Object lock = new Object();
private Boolean shouldContinue = true;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThread = new Thread(new Runnable()
{
public void run()
{
while (true)
{
synchronized(lock)
{
try
{
lock.wait(); // lock the Thread
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
while (shouldContinue)
{
try
{
final String data = inToServer.readLine();
if (data != null)
{
Log.v("data", data);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
String put[] = data.split("#");
//Data parsing
}
});
}
}
catch (IOException e)
{
e.printStackTrace();
}
Check on availability of the server:
try {
if(clientSocket.getInputStream().read() == -1)
{
Log.v("Connection: ", "lost");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
mThread.start();
Connect();
}
public void Connect()
{
shouldContinue = true;
try
{
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress("localhost", 15780), 30000);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inToServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
outTest = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(clientSocket.getOutputStream())), true);
synchronized(lock)
{
lock.notify();
}
sendUTF("3#kokoko"); //send the message!
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void sendUTF(String str)
{
try
{
byte[] buf = str.getBytes("UTF-8");
outToServer.write(buf, 0, buf.length);
outToServer.writeBytes("\n");
outToServer.flush();
}
catch (IOException e)
{
e.printStackTrace();
outServ.setText("Нет соединения!");
}
}
}
Problem in that when I don't use the
if(clientSocket.getInputStream().read() == -1)
And send data to server like here:
sendUTF("3#kokoko");
All is fine, but if I use it, on server I see this message like
"#kokoko" - I lose the first character of the message and my socket is crushed! Help me please