1. 程式人生 > >Android中的廣播(BroadcastReceiver)

Android中的廣播(BroadcastReceiver)

廣播的傳送是通過意圖(intent)實現的,那麼廣播的接收呢,使用過Broadcast Receiver來實現的。

廣播分為兩種,一種是標準廣播,另一種是有序廣播。

接收廣播,我們可以動態的註冊也可以靜態的註冊。

下面我們舉一個動態註冊的例子:

package com.example.sunshunli.broadcasttest;
        import android.content.BroadcastReceiver;
        import android.content.Context;
        import android.content.Intent;
        import android.content.IntentFilter;
        import android.net.ConnectivityManager;
        import android.net.NetworkInfo;
        import android.support.v7.app.AppCompatActivity;
        import android.os.Bundle;
        import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter intentFilter = new IntentFilter();
        //給intentfilter添加個action,因為當網路的緩急變化時就會發注這樣的廣播。
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        //註冊監聽
        registerReceiver(networkChangeReceiver,intentFilter);
    }
    protected void onDestory(){
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }
    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            //ConnectivityManager是一個系統服務類,專用於網路管理的。
            ConnectivityManager connectivityManager =(ConnectivityManager) getSystemService(context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if (networkInfo !=null && networkInfo.isAvailable()){
                Toast.makeText(context, "network is avaliable", Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(context, "network is not avaliable", Toast.LENGTH_SHORT).show();
            }
        }
    }
}
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

上面的例子是我們動態註冊監聽網路的變化。

我要要監聽它的變化,那麼我們是不是應該有一個監聽器呢,所以我們洗了一個監聽器的類繼承BroadcastReceiver,然後重寫父類onReceive方法。當有廣播到來時onReceive方法搜不會呼叫執行。

我們可以在模擬器的setting中找到datausage,然後每個模擬器還不一樣,你看著哪裡有按鈕可以控制開關就行。

我的是

接下里是靜態註冊開機啟動的例子:

package com.example.sunshunli.broadcasttest;

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

public class BootCompleteReceived extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
<receiver
            android:name=".BootCompleteReceived"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

 還是要加上許可權

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

這樣我們的靜態註冊就完成了。

對比一下動態註冊和今天註冊。

1.動態註冊沒有在mainifest檔案中進行接收器的註冊,而靜態的需要註冊。

2.動態註冊我們的action屬性是通過IntentFilter類來實現的,而靜態的是我們手動新增的。

上面我們做的都是系統的一些廣播,接下來我們來發送自定義的廣播。

這是一個標準廣播

package com.example.sunshunli.broadcasttest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               Intent intent = new Intent("com.example.sunshunli.broadcasttest.my_broadcast");
               sendBroadcast(intent);
            }
        });
    }
}
package com.example.sunshunli.broadcasttest;

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

public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
    }
}

自己需要在mainifest檔案中進行註冊我們的監聽器。

我們在建立一個專案,就是另一個應用程式。試試能不能接受這個廣播。

package com.example.sunshunli.broadcasttest2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class AnotherBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Toast.makeText(context, "receiver anotherbroadcastreceiver", Toast.LENGTH_SHORT).show();
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sunshunli.broadcasttest2">

    <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=".AnotherBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.sunshunli.broadcasttest.my_broadcast"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

答案是肯定的,當我們點選了send按鈕我們的連個專案都會有提示。

下面是我們的有序廣播:

第一個專案:

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

    <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=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.sunshunli.broadcasttest.my_broadcast"/>
                </intent-filter>
        </receiver>
    </application>

</manifest>
package com.example.sunshunli.broadcasttest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               Intent intent = new Intent("com.example.sunshunli.broadcasttest.my_broadcast");
               sendOrderedBroadcast(intent,null);
            }
        });
    }
}

 sendOrderedBroadcast(intent,null);傳送有序廣播,第二個引數是與許可權相關的字串。填null就可以。

package com.example.sunshunli.broadcasttest;

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

public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
        abortBroadcast();
    }
}

 abortBroadcast();是截斷廣播的。

第二個專案:

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

    <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=".AnotherBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.example.sunshunli.broadcasttest.my_broadcast"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>
<intent-filter android:priority="100">

是設定優先順序的。

package com.example.sunshunli.broadcasttest2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
package com.example.sunshunli.broadcasttest2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class AnotherBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        Toast.makeText(context, "receiver anotherbroadcastreceiver", Toast.LENGTH_SHORT).show();
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

這樣的,話但是接收到後截斷了,第二個就收不到了。