在通知中随机传递 Sqlite 数据

Passing Sqlite data randomly in notification

我在我的 Android 应用程序中使用预填充的 Sqlite 数据库,它有三个表(id、word、定义)。我想要做的是从数据库中随机向用户显示通知。我正在做类似下面代码的事情,但它不起作用。

DatabaseHelper.java

public Cursor getNotification(int id) {
    SQLiteDatabase db = this.getWritableDatabase();
    String Query = "Select * from " + TABLE_DICTIONARY + " where id = " + id  ;
    Cursor cursor = db.rawQuery(Query, null);
    if(cursor.getCount() <= 0){
        cursor.close();
    }
    cursor.close();
    return cursor;
}

这是我的 MainActivity.java

private void showNotification() {
   int position =  dictionaryAdapter.cursor.getPosition();
  int cursorCount = dictionaryAdapter.cursor.getCount();

    final int random = new Random().nextInt((cursorCount) - 1);

   Cursor i =  mDBHelper.getNotification(random);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this,CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(String.valueOf(i))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

    NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
    managerCompat.notify(1,mBuilder.build());

}

修复第 1 部分

简而言之,您可以利用以下内容:-

public Cursor getNotification() {
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.query(TABLE_DICTIONARY,null,null,null,null,null,"random()","1");
    return cursor;
}

以上等同于生成SQL :-

SELECT * FROM your_table ORDER BY random() LIMIT 1; 
  • 请注意,your_table 仅代表您的 table 名称,很可能需要更改以适应。

你不妨看看query

当然你可以在rawQuery中使用上面的SQL。但是,一般建议使用query等便捷方法,而不是rawQueryexec[=111] =] 方法时可以使用方便的方法。

上面的工作是使用 SQLite 的 random() 函数对行进行排序,然后 LIMITing 的数量结果行仅为 1。

其他问题

  1. 此外,重要的是,您不能按照 :-

    使用闭合游标
    • Closes the Cursor, releasing all of its resources and making it completely invalid. Unlike deactivate() a call to requery() will not make the Cursor valid again.

  2. 此外,要从 Cursor 访问存储的数据,您必须移动到一行,因为最初 Cursor 位于第一行之前(例如下面使用 i.moveToFirst())。

  3. 此外,由于返回了单个随机行,因此无需尝试随机检索其中一行。但是,您应该检查是否返回了一行。

修复第 2 部分

因此 Activity 中的代码可能是:-

private void showNotification() {


    Cursor i =  mDBHelper.getNotification();
    if (i.moveToFirst()) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this,CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(String.valueOf(i)) //???????????
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

        NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
        managerCompat.notify(1,mBuilder.build());
    } else {
        //code here to handle nothing being obtained and thus 
    }
    i.close(); // You should always close a Cursor when done with it.
}

另一期

使用 String.valueOf(i) 不会是数据库中的任何值,而是 Cursor 的 object 的 toString 方法产生的值。就像 android.database.sqlite.SQLiteCursor@a40a2ab

修复第 3 部分

你会想要类似的东西:-

    .setContentTitle(i.getString(i.getColumnIndex("word") + " is defined as " + i.getString(i.getColumnIndex("definition"))) // builds the title from columns of the selected row

这将标题设置为 the_word 定义为 the_definition_of_the_word 其中 the_word是存储在 word 列中的值,而 the_definition_of_the_word 是存储在 definition[=78 中的值=]列。

额外

  • 注意 Cursor getColumnIndex 方法有一个错误,因为它依赖于大小写。因此,建议对列名使用常量值,这样大小写总是正确的,而不是在使用列名时对它们进行硬编码。 (例如,就像您使用常量 TABLE_DICTIONARY)。