Уведомление Android не срабатывает, когда приложение убито

Эта функция принимает строку char * и разбивает ее на разделитель. В строке может быть несколько разделителей. Обратите внимание, что функция изменяет строку orignal. Сначала вы должны сделать копию исходной строки, если вам нужно, чтобы оригинал оставался неизменным. Эта функция не использует вызовы функций cstring, поэтому она может быть немного быстрее других. Если вам не важно распределение памяти, вы можете выделить sub_strings в верхней части функции с размером strlen (src_str) / 2 и (например, упомянутая версия c ++) пропустить нижнюю половину функции. Если вы это сделаете, функция сведена к O (N), но способ оптимизации памяти, показанный ниже, - O (2N).

Функция:

char** str_split(char *src_str, const char deliminator, size_t &num_sub_str){
  //replace deliminator's with zeros and count how many
  //sub strings with length >= 1 exist
  num_sub_str = 0;
  char *src_str_tmp = src_str;
  bool found_delim = true;
  while(*src_str_tmp){
    if(*src_str_tmp == deliminator){
      *src_str_tmp = 0;
      found_delim = true;
    }
    else if(found_delim){ //found first character of a new string
      num_sub_str++;
      found_delim = false;
      //sub_str_vec.push_back(src_str_tmp); //for c++
    }
    src_str_tmp++;
  }
  printf("Start - found %d sub strings\n", num_sub_str);
  if(num_sub_str <= 0){
    printf("str_split() - no substrings were found\n");
    return(0);
  }

  //if you want to use a c++ vector and push onto it, the rest of this function
  //can be omitted (obviously modifying input parameters to take a vector, etc)

  char **sub_strings = (char **)malloc( (sizeof(char*) * num_sub_str) + 1);
  const char *src_str_terminator = src_str_tmp;
  src_str_tmp = src_str;
  bool found_null = true;
  size_t idx = 0;
  while(src_str_tmp < src_str_terminator){
    if(!*src_str_tmp) //found a NULL
      found_null = true;
    else if(found_null){
      sub_strings[idx++] = src_str_tmp;
      //printf("sub_string_%d: [%s]\n", idx-1, sub_strings[idx-1]);
      found_null = false;
    }
    src_str_tmp++;
  }
  sub_strings[num_sub_str] = NULL;

  return(sub_strings);
}

Как используйте его:

  char months[] = "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC";
  char *str = strdup(months);
  size_t num_sub_str;
  char **sub_strings = str_split(str, ',', num_sub_str);
  char *endptr;
  if(sub_strings){
    for(int i = 0; sub_strings[i]; i++)
      printf("[%s]\n", sub_strings[i]);
  }
  free(sub_strings);
  free(str);
0
задан Alessandra Maria 16 January 2019 в 21:16
поделиться

1 ответ

Пример BroadCastREceiver

public class SchedulerMailBroadcastReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            Log.i("scheduler: " + new DateWrapper().getLocaleString());
            PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = null;
            if (pm != null) {
                Log.d("aquire wakelog");
                wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ics:mailScheduler");
                wl.acquire(10000);
            }
            startInNewThread(context.getApplicationContext(),wl);
        }catch(Exception e){
            Log.e(e);
        }
    }
    public void startInNewThread(final Context context, PowerManager.WakeLock wl){
        new ThreadWrapper(() -> {
            try {
               //Do Stuff
            }catch(Exception e){
                Log.e(e);
            }finally {
                Log.d("releasing wakelog");
                try {
                    wl.release();
                    Log.i("released wakelog");
                }catch(Exception e){
                    Log.e("wakelog release","exception on releasing wawkelog");
                }
            }
        }).start();
    }

    public static boolean registerScheduler(Context context){

        final int requestCode=1234;

        Intent intent = new Intent(context, SchedulerMailBroadcastReceiver.class);
        intent.setAction("startScheduler");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        if (alarmManager != null) {
           // alarmManager.cancel(previousPendingIntent);
            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 60*15, pendingIntent);
            Log.i("registered repeating");
        }
        return  true;
    }


}

вы, вероятно, не хотите setRepeating через

Пример JobService

[ 1112]
public class SchedulerMailJobManager extends JobService{

    @Override
    public boolean onStartJob(JobParameters params) {
        try {
            Log.i("SchedulerMailJobManager","scheduler run at "+ new DateWrapper().getLocaleString());
            startInNewThread(getApplicationContext(),params);
            return true;
        }catch(Exception e){
            Log.e("SchedulerMailJobManager","errpr in starting new thread",e);
            return false;
        }
    }

    @Override
    public void onDestroy(){
        Intent intent = new Intent(this,ServiceRestarter.class);
        intent.setAction("restartService");
        intent.putExtra("service","mailScheduler");
        sendBroadcast(intent);
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.w("stoppedJob","stopped");
        return true;
    }

    public void startInNewThread(final Context context,final JobParameters params){
        new ThreadWrapper(() -> {
            try {
                //Do Stuff
            }catch(Exception e){
                Log.e("JobScheduler2ndThread","Exception",e);
            }finally {
                if(params!=null) {
                    this.jobFinished(params,false);
                }else{
                    Log.e("JobScheduler2ndThread","no params for jobFinished");
                }
            }
        }).start();
    }


    static JobInfo createScheduledJob(Context context){
        ComponentName serviceComponent = new ComponentName(context,SchedulerMailJobManager.class );
        JobInfo.Builder builder=new JobInfo.Builder(1234,serviceComponent);
        int waitMin=30;
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        builder.setPersisted(true);
        builder.setPeriodic(1000*60*waitMin,1000);
        return builder.build();
    }
    public static boolean registerScheduler(Context context){
        JobScheduler scheduler=context.getSystemService(JobScheduler.class);
        if(scheduler==null){
            Log.e("registerScheduler","scheduler is null");
            return false;
        }
        if(scheduler.getPendingJob(1234)!=null) {
            scheduler.cancel(1234);
            Log.i("registerScheduler","cancelled previous");
        }
        int resultCode=scheduler.schedule(createScheduledJob(context));
        if(resultCode==JobScheduler.RESULT_SUCCESS){
            Log.i("JobManagerScheduler","registered new scheduler");
            return true;
        }else{
            Log.e("registerScheduler","failed registering");
            return false;
        }

    }

}

, поскольку у вас есть только Уведомление, вам, вероятно, не нужно ничего начинать в новом потоке, что означает, что в этом решении вы должны вернуть false в OnStartJob

0
ответ дан jonny h. 16 January 2019 в 21:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: