Java 如果应用程序关闭,每15分钟一次的Android通知就会崩溃

Java 如果应用程序关闭,每15分钟一次的Android通知就会崩溃,java,android,notifications,alarmmanager,Java,Android,Notifications,Alarmmanager,所以我是Android Studio的新手,我正在尝试制作一个简单的应用程序,它可以实现以下功能: 该应用程序在/res/values文件夹中设置了一个名为“frases”的字符串数组。 主活动包含一个按钮,当按下该按钮时,它会增加一个变量,该变量表示要使用的数组的索引(我称之为“iterador”),并将textView设置为frases[iterador]的值 然后在MainActivity的onCreate方法上,我有一个带有setRepeating的alarnm,它每15分钟调用一个类来

所以我是Android Studio的新手,我正在尝试制作一个简单的应用程序,它可以实现以下功能:

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

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

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

我试图通过使这两个变量都是静态的来解决这个问题,这样我就可以从notification类访问它们,但仍然不起作用

有没有办法解决这个问题,甚至在应用程序关闭的情况下也能显示通知动作

我的
main活动
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();
}
My
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());

    }
}

好的,现在已经修复了,通知运行得很好。唯一让我抓狂的是如何更新通知类末尾的
iterador
值,使其与
iteraux
匹配

到目前为止,我已经尝试使用
SharedReferences.editor
编辑
iterador
的值,但它似乎不起作用

有什么想法吗

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;
public void onReceive(上下文、意图){
弦乐[]终曲;
int iteraux;
SharedReferences settings=context.getSharedReferences(PREFS_NAME,0);//GUARDAR DATO DE ITERADOR
iteraux=settings.getInt(“iterador”,iterador);
Resources res=context.getResources();//获取资源
finale=res.getStringArray(R.array.cartas);//将字符串数组指定给变量
//iteraux=MainActivity.iterador;
if(iteraux==最终长度){
iteraux=0;
}
否则{
iteraux++;
}

// 当您收到通知时,您的活动未处于活动状态,因此,如果您尝试访问未处于活动状态的
活动
的字段,您会遇到异常

解决方案

1.)使用
上下文
获取
getStringArray(R.array.cartas)

2.)使用相同的
上下文
共享引用



注意:
static
不会有任何区别,因为只有当android操作系统调用
onCreate
时才会初始化数组,因此,由于情况并非如此,因此您的
static
字段将保持未初始化状态,表示为null和0。

当您收到通知时,您的活动不处于活动状态因此,如果您试图访问非活动的
活动
字段,您会遇到异常

解决方案

1.)使用
上下文
获取
getStringArray(R.array.cartas)

2.)使用相同的
上下文
共享引用



注意:
static
不会有任何区别,因为只有当android操作系统调用
onCreate
时才会初始化数组,因此,由于情况并非如此,因此您的
static
字段将保持未初始化状态,表示为null和0。

“应用程序已关闭”在Android中并不真正意味着什么。查找并理解“活动生命周期”如果您想在活动暂停或应用程序不是活动应用程序时执行功能,您需要使用服务或方法在特定时间调用代码(例如通过使用AlarmManagerpost在logcat上看到的崩溃)“应用程序已关闭”在Android中并不真正意味着什么。如果您想在活动暂停或应用程序不是活动应用程序时执行功能,请查看并理解“活动生命周期”,您需要使用服务或方法在特定时间调用代码(例如,通过使用AlarmManager,在LogcatHanks上看到的崩溃之前,它非常有效。我以前尝试使用上下文,但似乎所有语法都错了,因为它只是错误。现在,我的通知工作正常,谢谢!我很高兴能帮上忙,很高兴编写了大量日志!它有效。我以前尝试使用上下文但是似乎我把所有的语法都搞错了,因为这只是个错误。现在我的通知工作正常了,谢谢!我很高兴我能帮上忙,编码愉快
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;
        }
        //...
   }
}