LoginSignup
4
7

More than 3 years have passed since last update.

Android (Kotlin) でブロードキャスト送受信の仕方を理解する

Last updated at Posted at 2020-03-20

きっかけ

最近、Android 開発を仕事で行っていますが、複数のアプリ間連携の方法を今まで知りませんでした。
最近知ったのですが、IntentBroadcastReceiverを使用することで簡単にアプリ間連携が可能でした。

しかし、まったくの初心者であった自分にとっては???でした。。
そこで今回は 2 つのアプリを連携させるIntentの使い方について学ぶことができたので、共有します。

環境

  • Android Studio 3.6.1
  • Android 7.0 以降

概要

1 つの Android 端末に 2 つのアプリケーションをインストールし、その 2 つのアプリ間の連携方法について記述します。
今回作成するアプリは以下になります。

IntentBroadcast アプリ

  • Intentを Android 端末アプリケーション内の全てのアプリにブロードキャストするアプリケーション

IntentReceiver アプリ

  • ブロードキャストされたIntentを受信するアプリケーション

1. IntentBroadcast アプリについて

Activity 画面にボタンを配置し、そのボタンをタップすることでIntentを送信します。
ブロードキャストの方法は、以下のようにIntentインスタンスを作成し、sendBroadcast(intent)を実行することで可能です。

MainActivity.kt
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // ボタン1配置
        button1.setOnClickListener {
            // インテントをブロードキャスト
            val intent = Intent("com.example.broadcast.MY_NOTIFICATION1")
            intent.putExtra("data", "Notice me senpai!")
            sendBroadcast(intent)
        }

        // ボタン2配置
        button2.setOnClickListener {
            // インテントをブロードキャスト
            val intent = Intent("com.example.broadcast.MY_NOTIFICATION2")
            intent.putExtra("data", "Hello, world!")
            sendBroadcast(intent)
        }
    }
}

ここで、Intentのインスタンス作成時に以下のように Action 文字列をセットしています。
Intentを受信するレシーバはこのcom.example.broadcast.MY_NOTIFICATION1の部分を確認し、受け取るべき情報なのかを判断します。

そのため一意であればどんな文字列でも構いませんが、作法として「パッケージ名 + 任意の文字列」とするのがベターです。
(Android 端末内のアプリケーションのパッケージ名は基本的に一意であるためです。)

また、IntentputExtra()を利用することで情報を追加登録することができます。
今回はdataという名前でそれぞれ文字列をセットしました。



ちなみに以下のactivity_main.xmlstrings.xmlは画面にボタンを設置するために記述しているだけで、ブロードキャスト処理には関係ありません。
上記のソースを動かす際のサンプル用として参考してください。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="50dp"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button1" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button2" />
</LinearLayout>
strings.xml
<resources>
    <string name="app_name">IntentBroadcast</string>
    <string name="button1">Button1</string>
    <string name="button2">Button2</string>
</resources>

2. IntentReceiver アプリについて

こちらは Android 端末内にブロードキャストされているIntentを受信します。
受信の方法はまず、BroadcastReceiverクラスを継承した、ブロードキャストを実際に受信するクラス(MyBroadcastReceiverクラス)を作成します。

そしてメイン画面に、先ほど作成したMyBroadcastReceiverクラスを利用するレシーバを準備することでIntent受信が可能となります。

MyBroadcastReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast

class MyBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        // インテントに登録されている、名前"data"に対応する文字列をトーストで表示する
        Toast.makeText(context, intent?.getStringExtra("data"), Toast.LENGTH_SHORT).show()
    }
}
MainActivity.kt
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // BroadcastReceiverを継承したクラス(MyBroadcastReceiver)を指定する
        // IntentFilterは何を呼び出すかを振り分けるもの
        // 2020/03/20: links_2_3_4 さん指摘反映
        // 画面回転時にメモリリークに関する警告表示を阻止
        this.applicationContext.registerReceiver(
            MyBroadcastReceiver(),
            IntentFilter("com.example.broadcast.MY_NOTIFICATION1")
        )
        this.applicationContext.registerReceiver(
            MyBroadcastReceiver(),
            IntentFilter("com.example.broadcast.MY_NOTIFICATION2")
        )
    }
}

ここでMainActivity.ktでは、Intentの Action 文字列によってどのブロードキャストレシーバクラスを利用するかを設定しています。
(今回は同じブロードキャストレシーバクラスMyBroadcastReceiver()を設定しています。)

そしてIntentの Action 文字列(com.example.broadcast.MY_NOTIFICATION1)が、IntentFilter()内でで記述した文字列と同じであれば、設定したブロードキャストクラス内の処理が実行されます。

ブロードキャストレシーバクラスMyBroadcastReceiver.ktでは、Intentに登録された名前dataの文字列をトーストで表示するようにしました。

挙動確認

  1. IntentBroadcast アプリと IntentReceiver アプリを Android 端末にインストールします。
  2. IntentReceiver アプリを起動し、ホームボタンを選択するなどしてバックグラウンドに移動させます。
  3. IntentBroadcast アプリを起動し、画面上に設置したボタンをタップします。

うまくブロードキャスト送信・受信ができればIntentに登録したdataの文字列がトースト表示されます。
スライド1.JPG

これで、IntentBroadcast アプリで操作した情報が IntentReceiver アプリに受け渡され、2 つのアプリ間連携ができました。

最後に

今回は、1 つのアプリケーションでIntentをブロードキャストを行い、もう 1 つのアプリケーションでIntentを受け取ってトースト表示する仕組みを紹介しました。
本記事ではとても単純なケースを紹介しましたが、このIntentを使えば、複数の Android アプリケーションでの連携が可能になります。
今後余裕があれば、このIntentのやり取りを利用した他のサンプルも実装・紹介できたらなと思います。

最後まで閲覧いただき、ありがとうございました。

4
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7