I am working on an Android Application which have an one activity class and service class. In service, Continuous bulk data (1090 bytes) will be received every 10 milliseconds. I need to update the text view continuously with these bulk data. What is recommended way to update Text view from a continuous background service?
Service Class
public class RecepService extends Service {
public static Handler mHandler;
StringBuilder hexstring;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
init();
}
private void init() {
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
byte[] readBuf = (byte[]) msg.obj;
int readBuflen = msg.arg1;
// here will receive 1090 bytes of data
// every 10 milliseconds
Receivepatientattributes(readBuf,readBuflen);
}
}
};
}
public void Receivepatientattributes(byte[] readBuf, int len) {
String total_data = "";
total_data = bytetohex(readBuf, len);
MainActivity.recep.setText(MainActivity.recep.getText().toString() + "\t" +
"" + total_data );
}
String bytetohex(byte[] txt, int len) {
String p="";
byte[] text = new byte[len];
text = txt;
hexstring = new StringBuilder();
for (int j = 0; j < len; j++) {
String hex= Integer.toHexString(0xFF & txt[j]);
if (hex.length()==1) {
hexstring.append("0");
}
hexstring.append(hex+" ");
}
p=p+hexstring.toString();
return p;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
If you want to use Schedule and timer task then you can See My Answer
To solve current issue follow this bellow instructions.
Suppose your activity has a Broadcast Receiver
private BroadcastReceiver mReceiver;
Then you override methods onResume() where your broadcast receiver will be registered and also onPause() where will your receiver be unregistered:
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
IntentFilter intentFilter = new IntentFilter(
"android.intent.action.MAIN");
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract your message from intent
String msg_for_me = intent.getStringExtra("YOUR_MESSAGE");
//log your message value
Log.i("MyTag", msg_for_me);
}
};
//registering your receiver
this.registerReceiver(mReceiver, intentFilter);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
//unregister your receiver
this.unregisterReceiver(this.mReceiver);
}
Here the broadcast receiver is filtered via android.intent.action.MAIN and from Service the message will BroadCast using this filter
Now your Method Receivepatientattributes will like this :
public void Receivepatientattributes(byte[] readBuf, int len) {
String total_data = "";
total_data = bytetohex(readBuf, len);
Intent i = new Intent("android.intent.action.MAIN").putExtra("YOUR_MESSAGE", total_data);
this.sendBroadcast(i);
}
Thats it. :)
User LocalBroadcastManager
public void Receivepatientattributes(byte[] readBuf, int len) {
String total_data = "";
total_data = bytetohex(readBuf, len);
Intent intent = new Intent("update-text");
// add data
intent.putExtra("message", total_data);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
In MainActivity
#Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("update-text"));
}
private boolean mCanBeUpdated = true;
private static final int ONE_SEC = 1000; //ms
private static final int RECEPTION_SPEED = 10; //ms
private static final int CYCLES = (int) (ONE_SEC / RECEPTION_SPEED);
private int mCurrentCycle = -1;
private String mMsgCache = "";
// handler for received Intents for the "update-text" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
mMsgCache = mMsgCache + "\t" + message;
if (mCanBeUpdated) {
// No problem updating UI here, refer --> http://stackoverflow.com/a/5676888/1008278
final Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
MainActivity.recep.append(mMsgCache);
mMsgCache = "";
}
});
mCanBeUpdated = false;
} else if (mCurrentCycle >= CYCLES) {
mCurrentCycle = -1;
mCanBeUpdated = true;
} else {
mCurrentCycle++;
}
}
};
#Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
Reference
You can use Timer for Continously updating your textview.
Set value in preferences every time when your service is running with the latest value.
Now in Timer get that value from preferences and update your TextView with that value.
Here is some code :
class UpdateTimeTask extends TimerTask {
public void run() {
textview.setText("updated value");
}
}
Set in onCreate ();
Timer timer = new Timer();
UpdateTimeTask UpdateTimeTask = new UpdateTimeTask ();
timer.schedule(UpdateTimeTask, 1000);
Use handler beacuse A Handler allows communicating back with UI thread from other background thread.
boolean handlerStop = false;
void handleHandler(){
Handler handler =new Handler();
final Runnable r = new Runnable() {
public void run() {
handler.postDelayed(this, 30000);
if(!handlerStop) {
updateTextView() //update your text with other thread like asyncronous thread
}
}
};
handler.postDelayed(r, 0000);
}
#Override
public void onResume() {
super.onResume();
handlerStop=false;
handleHandler();
}
#Override
public void onPause() {
super.onPause();
handlerStop=true;
handleHandler();
}
#Override
public void onStop() {
super.onStop();
handlerStop=true;
handleHandler();
}
Related
I have the following scenario: a foreground service spawns 2 HandlerThreads (A and B). From time to time A must send some data to B, B performs a certain action on this data and sends back to A the result of the operation. I do not know how to effectivelly pass data between these 2 threads. Originally I was posting messages to the MainService thread (via handlers), which in turn posted it to the appropriate thread. But it seems like a bit overkill:
(thread A) post message to main thread handler
(main thread) receive the message and post it to the thread B handler
(thread B) do something and post the result back to the main thread handler
(main thread) receive the message and post it to the thread A handler
(thread A) do something
I thought that I could use LocalBroadcastManager, but it seems to be deprecated now. Do you have any suggestion on that?
EDIT 1
Simplified version of the program. I am afraid that the showed code will get too much complex after adding more signals between threads.
MainService.java
public class MainService extends Service {
private static final String TAG = "MainService";
public static final Integer START_A = 0;
public static final Integer DO_STH_IN_B = 1;
public static final Integer RESPOND_FROM_B_TO_A = 2;
private Handler mServiceHandler = new Handler(Looper.getMainLooper()) {
// this is a dispatcher for messages between threads
#Override
public void handleMessage(#NonNull Message msg) {
super.handleMessage(msg);
Message msg_s;
if (msg.what == DO_STH_IN_B)
msg_s = Message.obtain(myThreadB.getHandler());
else if (msg.what == RESPOND_FROM_B_TO_A)
msg_s = Message.obtain(myThreadA.getHandler());
else return;
msg_s.what = msg.what;
msg_s.sendToTarget();
}
};
private MyThreadA myThreadA = new MyThreadA(mServiceHandler);
private MyThreadB myThreadB = new MyThreadB(mServiceHandler);
#Override
public void onCreate() {
super.onCreate();
myThreadA.start();
myThreadB.start();
SystemClock.sleep(100);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification =
new NotificationCompat.Builder(this, "M_ID")
.setContentTitle("Notification Title")
.setContentText("Notification Text")
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
Message msg = Message.obtain(myThreadA.getHandler());
msg.what = START_A;
msg.sendToTarget();
//stopSelf();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
myThreadA.quit();
myThreadB.quit();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
MyThreadA.java
public class MyThreadA extends HandlerThread {
private static final String TAG = "MyThreadA";
private Handler mHandler;
private Handler mMainServiceHandler;
public MyThreadA(Handler handler) {
super(TAG, Process.THREAD_PRIORITY_BACKGROUND);
mMainServiceHandler = handler;
}
#SuppressLint("HandlerLeak")
#Override
protected void onLooperPrepared() {
mHandler = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
if (msg.what == MainService.START_A) {
mHandler.post(myRoutine);
} else if (msg.what == MainService.RESPOND_FROM_B_TO_A) {
mHandler.post(myRoutineRespond);
}
}
};
}
public Handler getHandler() { return mHandler; }
private Runnable myRoutine = new Runnable() {
#Override
public void run() {
Log.d(TAG, "run: [thread A] myRoutine");
// do something here (may be blocking)
SystemClock.sleep(1000);
// send message to Thread B (by passing it through the main service)
Message msg = Message.obtain(mMainServiceHandler);
msg.what = MainService.DO_STH_IN_B;
msg.sendToTarget();
// repeat the routine
mHandler.post(myRoutine);
}
};
private Runnable myRoutineRespond = new Runnable() {
#Override
public void run() {
Log.d(TAG, "run: [thread A] respond handler");
// do something here with the respond from B
SystemClock.sleep(2000);
}
};
}
MyThreadB.java
public class MyThreadB extends HandlerThread {
private static final String TAG = "MyThreadB";
private Handler mHandler;
private Handler mMainServiceHandler;
public MyThreadB(Handler handler) {
super(TAG, Process.THREAD_PRIORITY_BACKGROUND);
mMainServiceHandler = handler;
}
#SuppressLint("HandlerLeak")
#Override
protected void onLooperPrepared() {
mHandler = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
if (msg.what == MainService.DO_STH_IN_B) {
mHandler.post(myRoutine);
}
}
};
}
public Handler getHandler() { return mHandler; }
private Runnable myRoutine = new Runnable() {
#Override
public void run() {
Log.d(TAG, "run: [thread B] do something and respond");
// do something here (may be blocking)
SystemClock.sleep(2000);
// send respond back to Thread A
Message msg = Message.obtain(mMainServiceHandler);
msg.what = MainService.RESPOND_FROM_B_TO_A;
msg.sendToTarget();
}
};
}
I'm trying to creat a bacckground service that will have a thread that adds one to a counter every minute.
I want other apps to be able to call a methed call getBot that will retunt the value.
Right now I have a test app that has a activty that bindss to the app so it can talk to it to get the counter. When it exits it unbounds to it.
It has a button called botGert that gets the current counter value from the service.
When it unbounds to it, the service shuts down. How can I get it so it does not shut down????
service class
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;
static final int MSG_BOT_GET = 2;
static final int MSG_BOT_SET = 3;
static final int MSG_BOT_STOP = 4;
static final int MSG_BOT_PAUSE = 5;
static final int MSG_GET_ORDERS = 6;
static final int MSG_GET_POINT = 7;
static final int MSG_BOT_GET_RES = 2;
static final int PRICE_STATIC =1;
static final int PRICE_PERCENTAGE =2;
static final int PRICE_ALL = 3;
static final int VOL_STATIC = 1;
static final int VOL_PERCENTAGE = 2;
static final int VOL_ALL = 3;
int counter;
boolean isStop=false; // put bot in pause ste on next 1 min update
boolean isUYpdateNextMinute=false;
/**
This is called by a client to exicute code in this service
*/
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BOT_GET:
Message resp = Message.obtain(null, MSG_BOT_GET_RES);
Bundle bResp = new Bundle();
bResp.putString("respData", Integer.toString(counter ));
resp.setData(bResp);
try {
msg.replyTo.send(resp);
} catch (Exception e)
{
}
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
//////////////////////////////////////////////////////////////////////////////
// emplanent callbacks
MessengerService parent;
#Override
public void onCreate() {
Toast.makeText(this, "Service Created", Toast.LENGTH_LONG).show();
parent=this;
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
// sgart 1 minute update thread
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
}
///////////////////////////////////////////////////////////////
// thread code that runbs counter
class ThreadDemo extends Thread {
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
try {
do {
counter++;
Thread.sleep(1000 *60 );
counter++;
} while (true);
} catch(Exception e)
{
Toast.makeText(parent, "thread stopped", Toast.LENGTH_LONG).show();
}
} // end inner thread class
} // end class
}
/////////////////////////////////////////////////////////////////////
activity class
public class ActivityBoundMessenger extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bound_messenger);
}
/** Messenger for communicating with the service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
/////////////////////////////////////////////////////////////////////////////////////////
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};
////////////////////////////////////////////////////////////////////////////////
public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void butSet(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_BOT_SET, 0, 0);
Bundle b = new Bundle();
b.putString("data", "json object");
msg.setData(b);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void butGet(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message
.obtain(null, MessengerService.MSG_BOT_GET);
msg.replyTo = new Messenger(new ResponseHandler());
// We pass the value
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
////////////////////////////////////////////////////////////////////////////////////////
// these metheds get called whenb this acty starts and endsa
#Override
protected void onStart() {
super.onStart();
// Bind to the service
////////////////////////////////////////////
Intent ser = new Intent(this, MessengerService.class);
startService(ser);
bindService(ser, mConnection,
Context.BIND_AUTO_CREATE);
///////////////////////////////////////////
}
#Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
// This class handles the Service response
int ted=0;
String nextUpdate=null;
class ResponseHandler extends Handler {
#Override
public void handleMessage(Message msg) {
int respCode = msg.what;
switch (respCode) {
case MessengerService.MSG_BOT_GET_RES:
String nextUpdate= msg.getData().getString("respData");
ted++;
}
}
}
}
From Android Documentation:
When the last client unbinds from the service, the system destroys the service, unless the service was also started by startService().
So, all you have to do is call this in your onCreate() method in the Service:
startService(new Intent(this, MessengerService.class))
Of course make sure to call stopSelf() when you are done with the service.
I'm developing a application when which every 4,5 seconds the client checks whether the server responds "OK".
It's even working, But if I turn on/off the internet sometimes it stops working, it is inconsistent and I need to check the messages accurately.
And service stop like in example I gave and it re-operate outside the specified range of seconds (4.5)
I'm developing a chat, and I need to know this precisely, I need to be professional.
Start.java
public class Start extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
Intent serviceIntent = new Intent(getBaseContext(), BackExec.class);
getBaseContext().startService(serviceIntent);
}
#Override
protected void onResume()
{
super.onResume();
Intent serviceIntent = new Intent(getApplicationContext(), BackExec.class);
startService(serviceIntent);
}}
BackExec.java
public class BackExec extends Service {
static Timer t;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
String r = getData();
if(r != null){
if(r.equals("OK")){
NotificationCompat.Builder b = new NotificationCompat.Builder(getApplicationContext());
b.setSmallIcon(R.drawable.ic_ex);
b.setContentText("YOU HAVE NOTIFICATONS, CLICK.");
b.setContentTitle("TITLE APP:");
b.setOngoing(false);
b.setPriority(Notification.PRIORITY_MAX); //TALVEZ FUNCIONE
NotificationManager m = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
m.notify(0, b.build());
}
}
}
}, 1, 4500);
}
public int onStartCommand(Intent intent, int flags, int startId) {
t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
String r = getData();
if(r != null){
if(r.equals("OK")){
NotificationCompat.Builder b = new NotificationCompat.Builder(getApplicationContext());
b.setSmallIcon(R.drawable.ic_ex);
b.setContentText("YOU HAVE NOTIFICATONS, CLICK.");
b.setContentTitle("TITLE APP:");
b.setOngoing(false);
b.setPriority(Notification.PRIORITY_MAX); //TALVEZ FUNCIONE
NotificationManager m = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
m.notify(0, b.build());
}
}
}
}, 1, 4500);
return START_STICKY;
}
public static String getData(){
URL site = null;
try {
site = new URL("http://192.168.0.10:8080/example/server.php");
URLConnection urlConn = site.openConnection();
urlConn.setRequestProperty("Cookie", CookieManager.getInstance().getCookie("http://192.168.0.10:8080/example"));
urlConn.setDoOutput(true);
PrintStream enviarInfos = new PrintStream(urlConn.getOutputStream());
enviarInfos.print("pac=pac");
urlConn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String inputLine;
String out = "";
while ((inputLine = in.readLine()) != null)
out = out + inputLine;
in.close();
return out;
} catch (MalformedURLException e) {
return null;
} catch (IOException e) {
return null;
}
}
public void onStart(Intent intent, int startId) { } // TO DO
public IBinder onUnBind(Intent arg0) {
return null;
}
public void onStop() {}
public void onPause() {}
#Override
public void onDestroy() {}
#Override
public void onLowMemory() {} }
Actually i have a TCP Client that onStart connect to the server and send the device IP and number to it, but now i want that when the application is getting closed ( onDestroy ) delay it for some seconds ( the right time to reopen the connection and send another message ) and send another message in which i'm saying that the device is offline.
I've tryed to do it onDestroy method but probably it's madness and obviously
that didn't worked ( i tryed to do the following stuff onDestroy :
protected void onDestroy() {
new ConnectTask().execute("");
if (client != null) {
client.sendMessage(trm + "OFFLINE");
}
if (client != null) {
client.stopClient();
}
super.onDestroy();
server.onDestroy();
}
Here is my MainActivity code where i evocate the TCP Client and sending start message:
public class MainActivity extends AppCompatActivity {
Server server;
static Client client;
settings Settings;
public static TextView terminale, indr, msg;
TextView log;
static TextView msgServer;
static String ipp;
static String trm;
static DataBaseHandler myDB;
allert Allert;
SharedPreferences prefs;
String s1 = "GAB Tamagnini SRL © 2017 \n" +
"Via Beniamino Disraeli, 17,\n" +
"42124 Reggio Emilia \n" +
"Telefono: 0522 / 38 32 22 \n" +
"Fax: 0522 / 38 32 72 \n" +
"Partita IVA, Codice Fiscale \n" +
"Reg. Impr. di RE 00168780351 \n" +
"Cap. soc. € 50.000,00 i.v. \n" + "" +
"REA n. RE-107440 \n" +
"presso C.C.I.A.A. di Reggio Emilia";
ImageButton settings, helps, allerts, home;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Utils.darkenStatusBar(this, R.color.colorAccent);
server = new Server(this);
myDB = DataBaseHandler.getInstance(this);
msg = (TextView) findViewById(R.id.msg);
log = (TextView) findViewById(R.id.log_avviso);
settings = (ImageButton) findViewById(R.id.impo);
helps = (ImageButton) findViewById(R.id.aiut);
allerts = (ImageButton) findViewById(R.id.msge);
home = (ImageButton) findViewById(R.id.gab);
terminale = (TextView) findViewById(R.id.terminal);
indr = (TextView) findViewById(R.id.indr);
msgServer = (TextView) findViewById(R.id.serverMSG);
final Cursor cursor = myDB.fetchData();
if (cursor.moveToFirst()) {
do {
indr.setText(cursor.getString(1));
terminale.setText(cursor.getString(2));
Client.SERVER_IP = cursor.getString(1);
trm = cursor.getString(2);
} while (cursor.moveToNext());
}
startService(new Intent(MainActivity.this,FinalizingOperationsService.class));
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
ipp = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
startConnection.postDelayed(runnableConnection,5000);
startMessage.postDelayed(runnableMessage,5500);
cursor.close();
server.Parti();
home.setOnClickListener(new View.OnClickListener() {
int counter = 0;
#Override
public void onClick(View view) {
counter++;
if (counter == 10) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setMessage(s1);
builder.show();
counter = 0;
}
}
});
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent impostazioni = new Intent(getApplicationContext(), settingsLogin.class);
startActivity(impostazioni);
}
});
helps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent pgHelp = new Intent(getApplicationContext(), help.class);
startActivity(pgHelp);
}
});
allerts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Server.count = 0;
SharedPreferences prefs = getSharedPreferences("MY_DATA", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.clear();
editor.apply();
msg.setVisibility(View.INVISIBLE);
Intent pgAlert = new Intent(getApplicationContext(), allert.class);
startActivity(pgAlert);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
server.onDestroy();
}
public static class ConnectTask extends AsyncTask<String, String, Client> {
#Override
protected Client doInBackground(String... message) {
client = new Client(new Client.OnMessageReceived() {
#Override
public void messageReceived(String message) {
publishProgress(message);
}
});
client.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
msgServer.setTextColor(Color.parseColor("#00FF00"));
msgServer.setText("ONLINE");
Log.d("test", "response " + values[0]);
}
}
static Handler startConnection = new Handler();
static Runnable runnableConnection = new Runnable() {
#Override
public void run() {
new ConnectTask().execute("");
}
};
static Handler startMessage = new Handler();
static Runnable runnableMessage = new Runnable() {
#Override
public void run() {
final Cursor cursor = myDB.fetchData();
if (cursor.moveToFirst()) {
do {
Client.SERVER_IP = cursor.getString(1);
trm = cursor.getString(2);
} while (cursor.moveToNext());
}
if (client != null) {
client.sendMessage(ipp + "#" + trm);
}
}
};
static Handler startMessageClose = new Handler();
static Runnable runnableMessageClose = new Runnable() {
#Override
public void run() {
if (client != null) {
client.sendMessage(trm + "IS OFFLINE");
}
}
};
}
The right command for open the connection is new ConnectTask().execute("");
while i'm sending the message with if (client != null) { client.sendMessage(ipp + "#" + trm); }
FinalizingOperationsService.java code:
public class FinalizingOperationsService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("FOService", "Service Started");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("FOService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("FOService", "Service Ends");
MainActivity.startConnection.removeCallbacks(MainActivity.runnableConnection);
MainActivity.startConnection.postDelayed(MainActivity.runnableConnection,100);
MainActivity.startMessageClose.removeCallbacks(MainActivity.runnableMessageClose);
MainActivity.startMessageClose.postDelayed(MainActivity.runnableMessageClose,110);
stopSelf();
}
}
Create a new service like this,
public class FinalizingOperationsService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("FOService", "Service Started");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("FOService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("FOService", "Service Ends");
// write server updation code here
// after completing code perform stopself() to stop this service;
}
}
And define this service in manifest file like this,
<service android:name=". FinalizingOperationsService" android:stopWithTask="false"/>
Finally start service in onCreate method of your main activity
startService(newIntent(getContext(),FinalizingOperationsService.class));
Explanation:
onTaskRemoved() method of the service is called when application is killed or destroyed, so in this method you can perform your final operations to notify server and stop your service after operations done. Hope it will help you.
Service stop working when turn on /of Wi-Fi many time, when I start service do counter 1,2,3 etc or any thing then turn on /of Wi-Fi many time the service stops working ,I have BroadcastReceiver class doing start service, no exceptions , error appear , only I sent one message to phone to start service..
This is the code inside BroadcastReceiver:
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Intent recorderIntent = new Intent(context, Start2.class);
context.startService(recorderIntent);
}
This My Start2 Service:
public class Start2 extends Service {
private static final String TAG = Start2.class.getSimpleName();
int mStartMode;
#Override
public void onDestroy() {
Log.d(TAG, "Stop Service onDestroy");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
final Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
int i = 0 ;
#Override
public void run() {
try{
//do your code here
Log.d(TAG, "Start Service Repeat Time.. " + i);
i++;
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable to call it at regular interval
handler.postDelayed( this, 5000 );
}
}
};
handler.postDelayed(runnable, 1000 );
return null;
}
};
task.execute();
return mStartMode;
}
}