Android:报警管理器;从 Broadcastreceiver 访问 MainActivity 中的 SQLiteOpenhelper 时出现 Nullpointer class
Android: Alarm Manager; Nullpointer when accessing SQLiteOpenhelper in MainActivity from Broadcastreceiver class
我正忙于开发一个报价应用程序,该应用程序每天早上都会在 9:00am 向用户显示新的励志名言。
我的 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:00am 更改报价并且闹钟正在触发,但问题在于能够 运行 来自广播接收器 [=35] 我的 MainActivity 中的意图=].这是 class... 空白,因为我不知道如何让它工作。
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();
}
}
非常感谢在此领域的任何帮助。我应该使用一个全新的意图还是一个对象 class,你能举个例子吗?
****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(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 class 内 DailyQuoteDatabaseAccess 方法内的这一行:
SQLiteOpenHelper sqLiteOpenHelper = new SQLiteAssetHelper(this, DATABASE_NAME, null, DATABASE_VERSION);
对于每日行情,我做了一些事情....
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);
}
现在在数据库 class 中创建函数以在数据库 class
中获取随机报价
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());
}
}
在这里当你重启你的phone你也需要重启你的闹钟,所以我已经做了
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>
我正忙于开发一个报价应用程序,该应用程序每天早上都会在 9:00am 向用户显示新的励志名言。
我的 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:00am 更改报价并且闹钟正在触发,但问题在于能够 运行 来自广播接收器 [=35] 我的 MainActivity 中的意图=].这是 class... 空白,因为我不知道如何让它工作。
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();
}
}
非常感谢在此领域的任何帮助。我应该使用一个全新的意图还是一个对象 class,你能举个例子吗?
****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(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 class 内 DailyQuoteDatabaseAccess 方法内的这一行:
SQLiteOpenHelper sqLiteOpenHelper = new SQLiteAssetHelper(this, DATABASE_NAME, null, DATABASE_VERSION);
对于每日行情,我做了一些事情....
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);
}
现在在数据库 class 中创建函数以在数据库 class
中获取随机报价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());
}
}
在这里当你重启你的phone你也需要重启你的闹钟,所以我已经做了
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>