Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

16.2. 静态注册

Android Studio 选择 File - New - Other - Broadcast Receiver

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>

        </receiver>
    </application>

</manifest>		
		
		

MyReceiver 集成 BroadcastReceiver 在 onReceive 中写入你的业务逻辑。

		
package cn.netkiller.broadcast;

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

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "程序已启动,接收到系统启动广播", Toast.LENGTH_SHORT).show();
    }
}
		
		
		

现在重启 Android 模拟器,启动后虽然 App 并没有进入,但是屏幕底部会看到 "程序已启动,接收到系统启动广播"

16.2.1. 电源管理

静态注册

		
        <receiver
            android:name=".receiver.StaticBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_BATTERY_CHANGED" />
                <action android:name="android.intent.action.ACTION_BATTERY_LOW" />
                <action android:name="android.intent.action.ACTION_BATTERY_OKAY" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>		
		
			

动态注册

		
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
            filter.addAction(Intent.ACTION_BATTERY_LOW);
            filter.addAction(Intent.ACTION_BATTERY_OKAY);
            filter.addAction(Intent.ACTION_POWER_CONNECTED);
            filter.addAction(Intent.ACTION_POWER_DISCONNECTED);		
		
			

16.2.2. 接收不到消息

Android 8 以上,静态广播必须指定包名 intent.setPackage(context.getPackageName());

			
    public static void broadcastTest(String message) {
        Log.d(TAG, "发送广播: " + message);
        Context context = ContextHolder.getContext();
        Intent intent = new Intent();
        intent.setAction("test.broadcast");
        intent.setPackage(context.getPackageName());
        intent.putExtra("message", message);
        context.sendBroadcast(intent);
    }
			
			

16.2.3. StaticBroadcastReceiver 完整的例子

			
        <receiver
            android:name="com.netkiller.conference.receiver.StaticBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_BATTERY_CHANGED" />
                <action android:name="android.intent.action.ACTION_BATTERY_LOW" />
                <action android:name="android.intent.action.ACTION_BATTERY_OKAY" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
                <action android:name="android.intent.action.ACTION_CLOSE_SYSTEM_DIALOGS" />
                <action android:name="android.intent.action" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
			
			
			
package com.netkiller.conference.receiver;

import android.app.DownloadManager;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.netkiller.conference.MainActivity;
import com.netkiller.conference.ai.aigc.AigcSpeech;
import com.netkiller.conference.ai.aigc.Cache;
//import cn.aigcsst.aigc.education.skill.PictureSkillComponent;

public class StaticBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = StaticBroadcastReceiver.class.getSimpleName();
    private final Cache cache = new Cache();
    private final AigcSpeech aigcSpeech = AigcSpeech.getInstance();

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

        String action = intent.getAction();
        Log.d(TAG, "Static broadcast Action: " + intent.getAction());

        try {
            switch (action) {
                case Intent.ACTION_BOOT_COMPLETED:
                    Log.d(TAG, "自启动了 !!!!!");
                    intent = new Intent(context, MainActivity.class);  // 要启动的Activity
                    //1.如果自启动APP,参数为需要自动启动的应用包名
                    //Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);
                    //这句话必须加上才能开机自动运行app的界面
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    //2.如果自启动Activity
                    context.startActivity(intent);
                    //3.如果自启动服务
                    //context.startService(newIntent);
                case Intent.ACTION_BATTERY_CHANGED://电量发生改变
//                    aigcSpeech.say("电量发生改变");
                    Log.e(TAG, "BatteryBroadcastReceiver --> ACTION_BATTERY_CHANGED");
                    break;
                case Intent.ACTION_BATTERY_LOW://电量低
//                    aigcSpeech.say("电量低");
                    Log.e(TAG, "BatteryBroadcastReceiver --> ACTION_BATTERY_LOW");
                    break;
                case Intent.ACTION_BATTERY_OKAY://电量充满
//                    aigcSpeech.say("电量充满");
                    Log.e(TAG, "BatteryBroadcastReceiver --> ACTION_BATTERY_OKAY");
                    break;
                case Intent.ACTION_POWER_CONNECTED://接通电源
//                    aigcSpeech.say("接通电源");
                    Log.e(TAG, "BatteryBroadcastReceiver --> ACTION_POWER_CONNECTED");
                    break;
                case Intent.ACTION_POWER_DISCONNECTED://拔出电源
//                    aigcSpeech.say("拔出电源");
                    Log.e(TAG, "BatteryBroadcastReceiver --> ACTION_POWER_DISCONNECTED");
                    break;
                case DownloadManager.ACTION_DOWNLOAD_COMPLETE:
//                    aigcSpeech.say("文件下载完成");
                    long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                    cache.setDownloadCache(id);
//                    Log.d(TAG, "文件下载:" + id);
                    break;
                case Intent.ACTION_CLOSE_SYSTEM_DIALOGS:
                    // 监听home键
//                    String reason = intent.getStringExtra(SYSTEM_REASON);
                    Log.d(TAG, "Home");
                    // 表示按了home键,程序到了后台
                    break;
                case BluetoothDevice.ACTION_ACL_CONNECTED:
                    Log.d(TAG, "Bluetooth connected");
                    break;
                case BluetoothDevice.ACTION_ACL_DISCONNECTED:
                    Log.d(TAG, "Bluetooth disconnected");
                    break;
                case "main.screen":
                    context.startActivity(new Intent(context, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                    break;
            }
        } catch (Exception e) {
            Log.d(TAG, e.toString());
        }

    }
}