Android: диспетчер тревог;Нулевой указатель при доступе к SQLiteOpenhelper в MainActivity из класса Broadcastreceiver - PullRequest
0 голосов
/ 22 ноября 2018

Я занят работой над приложением для цитат, которое будет показывать пользователю новую мотивационную цитату каждое утро в 9:00.

У меня есть этот метод в моем 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, и будильник срабатывает, но проблема заключается в том, что я могу запустить это намерение в моем MainActivity из класса Broadcast Receiver.Вот этот класс ... пустой, потому что я не могу понять, как заставить его работать.

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();

    }
}

Любая помощь в этой области была бы очень признательна.Должен ли я использовать намерение или объект совершенно нового класса, и не могли бы вы привести пример?

**** 22.11.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);

    }

}

Это мой журналcat для нулевого указателя ...

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, поэтому я знаю, что он устанавливает соединение, но ошибка поступает из этой строки внутри метода DailyQuoteDatabaseAccess внутри MainActivity.класс:

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

1 Ответ

0 голосов
/ 22 ноября 2018

Для ежедневных кавычек я должен что-то сделать ....

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;
}

и получить этоreciver

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...