【问题标题】:Android notification every 15 minutes crashes if app is closed如果应用程序关闭,Android 通知每 15 分钟崩溃一次
【发布时间】:2017-02-10 02:41:52
【问题描述】:

所以我是 Android Studio 的新手,我正在尝试制作一个简单的应用程序,它执行以下操作:

该应用在 /res/values 文件夹中设置了一个名为“frases”的字符串数组。 Main Activity 包含一个按钮,当它被按下时,它会增加一个变量,该变量表示要使用的数组的索引(我称之为“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());

    }
}

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

到目前为止,我尝试使用SharedPreferences.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;

【问题讨论】:

  • “应用程序已关闭”在 Android 中并没有任何意义。查找并了解“Activity Lifecycle”
  • 如果你想在一个Activity被挂起或者你的应用不是活跃的时候执行功能,你需要使用一个服务或者方法在特定的时间调用你的代码(比如通过使用 AlarmManager
  • 发布你在 logcat 上看到的崩溃

标签: java android notifications alarmmanager


【解决方案1】:

当您收到通知时,您的活动不是 alive,因此如果您尝试访问不是 aliveActivity 的字段,则会出现异常

解决方案

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 将被 android 操作系统调用时才被初始化,因此由于情况并非如此,因此您的 static 字段将保持不变初始化均值为 null 和 0。

【讨论】:

  • 非常感谢!有效。我之前尝试过使用上下文,但似乎我把所有的语法都弄错了,因为它只是错误。现在我的通知可以正常工作了,谢谢!
  • 很高兴能帮上忙,编码愉快
猜你喜欢
  • 2011-04-25
  • 2021-04-05
  • 2017-06-13
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
相关资源
最近更新 更多