簡體   English   中英

在 Android 應用程序中使用 BROADCAST RECEIVER 自動重啟時在上下文中獲取 NULL

[英]Getting NULL in context while auto restart with BROADCAST RECEIVER in Android app

我正在開發 android 應用程序,該應用程序需要在重啟設備時自動重啟,因為我正在使用具有操作 BOOT_COMPLETED 的廣播接收器。

當我重新啟動設備時,廣播接收器正在接收消息,但在重新啟動方法中我想啟動主要活動,因為我使用了 Intent,但在接收器的 onReceive 方法中,我得到 null 上下文,所以我無法重新啟動主要活動。

下面是代碼。

MainActivity.java

private Object activity;
private TextView tvImeiNum;
private BroadcastReceiver rebootreceiver;
private IntentFilter filter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    tvImeiNum = (TextView)findViewById(R.id.tv_imeinum);

     filter = new IntentFilter();
    filter.addAction(Intent.ACTION_BOOT_COMPLETED);
    filter.addAction(Intent.ACTION_REBOOT);



    rebootreceiver = new BootUpReceiver(MainActivity.this);

    LocalBroadcastManager.getInstance(this).registerReceiver(rebootreceiver, 
filter);//registering receiver


    generateUniqueCode();
}

BootupReceiver.java

    public class BootUpReceiver extends BroadcastReceiver {

        MainActivity ma;
        public BootUpReceiver(MainActivity maContext){
            ma=maContext;
        }

        public BootUpReceiver(){
        }

        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onReceive(Context context, Intent intent) {

            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                Log.d("TAG REBOOT", "onReceive: " + intent);
                Log.d("Reboot complete", "connection");

                GlobalTool.restartApplication(context);

            }
        }
    }

GlobalTool.java

    public class GlobalTool {

        @RequiresApi(api = Build.VERSION_CODES.M)
        public static void restartApplication(Context context) {
    

            Log.d("IN App restart:", "");


            Log.d("TAG", "restartApplication: ");
            if(context != null)
            {
                Log.d("TAG NULL", "restartApplication: ");
                Intent mainIntent = new Intent(context, MainActivity.class);

                AlarmManager alarmMgr = (AlarmManager) 
context.getSystemService(ALARM_SERVICE);
                TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
                stackBuilder.addNextIntent(mainIntent);
                PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, 
PendingIntent.FLAG_UPDATE_CURRENT);

                long alarmTime = System.currentTimeMillis() + (1 * 1000);
                alarmMgr.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
                Log.d("TAG", "restartApplication: 111");
                Log.d("TAG", "restartApplication: 111");

            }
            else {
                Intent mainIntent = new Intent(context, MainActivity.class);

                AlarmManager alarmMgr = (AlarmManager) 
context.getSystemService(ALARM_SERVICE);
                TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
                stackBuilder.addNextIntent(mainIntent);
                PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, 
PendingIntent.FLAG_UPDATE_CURRENT);

            long alarmTime = System.currentTimeMillis() + (1 * 1000);
            alarmMgr.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
            Log.d("TAG", "restartApplication: 111");
            Log.d("TAG", "restartApplication: 111");
        }
    }

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.kioskappdemo">

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

<application
        android:name="KioskApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.KioskAppDemo"
        tools:targetApi="31"
        tools:ignore="Instantiatable">
        <service
            android:name=".RebootService"
            android:enabled="true"
            android:exported="true"></service>

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:screenOrientation="landscape"
            android:theme="@style/Theme.AppCompat.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category 
android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver
            android:name=".Activity.BootUpReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter >
                <action 
android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.REBOOT" />
                <action 
android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="com.reboot.test" />
                <action 
android:name="android.intent.action.TIMEZONE_CHANGED" />
                <action 
android:name="android.intent.action.DATE_CHANGED" />


            </intent-filter>
        </receiver>
    </application>

</manifest>

一些代碼改進:

  1. 不要將上下文放入 Brodcast Receiver 構造函數。 使用 onReceive 方法中的上下文
    public class BootUpReceiver extends BroadcastReceiver {
        public BootUpReceiver(){
           //TODO log
        }
    ...
  1. 您不應使用 LocalBroadcastManager::registerReceiver 調用。 如果將廣播接收器添加到 AndroidManifest 中,那么它將由系統啟動。
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <receiver
        android:name=".activity.BootUpReceiver"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter >
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
  1. 不要將 CamelCase 用於 package 名稱(use.activity.BootUpReceiver insetad.Activity.BootUpReceiver)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM