Android:警报管理器;从Broadcastreceiver类访问MainActivity中的SQLiteOpenhelper时的Nullpointer

时间:2018-11-22 04:07:28

标签: android sqlite broadcastreceiver alarmmanager android-cursoradapter

我正忙于开发一个报价应用程序,该应用程序每天早晨9:00 am向用户显示一个新的激励性报价。

我的MainActivity中有此方法,可以提取并在显示单引号的listView中显示引号。我知道还存在此类问题的其他示例,但我还没有看到需要使用数据库数据和游标或游标适配器的一个例子。

public void DailyQuoteDatabaseAccess(){

    SQLiteOpenHelper sqLiteOpenHelper = new SQLiteAssetHelper(this, DATABASE_NAME, null, DATABASE_VERSION);
    SQLiteDatabase SqlDb = sqLiteOpenHelper.getReadableDatabase();
    String rawQuery = "SELECT * FROM dailyQuoteTable ORDER BY RANDOM() LIMIT 1";
    Cursor cursor = SqlDb.rawQuery(rawQuery, null);
    DailyQuoteCursorAdapter DQCursorAdapter = new DailyQuoteCursorAdapter(this, cursor);
    this.mDailyQuoteListView.setAdapter(DQCursorAdapter);
}

我从OnCreate调用了此方法,它可以正常工作,但是每次重新启动应用程序时都会重新加载。我正在使用AlarmManager设置警报,以每天早上9:00 am更改报价,并且警报正在触发,但是问题出在能否从Broadcast Receiver类在MainActivity中运行该意图。这是一堂课...空白,因为我不知道如何使它工作。

package com.myapps.dailyquotes;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class TodaysQuoteAlarmReceiver  extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    MainActivity mainActivity = new MainActivity();
    mainActivity.DailyQuoteDatabaseAccess();

    }
}

在这个领域的任何帮助将不胜感激。我应该使用全新的类的意图还是对象,请提供示例吗?

**** 11/22/18 ****

我忘了添加我的自定义光标适配器...我认为这可能会有所作为,但我仍然不确定如何将其与Broadcast Receiver集成以传递所需的数据...

public class DailyQuoteCursorAdapter extends CursorAdapter{

    public DailyQuoteCursorAdapter(Context context, Cursor c) {
        super(context, c, 0);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.daily_quote_item, parent, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        TextView NameTextView = (TextView) view.findViewById(R.id.name);
        TextView NumberTextView = (TextView) view.findViewById(R.id.number);
        TextView DateTextView = (TextView) view.findViewById(R.id.date);
        TextView QuoteTextView = (TextView) view.findViewById(R.id.quote);

        String name = cursor.getString(cursor.getColumnIndexOrThrow("quote_main"));
        String number = cursor.getString(cursor.getColumnIndexOrThrow("number"));
        String date = cursor.getString(cursor.getColumnIndexOrThrow("date"));
        String quote = cursor.getString(cursor.getColumnIndexOrThrow("quote"));

        nameTextView.setText(name + " ");
        numberTextView.setText(String.valueOf(number) + ":");
        dateTextView.setText(String.valueOf(date));
        quoteTextView.setText(quote);

    }

}

这是我的空指针日志猫...

Process: com.myapps.dailyquotes, PID: 15024
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } in com.myapps.dailyquotes.TodaysQuoteAlarmReceiver@d63089d
    at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$-android_app_LoadedApk$ReceiverDispatcher$Args_52497(LoadedApk.java:1323)
    at android.app.-$Lambda$aS31cHIhRx41653CMnd4gZqshIQ.$m$7(Unknown Source:4)
    at android.app.-$Lambda$aS31cHIhRx41653CMnd4gZqshIQ.run(Unknown Source:39)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
    at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:152)
    at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.<init>(SQLiteAssetHelper.java:109)
    at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.<init>(SQLiteAssetHelper.java:129)
    at com.myapps.dailyquotes.MainActivity.DailyQuoteDatabaseAccess(MainActivity.java:403)
    at com.myapps.dailyquotes.TodaysQuoteAlarmReceiver.onReceive(TodaysQuoteAlarmReceiver.java:18)

接收器确实尝试从MainActivity运行该方法,所以我知道它正在建立连接,但错误是来自MainActivity类内部的DailyQuoteDatabaseAccess方法中的以下行:

 SQLiteOpenHelper sqLiteOpenHelper = new SQLiteAssetHelper(this, DATABASE_NAME, null, DATABASE_VERSION);

1 个答案:

答案 0 :(得分:1)

对于每日行情,我已经做了一些事情。...

public void setAlarm() {
// Quote in Morning at 08:32:00 AM
    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.HOUR_OF_DAY, 8);
    calendar.set(Calendar.MINUTE, 32);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    Calendar cur = Calendar.getInstance();

    if (cur.after(calendar)) {
        calendar.add(Calendar.DATE, 1);
    }

    Intent myIntent = new Intent(context, DailyReceiver.class);
    int ALARM1_ID = 10000;
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            context, ALARM1_ID, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}

现在在数据库类中创建函数以获取数据库类中的随机报价

public String getAlarmQuote(int id, String table) {
   String quote = "", author = "";
   SQLiteDatabase db = this.getReadableDatabase();
   Cursor cursor = db.query(table, new String[]{QUOTE_ID, QUOTE_QUOTE, QUOTE_AUTHOR}, QUOTE_ID + "=?", new String[]{String.valueOf(id)}, null, null, null, null);
   if (cursor != null && cursor.getCount() > 0) {
       if (cursor.moveToFirst()) {
           quote = cursor.getString(cursor.getColumnIndex(QUOTE_QUOTE));
           author = cursor.getString(cursor.getColumnIndex(QUOTE_AUTHOR));
       }
   }
   db.close();
   return quote;
}

并获得此收据

public class DailyReceiver extends BroadcastReceiver {

DatabaseHelper databaseHelper;

@Override
public void onReceive(Context context, Intent intent) {String quote ;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context
        .getSystemService(Context.NOTIFICATION_SERVICE);

Intent notificationIntent = new Intent(context, DailySpecialActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
        notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

// get your quote here
   int max = databaseHelper.getTotalQuotes();  // here you have to put total number of quotes in your database table
   Random r = new Random();
   int randomNumber = r.nextInt(max - 1 + 1) + 1;
   quote = databaseHelper.getAlarmQuote(randomNumber, YourTableName);


NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(
        context).setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("My Quotes")
        .setContentText(quote).setSound(alarmSound)
        .setAutoCancel(true).setWhen(when)
        .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
        .setStyle(new NotificationCompat.BigTextStyle().bigText(quote))
        .setContentIntent(pendingIntent)
        .setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});  // Declair VIBRATOR Permission in AndroidManifest.xml
notificationManager.notify(5, mNotifyBuilder.build());
   }
}

在这里,当您重新启动手机时,您还需要重新启动闹钟,所以我可以了

public class WakeUpAlarmReceiver extends BroadcastReceiver {

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

if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
    // Quote in Morning
    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.HOUR_OF_DAY, 8);
    calendar.set(Calendar.MINUTE, 30);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    Calendar cur = Calendar.getInstance();

    if (cur.after(calendar)) {
        calendar.add(Calendar.DATE, 1);
    }
    Intent myIntent = new Intent(context, DailyReceiver.class);
    int ALARM1_ID = 10000;
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, ALARM1_ID, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
  }
 }
}

最后是您的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nils.myquotesapp">
<!--you must need this three permissions-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />

<application
  android:name="com.nils.myquotesapp.QuotesApplication"
  android:allowBackup="true"
  android:icon="@mipmap/ic_launcher"
  android:label="@string/app_name"
  android:largeHeap="true"
  android:supportsRtl="true"
  android:theme="@style/AppTheme">
  <activity
    android:name="com.nils.myquotesapp.Activity.MainActivity"
    android:label="@string/app_name"
    android:screenOrientation="portrait"
    android:theme="@style/AppTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<receiver
    android:name="com.nils.myquotesapp.DailyReceiver"
    android:enabled="true" />

<receiver
    android:name="com.nils.myquotesapp.WakeUpAlarmReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

</application>
<meta-data
  android:name="com.google.android.gms.version"
  android:value="@integer/google_play_services_version" />
</manifest>