Android:游标问题和崩溃的应用程序?

时间:2018-07-09 12:18:37

标签: android bootcompleted

我试图在设备重新启动后在SQLite数据库中重置一堆日期通知。当我测试时,该应用程序可以编译,但通知不会触发,并且该应用程序始终崩溃。

代码流:

1)RebootReceiver尝试捕获BOOT_COMPLETED事件

2)启动RebootService以使用以下命令加载所有SQLite通知    光标,PendingIntents和AlarmManager,它们将启动AlarmReceiver。游标使用SQLite方法“ resetNotifications”从数据库的“通知”列中收集所有日期(这些都是长整型)。

3)AlarmReceiver是启动AlarmService的BroadcastReceiver

4)AlarmService创建并显示通知

我在这里想念什么?

AndroidManifest.xml

...
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<service android:name=".AlarmService"
        android:exported="false">
</service>
<receiver android:name=".AlarmReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.wimso.v095.intent.action.ALARM" />
        </intent-filter>
</receiver>
<receiver android:name=".RebootReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
</receiver>
<service android:name=".RebootService"
        android:exported="false" >
    </service>

RebootReceiver.java

...
@Override
public void onReceive(Context context, Intent intent) {

    String action = intent.getAction();
    if (action == null) {
        return;
    }
    else if (action.equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
        intent.putExtra("TAG","bootCompleted");
    }        
    RebootService.enqueueWork(context, intent);
}

RebootService.java

public class RebootService extends JobIntentService {


// Unique job ID for this service
static final int JOB_ID = 10000;

public static void enqueueWork(Context context, Intent work) {
    enqueueWork(context, RebootService.class, JOB_ID, work);
}
@Override
protected void onHandleWork(@NonNull Intent intent) {

    SQLiteDB sqLiteDB = SQLiteDB.getInstance(this);
    int randInt = 0;
    Calendar cal2 = Calendar.getInstance();

    Bundle extras = intent.getExtras(); 
    if (extras != null) {

        String classname = extras.getString("TAG");

        if (classname != null && classname.equals("bootCompleted")) {

            Intent brIntent1;
            AlarmManager alarmManager;
            PendingIntent pendingIntent1;

            Cursor cursor = sqLiteDB.resetNotifications();
            try {
                if (cursor != null) {
                    cursor.moveToFirst(); 

                    int notifColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_NOTIFTIME);
                    int randColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_RANDINT);

                    while (!cursor.isAfterLast()) { 

                        do {

                            long notifTime = cursor.getLong(notifColumnIndex);
                            randInt = cursor.getInt(randColumnIndex);

                            cal2.setTime(new Date(notifTime));

                        } while (cursor.moveToNext());
                    }
                }
            } finally {
                if (cursor != null && !cursor.isClosed()) {
                    cursor.close();
                }
            }

            // Set up a PendingIntent that will perform broadcast to the BroadcastReceiver.
            brIntent1 = new Intent(this, AlarmReceiver.class);
            brIntent1.setAction("reBoot");   
            pendingIntent1 = PendingIntent.getBroadcast(this,randInt,brIntent1,
                PendingIntent.FLAG_ONE_SHOT);
            alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            int SDK_INT2 = Build.VERSION.SDK_INT;
            if (SDK_INT2 >= Build.VERSION_CODES.M) {

                if (alarmManager != null) {
                    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(),
                            pendingIntent1);
                }
            } else if (SDK_INT2 >= Build.VERSION_CODES.KITKAT) {                    
                if (alarmManager != null) {
                    alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), pendingIntent1);
                }
            } else {                    
                if (alarmManager!= null) {
                    alarmManager.set(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), pendingIntent1);
                }
            }

SQLiteDB.java

...
// Helps gather all Notifications so that after a device re-boot the Notifications can be reset.
public Cursor resetNotifications() {

    SQLiteDatabase db = getReadableDatabase();

    if (db == null) {
        return null;
    }
    else {
        String[] columns = new String[]{COLUMN_NOTIFTIME};
        return db.query(
                TABLE_NAME, 
                columns, 
                null,      
                null,   
                null,   
                null,   
                null    
        );
    }
}  

AlarmReceiver.java

...
public class AlarmReceiver extends BroadcastReceiver {

public AlarmReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (action == null) {
        return;
    }
    else if (action.equals("reBoot")) {

        intent.putExtra("TAG","reBootReceiver");
    }

    AlarmService.enqueueWork(context, intent);
}    

AlarmService.java

public class AlarmService extends JobIntentService {

    // Unique job ID for this service
    static final int JOB_ID = 9999;
    ...        
    public static void enqueueWork(Context context, Intent work) {
        enqueueWork(context, AlarmService.class, JOB_ID, work);
    }
    @Override
    protected void onHandleWork(@NonNull Intent intent) {   
    NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                "My Notifications", NotificationManager.IMPORTANCE_DEFAULT);

        if (notificationManager != null) {
            notificationManager.createNotificationChannel(notificationChannel);
        }
    }

    Bundle extras = intent.getExtras(); 
    if (extras != null) {
        String classname = extras.getString("TAG");
         else if (classname != null && classname.equals("reBootReceiver")) {

            // Send the Notification
            // The ID lets you update the notification later.
            int notify24HourID = 4;

            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                            .setDefaults(Notification.DEFAULT_ALL)
                            .setSmallIcon(R.drawable.ic_announcement_white_24dp)
                            .setContentText("")                                
                            .setPriority(NotificationCompat.PRIORITY_HIGH);
             if (notificationManager != null) {
                notificationManager.notify(notify24HourID, mBuilder.build());
            }

1 个答案:

答案 0 :(得分:0)

更改光标迭代循环

if (cursor.moveToFirst()) { 
    int notifColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_NOTIFTIME);
    int randColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.COLUMN_RANDINT);
    do {  
        long notifTime = cursor.getLong(notifColumnIndex);
        randInt = cursor.getInt(randColumnIndex);
        cal2.setTime(new Date(notifTime));
    } while (cursor.moveToNext());
}