Gustavo Piris
Gustavo Piris

Reputation: 68

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);

        }
    }
}

}

Upvotes: 0

Views: 108

Answers (1)

Budius
Budius

Reputation: 39846

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);
    }
}

Upvotes: 1

Related Questions