如果应用关闭,每15分钟一次Android通知会崩溃

时间:2017-02-09 13:56:58

标签: java android notifications alarmmanager

所以我是Android Studio中的一个完整的新手,我正在尝试创建一个简单的应用程序来执行以下操作:

app在/ res / values文件夹中设置了一个字符串数组,名为" frases"。 Main活动包含一个按钮,当按下它时,它会增加一个变量,该变量表示要使用的数组的索引(我称之为" iterador")并设置textView到了frases [iterador]的价值。

然后在MainActivity的onCreate方法中,我有一个使用setRepeating的警告,它调用一个类来每15分钟接收一次通知。这样做的目的是在MainActivity中都有一个textview和一个可以显示frases [iterador]值的通知。

这里的问题是每当我的应用程序关闭时(没有从android设置菜单停止,只是关闭)我得到一个错误,说字符串数组为空。更糟糕的是,在第一次通知后,如果我不打开手机中的应用程序(即使它没有关闭),有时第二个通知即使在15分钟后也不会出现。

我试图通过将两个变量设置为静态来解决此问题,以便我可以从通知类中访问它们,但仍然无法正常工作。

有没有办法解决这个问题,即使应用程序关闭,也会显示通知?

我的MainActivity vars和onCreate方法:

public class MainActivity extends Activity implements View.OnClickListener {

//MY CODE
public static boolean primera; //APP OPENED FOR THE FIRST TIME

private Button b_corazon, b_carta;
private TextView t_frase;
public static final String PREFS_NAME = "MyPrefsFile";


//-------------------------STRING SHOW VARIABLES----------------------
public static String[] frases; //STRING ARRAY
public static int iterador; // INDEX FOR THE ARRAY
AlarmManager alarmManager; //ALARM MANAGER





@Override
protected void onCreate(Bundle savedInstanceState) {
    Resources res=getResources(); //GET THE RESOURCES
    frases=res.getStringArray(R.array.cartas); //ASIGN THE STRING ARRAY TO THE VARIABLE
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    //MI CODIGO

    Intent intent = new Intent(getApplicationContext(), RecibeNotif.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),0,intent,0);
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

    Calendar firing = Calendar.getInstance();  //SCHEDULED TIME
    Calendar current = Calendar.getInstance(); //CURRENT TIME

    firing.set(Calendar.HOUR_OF_DAY,14);
    firing.set(Calendar.MINUTE,20);
    firing.set(Calendar.SECOND,0);

    long intendedTime=firing.getTimeInMillis(); //SCHEDULED TIME
    long currentTime=current.getTimeInMillis(); //CURRENT TIME

    if(intendedTime>=currentTime){ //IF IT ISN'T THE TIME YET
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, intendedTime,AlarmManager.INTERVAL_FIFTEEN_MINUTES,pendingIntent);
    }
    else{ //IF THE TIME HAS ALREADY PASSED
        firing.add(Calendar.MINUTE,15); //ADD 15 MINUTES FOR THE NEXT ALARM
        intendedTime=firing.getTimeInMillis();
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, intendedTime,AlarmManager.INTERVAL_FIFTEEN_MINUTES,pendingIntent);
    }






    //SAVE THE VALUE OF ITERADOR IN THE APPLICATION DATA
    SharedPreferences settings = getSharedPreferences(PREFS_NAME,0); //GUARDAR DATO DE ITERADOR
    primera=getSharedPreferences("PREFERENCE",MODE_PRIVATE).getBoolean("primera", true);
    iterador=settings.getInt("iterador",iterador);
    init();
}

我的BroadcastReceiver通知类:

public class RecibeNotif extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        String[] frasesaux;
        int iteraux;

        iteraux=MainActivity.iterador;
        frasesaux=MainActivity.frases;
        if(iteraux==frasesaux.length){
            iteraux=0;
        }

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        Intent redir = new Intent(context,direct.class);
        redir.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 100, redir, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
                .setContentIntent(pendingIntent)
                .setSmallIcon(R.drawable.message)  //ICONO DE LA NOTIFICACION
                .setContentTitle(".////.")
                .setContentText(frasesaux[iteraux])
                .setAutoCancel(true);

        notificationManager.notify(100,builder.build());

    }
}

< ----------- EDIT ------------->

好的,现在已经解决,通知效果很好。唯一让我感到疯狂的是如何更新通知类末尾的iterador值,使其与iteraux匹配。

到目前为止,我已尝试使用iterador修改SharedPreferences.editor的值,但它似乎无法正常工作。

有什么想法吗?

public void onReceive(Context context, Intent intent) {
    String[] finale;
    int iteraux;
    SharedPreferences settings = context.getSharedPreferences(PREFS_NAME,0); //GUARDAR DATO DE ITERADOR
    iteraux = settings.getInt("iterador",iterador);
    Resources res= context.getResources(); //GET THE RESOURCES
    finale=res.getStringArray(R.array.cartas); //ASIGN THE STRING ARRAY TO THE VARIABLE
    //iteraux=MainActivity.iterador;

    if(iteraux==finale.length){
        iteraux=0;
    }
    else{
        iteraux++;
    }



    //<-----------UPDATE ITERADOR VAR IN MAINACTIVITY
    SharedPreferences.Editor editor2 = settings.edit();
    editor2.putInt("iterador",iteraux);
    editor2.commit();

   // frasesaux=MainActivity.frases;

1 个答案:

答案 0 :(得分:2)

当您收到通知时,您的活动不是alive,因此如果您尝试访问Activity不是alive的字段,则会出现例外情况

解决方案

1。)使用context获取getStringArray(R.array.cartas)

2.。)使用相同的contextSharedPreferences

获取数据
public class RecibeNotif extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        String[] frasesaux;
        int iteraux;
        SharedPreferences settings = context.getSharedPreferences("MyPrefsFile",0);
        iteraux = settings.getInt("iterador",0);
        //                                   ^^ your default value

        //iteraux=MainActivity.iterador;
        frasesaux=context.getResources().getStringArray(R.array.cartas);
        // ^^ fetch the array 
        if(iteraux==frasesaux.length){
            iteraux=0;
        }
        //...
   }
}

注意:static没有任何区别,因为只有在安卓操作系统调用onCreate时才会初始化您的数组,因此情况并非如此,因此您的{static 1}}字段将保持未初始化,表示null和0。