Why does this service stop? - android

I have the following Service that is meant to check a web API.
The Implementation is meant to retry the HTTP request 5 times before issuing a notification.
Anyway it seems that the service simply stops after the first attempt.
Please what is going on???
public class CreditcheckService extends IntentService {
public CreditcheckService() {
super("CreditcheckService");
}
#Override
protected void onHandleIntent(Intent intent) {
String phone = "";
phone = intent.getStringExtra("phone");
checkcreditonline(phone);
Log.e("inizio il service","inizio il service");
}
private void checkcreditonline(final String phone) {
final Handler h = new Handler();
final JsonHttpResponseHandler jsonHttpResponseHandler = new JsonHttpResponseHandler() {
private int counter = 0;
#Override
public void onSuccess(JSONObject arg0) {
int cazzo=0;
cazzo++;
try {
String status = arg0.getString("credit");
} catch (JSONException e) {
e.printStackTrace();
}
try {
String status = arg0.getString("error");
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable arg0) {
//IF FAILED SHOULD RETRY, BUT IT DOESN'T
if (counter < 5) {
//HERE THE SUCCESSIVE ATTEMPTS
h.postDelayed(new WebserviceRunnable(this, phone), 5000);
} else {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(CreditcheckService.this)
.setSmallIcon(R.drawable.icon)
.setContentTitle(getResources().getString(R.string.unable_to))
.setContentText(getResources().getString(R.string.please_connect));
mBuilder.setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), 0));
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(999, mBuilder.build());
}
counter++;
}
};
h.post(new WebserviceRunnable(jsonHttpResponseHandler, phone));
}
private class WebserviceRunnable implements Runnable {
private JsonHttpResponseHandler jsonHttpResponseHandler;
private String email;
public WebserviceRunnable(
JsonHttpResponseHandler jsonHttpResponseHandler, String aEmail) {
this.jsonHttpResponseHandler = jsonHttpResponseHandler;
this.email = aEmail;
}
public void run() {
try {
WebServiceApi.get(
"rest/credit/get/" + URLEncoder.encode(email, "utf-8"),
null, jsonHttpResponseHandler);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}

onHandleIntent in IntentService is asynchronous.
When onHandleIntent exits, the Service is stopped.
So don't post a message to a Handler, instead do it directly in checkcreditonline().

Related

Asynctask within fragments doesn't work when service is running

I have a drawerlayout and he call many fragments and they have asynctask within, also i have created a notification service, it's work very fine in api level < 11 but when the level is > 10 the asynctask of fragment only work when the service is not running, why?
My code of service is here
public class NotificationService extends Service {
MyTask myTask;
private final String url_notificaciones = "http://www.domain.com/domain/getNotificaciones.php";
private static final String TAG_TIPO_NOTIFICACION = "tipo_notificacion";
private static final String TAG_TITULO_NOTIFICACION= "titulo_notificacion";
private static final String TAG_DESCRIPCION_NOTIFICACION= "descripcion_notificacion";
private String jsonResult;
SessionManagement session;
boolean InitializeNotificationManager = true;
private HashMap<String, String> user;
private String id_datos_usuarios_session;
private JsonReadTask task;
private Handler handler = new Handler();
private TaskCanceler taskCanceler;
#Override
public void onCreate() {
super.onCreate();
try {
session = new SessionManagement(getApplication());
user = session.getUserDetails();
id_datos_usuarios_session = user.get(SessionManagement.KEY_ID_DATOS_USUARIOS).toString();
}catch (Exception e){
InitializeNotificationManager = false;
}
myTask = new MyTask();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
myTask.execute();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
myTask.cancel(true);
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
private class MyTask extends AsyncTask<String, String, String> {
private String date;
private boolean cent;
#Override
protected void onPreExecute() {
super.onPreExecute();
cent = true;
}
#Override
protected String doInBackground(String... params) {
while (cent) {
try {
if(isNetworkStatusAvialable (getApplication())) {
accessWebService();
}
// Stop 20s
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
//Toast.makeText(getApplicationContext(), "Hora actual: ", Toast.LENGTH_SHORT).show();
}
#Override
protected void onCancelled() {
super.onCancelled();
cent = false;
}
}
public void accessWebService(){
task = new JsonReadTask();
taskCanceler = new TaskCanceler(task);
handler.postDelayed(taskCanceler, 15*1000);
task.execute(new String[]{url_notificaciones});
}
private class JsonReadTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("get_app_id_datos_usuarios", id_datos_usuarios_session));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(
response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (IOException e) {
// e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error..." + e.toString(), Toast.LENGTH_LONG).show();
}
return answer;
}
#Override
protected void onPostExecute(String result) {
ListDrwaer();
}
// build hash set for list view
public void ListDrwaer() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("notification");
JSONObject jsonChildNode = jsonMainNode.getJSONObject(0);
String tipo_notificacion = jsonChildNode.getString(TAG_TIPO_NOTIFICACION);
String titulo_notificacion = jsonChildNode.getString(TAG_TITULO_NOTIFICACION);
String descripcion_notificacion = jsonChildNode.getString(TAG_DESCRIPCION_NOTIFICACION);
if(tipo_notificacion.equals("1")) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("MenuNotificationFragment", "MyFriendsRequired");
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
// Creamos la notificación. Las acciones son de "mentirijilla"
Notification noti = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle(titulo_notificacion)
.setContentText(descripcion_notificacion).setSmallIcon(R.mipmap.icon_app)
.setContentIntent(pIntent)
.setLights(0xffff00, 4000, 100)
/*.addAction(R.drawable.ic_arrow, "Llamada", pIntent)
.addAction(R.drawable.ic_arrow, "Más", pIntent)
.addAction(R.drawable.ic_arrow, "Mucho Más", pIntent)*/.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Ocultamos la notificación si ha sido ya seleccionada
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
//Sound notification
try {
Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), ringtoneUri);
ringtone.play();
} catch (Exception e) {
}
//Vibrate notification
try {
// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Start without a delay
// Vibrate for 100 milliseconds
// Sleep for 1000 milliseconds
long[] pattern = {0, 100, 2000};
// The '0' here means to repeat indefinitely
// '0' is actually the index at which the pattern keeps repeating from (the start)
// To repeat the pattern from any other point, you could increase the index, e.g. '1'
v.vibrate(pattern, -1);
} catch (Exception e) {
}
}else if(tipo_notificacion.equals("2")){
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("MenuNotificationFragment", "MyBussinesRequired");
PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
// Creamos la notificación. Las acciones son de "mentirijilla"
Notification noti = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle(titulo_notificacion)
.setContentText(descripcion_notificacion).setSmallIcon(R.mipmap.icon_app)
.setContentIntent(pIntent)
.setLights(0xffff00, 4000, 100)
/*.addAction(R.drawable.ic_arrow, "Llamada", pIntent)
.addAction(R.drawable.ic_arrow, "Más", pIntent)
.addAction(R.drawable.ic_arrow, "Mucho Más", pIntent)*/.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Ocultamos la notificación si ha sido ya seleccionada
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
//Sound notification
try {
Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), ringtoneUri);
ringtone.play();
} catch (Exception e) {
}
//Vibrate notification
try {
// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Start without a delay
// Vibrate for 100 milliseconds
// Sleep for 1000 milliseconds
long[] pattern = {0, 100, 2000};
// The '0' here means to repeat indefinitely
// '0' is actually the index at which the pattern keeps repeating from (the start)
// To repeat the pattern from any other point, you could increase the index, e.g. '1'
v.vibrate(pattern, -1);
} catch (Exception e) {
}
}
} catch (JSONException e) {
}
}
}// end async task
//If the internet connection is ok
public static boolean isNetworkStatusAvialable (Context context) {
try {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo netInfos = connectivityManager.getActiveNetworkInfo();
if (netInfos != null)
if (netInfos.isConnected())
return true;
}
}catch (Exception e){
return false;
}
return false;
}
public class TaskCanceler implements Runnable{
private AsyncTask taskR;
public TaskCanceler(AsyncTask task) {
this.taskR = task;
}
#Override
public void run() {
if (task.getStatus() == AsyncTask.Status.RUNNING ) {
task.cancel(true);
}
}
}
}
Starting on Android 11 AsyncTask objects shares a single thread. So your service is blocking that thread, and the fragments can't run. The easiest solution is pretty obvious here, don't use AsyncTask for the service. It doesn't even make sense to use it there because AsyncTask is meant to deliver results back on the UI thread, something your service doesn't need to do. Here is a possible solution:
public class MyService extends Service implements Runnable {
private HandlerThread = ht;
private Handler handler;
#Override
public void onCreate() {
super.onCreate();
try {
session = new SessionManagement(getApplication());
user = session.getUserDetails();
id_datos_usuarios_session = user.get(SessionManagement.KEY_ID_DATOS_USUARIOS).toString();
}catch (Exception e){
InitializeNotificationManager = false;
}
ht = new HandlerThread("MyService");
ht.start();
handler = new Handler(ht.getLooper());
handler.post(this);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(this);
ht.quit();
ht = null;
handler = null;
}
#Override
public void run(){
if(isNetworkStatusAvialable (getApplication())) {
accessWebService();
}
handler.postDelayed(20000, this);
}
}

Schedule Asynctask - While? Service? Timer?

Ok, I got a Togglebutton that starts a service. The service starts a new Thread in onStartCommand. In this Thread an Asynctask is executed.
Now I want this Asynctask to be executed for example every 5 seconds. The Asynctask checks if the website is available.
-> if no, after 5 secs check again
-> if yes, show message and stop
Whats the best method with my already present code:
public class NotifiyService extends Service {
String savedsa;
Thread Th1;
boolean value;
final class TheThread implements Runnable{
int serviceID;
String savedsa1;
TheThread(int serviceID,String savedsa){
this.serviceID = serviceID;
this.savedsa1 = savedsa;
}
#Override
public void run() {
HttpTaskParams httpparams = new HttpTaskParams(value,savedsa1);
new HttpTask().execute(httpparams);
}
}
public NotifiyService() {
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SharedPreferences sharedPreferences7 = getSharedPreferences("Prefsa",MODE_WORLD_READABLE);
savedsa = sharedPreferences7.getString("keysa","");
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStarted)+ "\n" + savedsa,Toast.LENGTH_LONG).show();
Th1 = new Thread(new TheThread(startId,savedsa));
Th1.start();
return START_STICKY;
}
#Override
public void onDestroy() {
//super.onDestroy();
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStopped), Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
private static class HttpTaskParams{
boolean value;
String address;
HttpTaskParams(boolean value, String address){
this.value = value;
this.address = address;
}
}
private class HttpTask extends AsyncTask<HttpTaskParams,Void,Boolean>{
#Override
protected Boolean doInBackground(HttpTaskParams... params) {
boolean value = params[0].value;
String address = params[0].address;
try {
URL url = new URL(address);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("HEAD");
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setReadTimeout(3000);
httpURLConnection.connect();
value = true;
return value;
} catch (MalformedURLException e) {
e.printStackTrace();
value = false;
return value;
} catch (IOException e) {
e.printStackTrace();
value = false;
return value;
}
}
#Override
protected void onPostExecute(Boolean result) {
if(result){
Toast.makeText(NotifiyService.this,"true",Toast.LENGTH_SHORT).show();
//Notification in Status Bar
NotificationCompat.Builder builder = new NotificationCompat.Builder(NotifiyService.this);
builder.setSmallIcon(R.drawable.dummy);
Intent intent = new Intent(NotifiyService.this, Main2Activity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(NotifiyService.this,0,intent,0);
builder.setContentIntent(pendingIntent);
builder.setLights(Color.YELLOW,600,600);
builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.dummy));
builder.setContentTitle(getResources().getString(R.string.newNotify));
builder.setContentText(getResources().getString(R.string.newNotify2));
builder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1,builder.build());
}
else{
Toast.makeText(NotifiyService.this,"false",Toast.LENGTH_SHORT).show();
}
}
}
}
EDIT:
#Override
public void run() {
ScheduledExecutorService checkreg = Executors.newScheduledThreadPool(1);
scheduledFuture = checkreg.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
HttpTaskParams httpparams = new HttpTaskParams(value, savedsa1);
new HttpTask().execute(httpparams);
}
}, 0, 20, TimeUnit.SECONDS);}
#Override
public void onDestroy() {
//super.onDestroy();
Th1.interrupt();
scheduledFuture.cancel(false);
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStopped), Toast.LENGTH_LONG).show();
stopSelf();
}
I think a ScheduledExecutorService could help you.
Please check this answer.
Please let me know if this helps you.
try this /**
* Loads exchange rates form network periodically
* Returns results in broadcast message.
* Created by koss on 19.02.16.
* */
public class EcbEuropeService extends Service {
public static final String ECB_URL = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
public static final int UPDATE_PERIOD = 30000;
public static final int UPDATE_TICK = 1000;
public static final String NOTIFICATION = "koss.ru.oneclickrate.receiver";
public static final String EXTRA_CURRENCIES_MAP = "extra_currencies_map";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
getUrlData();
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public Cubes getUrlData() {
(new AsyncTask<Object, Object, Cubes>() {
Map<CurrencyType, BigDecimal> result = new EnumMap<CurrencyType, BigDecimal>(CurrencyType.class);
#Override
protected Cubes doInBackground(Object... params) {
Cubes cubes = new Cubes();
InputStream is = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(ECB_URL);
urlConnection = (HttpURLConnection) url.openConnection();
is = urlConnection.getInputStream();
cubes = EcbEuropeResponseParser.parse(is);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(urlConnection!=null) IOUtils.close(urlConnection);
if(is!=null) IOUtils.closeQuietly(is);
return cubes;
}
}
#Override
protected void onPostExecute(Cubes map) {
super.onPostExecute(map);
sendBroadcastMessage(map);
startTimer();
}
}).execute();
return null;
}
/**
* Restarts timer
* */
public void startTimer() {
cdt.cancel();
cdt.start();
}
CountDownTimer cdt = new CountDownTimer(UPDATE_PERIOD, UPDATE_TICK) {
#Override
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
getUrlData();
}
};
private void sendBroadcastMessage(Cubes currenciesMap) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(EXTRA_CURRENCIES_MAP, currenciesMap);
sendBroadcast(intent);
}
}

Android background service and wake lock

I have android background service to connect with my RabbitMQ server. My background service listen incoming rabbitmq message. Everything is working well but the problem is appear while screen goes off. My android client disconnect when phone screen goes off. What should I do to always connected with my android rabbitmq client and rabbitmq server ?
My code are below :
public class RabbitmqPushService extends Service{
private Thread subscribeThread;
private ConnectionFactory factory;
private Connection connectionSubscribe;
private Channel channelSubscribe;
private NotificationManager mNotificationManager;
public static int NOTIFICATION_ID = 0;
private static final String HOST_NAME = Constant.HOST_NAME; //Rabbitmq Host Name
private static final int PORT_ADDRESS = 5672;
private static final String EXCHANGE_NAME = "fanout_msg";
private static String QUEUE_NAME = Constant.phone_number+"_queue"; //Queue Name
private static String[] ROUTE_KEY = {"all", Constant.phone_number};
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
NOTIFICATION_ID = 0;
setupConnectionFactory();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(connectionSubscribe != null)
{
if(!connectionSubscribe.isOpen())
{
connect();
}
}
else
{
connect();
}
return Service.START_STICKY;
}
#Override
public void onDestroy() {
if(connectionSubscribe != null)
{
disconnectSubscribe();
}
NOTIFICATION_ID = 0;
}
private void setupConnectionFactory() {
factory = new ConnectionFactory();
factory.setHost(HOST_NAME);
factory.setPort(PORT_ADDRESS);
factory.setUsername(Constant.USERNAME);
factory.setPassword(Constant.PASSWORD);
factory.setRequestedHeartbeat(60);
}
private void connect()
{
final Handler incomingMessageHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String message = msg.getData().getString("msg");
try {
JSONObject jsonObject = new JSONObject(message);
BeepHelper.msgBeep(getApplicationContext());
sendNotification("From : " + jsonObject.getString("from"), jsonObject.getString("message"));
} catch (JSONException e) {
e.printStackTrace();
}
}
};
subscribe(incomingMessageHandler);
publishToAMQP();
}
private void disconnectSubscribe()
{
subscribeThread.interrupt();
try {
channelSubscribe.close();
connectionSubscribe.close();
} catch (IOException e) {
e.printStackTrace();
}
catch (TimeoutException e) {
e.printStackTrace();
}
}
void subscribe(final Handler handler)
{
subscribeThread = new Thread()
{
#Override
public void run() {
while(true) {
try {
connectionSubscribe = factory.newConnection();
channelSubscribe = connectionSubscribe.createChannel();
channelSubscribe.exchangeDeclare(EXCHANGE_NAME, "fanout");
channelSubscribe.queueDeclare(QUEUE_NAME, true, false, false, null);
for(int i = 0; i<ROUTE_KEY.length; i++)
{
channelSubscribe.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTE_KEY[i]);
}
QueueingConsumer consumer = new QueueingConsumer(channelSubscribe);
channelSubscribe.basicConsume(QUEUE_NAME, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
Message msg = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putString("msg", message);
msg.setData(bundle);
handler.sendMessage(msg);
channelSubscribe.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
} catch (InterruptedException e) {
break;
} catch (Exception e1) {
try {
Thread.sleep(4000); //sleep and then try again
} catch (InterruptedException e) {
break;
}
}
}
}
};
subscribeThread.start();
}
#Override
public void publishMessage(String message) {
try {
queue.putLast(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void sendNotification(String title, String msg) {
mNotificationManager = (NotificationManager)
getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), MainActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID++, mBuilder.build());
}
}
You need a Wake Lock to keep the phone running when screen is off. Wake locks allow your application to control the power state of the host device.
Add the WAKE_LOCK permission to your application's manifest file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Then add the following in onCreate():
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakelock= pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getCanonicalName());
wakelock.acquire();
If your app includes a broadcast receiver that uses a service to do some work, you can manage your wake lock through a WakefulBroadcastReceiver. This is the preferred approach. If your app doesn't follow that pattern, you set a wake lock directly.

Android service thread making web request is blocking UI

First I will explain the current situation.
I've 2 different threads in 2 services(read from usb port service and make web requests service). I'm starting them in onCreate of my activity like:
serialServiceIntent = new Intent(NDKSerialActivity.this, SerialService.class);
startService(serialServiceIntent);
webServiceIntent = new Intent(NDKSerialActivity.this, RecordWebService.class);
startService(webServiceIntent);
There is nothing wrong with serial service but in RecordWebService when I make a request my gui stops until response comes.
The code is like that:
public class RecordWebService extends Service
{
public static final String SERVER_ADDRESS = "http://192.168.1.100:8080/MobilHM/rest";
private static final String TAG = RecordWebService.class.getSimpleName();
private RecordWebThread recordWebThread;
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
recordWebThread = new RecordWebThread(true);
recordWebThread.start();
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.i(TAG, "RecordWebService Destroyed");
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
and
public class RecordWebThread extends Thread
{
private static final String TAG = RecordWebThread.class.getSimpleName();
public boolean always;
public RecordWebThread(boolean always)
{
this.always = always;
}
#Override
public void run()
{
PatientRecord patientRecord = new PatientRecord();
while (always)
{
RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
try
{
restClient.execute(RequestMethod.GET);
}
catch (Exception e1)
{
Log.e(TAG, "", e1);
}
Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
Log.i(TAG, "Server Response:->" + restClient.getResponse());
try
{
sleep(4 * 1000);
}
catch (InterruptedException e)
{
Log.e(TAG, "Web service interrupted", e);
}
}
}
}
Also I've tried to remove sleep part and make the thread to run with timer and timer task like:
public void sendRecord()
{
scanTask = new TimerTask()
{
public void run()
{
handler.post(new Runnable()
{
public void run()
{
RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
try
{
restClient.execute(RequestMethod.GET);
}
catch (Exception e1)
{
Log.e(TAG, "", e1);
}
Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
Log.i(TAG, "Server Response:->" + restClient.getResponse());
}
});
}
};
t.schedule(scanTask, 1000, 4000);
}
but no luck, my gui hangs when it comes to restClient.execute .
You can find RestClient.java # http://www.giantflyingsaucer.com/blog/?p=1462
How can I make my requests not block my gui thread?
Edit:
public void sendRecord()
{
scanTask = new TimerTask()
{
public void run()
{
RestClient restClient = new RestClient(RecordWebService.SERVER_ADDRESS + "/hello");
try
{
restClient.execute(RequestMethod.GET);
}
catch (Exception e1)
{
Log.e(TAG, "", e1);
}
Log.i(TAG, "Server Response Code:->" + restClient.getResponseCode());
Log.i(TAG, "Server Response:->" + restClient.getResponse());
}
};
t.schedule(scanTask, 1000, 4000);
}
Without handler, I call this in onCreate of my activity but still ui hanging.
Or you can use an IntentService which will handle the thread issues for you.
This is an example class:
public class MyService extends IntentService {
public MyService() {
super("MyService");
}
public MyService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent arg0) {
//Do what you want
}
}
Then you just call:
Intent intent = new Intent(getApplicationContext(),MyService.class);
startService(intent);
Edit:
To repeat the same thing every 4 seconds you should do something like this:
PendingIntent serviceIntent= PendingIntent.getService(context,
0, new Intent(context, MyService.class), 0);
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
long intervalInSec = 4;
am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, intervalInSec*1000, serviceIntent)
;
In your code (2d version) happens next: You create thread, and it asks UI thread to do some net interaction. Just exclude handler.post(...) while executing request. Later you can use this for simple runnable for updating your UI with results of request.

When running my Android App in the Eclipse Debugger, I have a service that notifies. Outside of the debugger it does not send a notification

I'm making an app that sends a notification to the status bar, it sends the notification when stepping through the code in the debugger, however it never sends the notification when run in realtime.
Here is my runnable that generates the notification, again when stepping through this code in the debugger the notification runs however in realtime nothing happens.
public class NewsEvents_Service extends Service {
private static final String NEWSEVENTS = "newsevents";
private static final String KEYWORDS = "keywords";
private NotificationManager mNM;
private ArrayList<NewsEvent> neList;
private int count;
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
neList = new ArrayList<NewsEvent>();
getKeywords();
//getNewsEvents();
Thread thr = new Thread(null, mTask, "NewsEvents_Service");
thr.start();
Log.d("Thread", "IT STARTED!!!!!!????!!!!!!!!!!!!!!!?!!?");
}
#Override
public void onDestroy() {
// Cancel the notification -- we use the same ID that we had used to start it
mNM.cancel(R.string.ECS);
// Tell the user we stopped.
Toast.makeText(this, "Service Done", Toast.LENGTH_SHORT).show();
}
/**
* The function that runs in our worker thread
*/
Runnable mTask = new Runnable() {
public void run() {
getNewsEventsFromWeb();
for(NewsEvent ne : neList){
Log.d("Thread Running", "Service Code running!!!!!!!!!!!!!!!");
String body = ne.getBody().replaceAll("\\<.*?>", "");
String title = ne.getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
ne.setInterested(true);
}
}
if(ne.isInterested() == true ){
Notification note = new Notification(R.drawable.icon,
"New ECS News Event", System.currentTimeMillis());
Intent i = new Intent(NewsEvents_Service.this, FullNewsEvent.class);
i.putExtra("ne", ne);
PendingIntent pi = PendingIntent.getActivity(NewsEvents_Service.this, 0,
i, 0);
note.setLatestEventInfo(NewsEvents_Service.this, "New Event", ne.getTitle(), pi);
note.flags = Notification.FLAG_AUTO_CANCEL;
mNM.notify(R.string.ECS, note);
}
}
}
};
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* Show a notification while this service is running.
*/
private void getNewsEventsFromWeb() {
HttpClient client = new DefaultHttpClient();
HttpGet get;
try {
get = new HttpGet(getString(R.string.jsonnewsevents));
ResponseHandler<String> response = new BasicResponseHandler();
String responseBody = client.execute(get, response);
String page = responseBody;
Bundle data = new Bundle();
data.putString("page",page);
Message msg = new Message();
msg.setData(data);
handler.sendMessage(msg);
}
catch (Throwable t) {
Log.d("UpdateNews", "PROBLEMS");
}
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private ArrayList<String> keyWordList;
public void getNewsEvents(){
try {
InputStream fi = openFileInput(NEWSEVENTS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
neList = (ArrayList<NewsEvent>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(neList == null){
neList = new ArrayList<NewsEvent>();
}
}
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
/**
* This is the object that receives interactions from clients. See RemoteService
* for a more complete example.
*/
private final IBinder mBinder = new Binder() {
#Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
return super.onTransact(code, data, reply, flags);
}
};
}
Here is my activity that schedules the service to run
public class NewsEvents extends ListActivity{
private URL JSONNewsEvents;
private ArrayList<NewsEvent> neList;
private ArrayList<String> keyWordList;
private Worker worker;
private NewsEvents ne;
public static final String KEYWORDS = "keywords";
private static final String NEWSEVENTS = "newsevents";
public static final int ONE_ID = Menu.FIRST+1;
private PendingIntent newsAlarm;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsevents);
ne = this;
neList = new ArrayList<NewsEvent>();
try {
JSONNewsEvents = new URL(getString(R.string.jsonnewsevents));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
worker = new Worker(handler, this);
setListAdapter(new IconicAdapter());
getKeywords();
worker.execute(JSONNewsEvents);
}
#Override
protected void onStop() {
super.onStop();
writeNewsEvents() ;
}
#Override
protected void onPause(){
super.onPause();
writeNewsEvents();
}
private void writeNewsEvents() {
try {
OutputStream fi = openFileOutput(NEWSEVENTS, 0);
if (fi!=null) {
ObjectOutputStream out = new ObjectOutputStream(fi);
out.writeObject(neList);
out.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
}
/**
* #return
*/
public ArrayList<String> getKeywords(){
try {
InputStream fi = openFileInput(KEYWORDS);
if (fi!=null) {
ObjectInputStream in = new ObjectInputStream(fi);
keyWordList = (ArrayList<String>) in.readObject();
in.close();
}
}
catch (java.io.FileNotFoundException e) {
// that's OK, we probably haven't created it yet
}
catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), Toast.LENGTH_LONG)
.show();
}
if(keyWordList == null){
keyWordList = new ArrayList<String>();
return keyWordList;
}
return keyWordList;
}
public void onListItemClick(ListView parent, View v,
int position, long id) {
startFullNewsEvent(neList.get(position));
}
/**
* #param newsEvent
*/
public void startFullNewsEvent(NewsEvent ne) {
Intent intent = new Intent(this, FullNewsEvent.class);
intent.putExtra("ne", ne);
this.startActivity(intent);
finish();
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
String page = msg.getData().getString("page");
try {
JSONArray parseArray = new JSONArray(page);
for (int i = 0; i < parseArray.length(); i++) {
JSONObject jo = parseArray.getJSONObject(i);
String title = jo.getString("title");
String body =jo.getString("body");
String pd = jo.getString("postDate");
String id = jo.getString("id");
NewsEvent ne = new NewsEvent(title, pd , body, id);
boolean unique = true;
for(NewsEvent ne0 : neList){
if(ne.getId().equals(ne0.getId())){
unique = false;
}else{
unique = true;
}
}
if(unique == true){
neList.add(ne);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ne.setListAdapter(new IconicAdapter());
}
};
public class IconicAdapter extends ArrayAdapter<NewsEvent> {
IconicAdapter() {
super(NewsEvents.this, R.layout.rownews, neList);
}
public View getView(int position, View convertView,ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.rownews, parent, false);
TextView label=(TextView)row.findViewById(R.id.label);
ImageView image= (ImageView)row.findViewById(R.id.icon);
String body = neList.get(position).getBody();
body.replaceAll("\\<.*?>", "");
String title = neList.get(position).getTitle();
for(String s : keyWordList){
if(body.contains(s) || body.contains(s.toLowerCase()) ||
title.contains(s) || title.contains(s.toLowerCase())){
neList.get(position).setInterested(true);
}
}
if(neList.get(position).isInterested() == true){
image.setImageResource(R.drawable.star);
}
label.setText(neList.get(position).getTitle());
return(row);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
populateMenu(menu);
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return(applyMenuChoice(item) || super.onOptionsItemSelected(item));
}
//Creates our activity to menus
private void populateMenu(Menu menu) {
menu.add(Menu.NONE, ONE_ID, Menu.NONE, "Home");
}
private boolean applyMenuChoice(MenuItem item) {
switch (item.getItemId()) {
case ONE_ID: startHome(); return(true);
}
return(false);
}
public void startHome() {
Intent intent = new Intent(this, ECS.class);
this.startActivity(intent);
finish();
}
}
Race conditions, I'm making an HTTP Request and then handing it off to a handler, immediately following that I iterator through the array list, which at full speed is empty because the HTTP hasn't completed. In debugging it all slows down so the HTTP is complete and all works well.
Threads and Network Connections, a deadly combination.

Categories

Resources