20210604のAndroidに関する記事は6件です。

【Kotlin研修3日目】アクティビティのライフサイクルとログレベル

アクティビティのライフサイクル 出典・参考: アクティビティのライフサイクル アクティビティのライフサイクルを示す図は以下の通り。 ライフサイクル アクティビティの起動から終了までの、アクティビティの状態遷移。 ライフサイクルコールバックメソッド アクティビティの画面状態に応じて呼び出されるメソッド。 ライフサイクルの流れ アプリ起動時 ライフサイクル 処理 [Main] onCreate() 初回起動時のバックグラウンド処理 [Main] onStart() アクティビティ(=画面)の起動 [Main] onResume() ユーザによる操作入力が可能 画面遷移時(Main→Sub) ライフサイクル 処理 [Main] onPause() アクティビティの一時的な停止 [Sub] onCreate() 初回起動時のバックグラウンド処理 [Sub] onStart() アクティビティの起動 [Sub] onResume() ユーザによる操作入力が可能 [Main] onStop() アクティビティの停止 画面遷移時(Sub→Main) ライフサイクル 処理 [Sub] onPause() アクティビティの一時的な停止 [Main] onRestart() アクティビティの再開 [Main] onStart() アクティビティの起動 [Main] onResume() ユーザによる操作入力が可能 [Sub] onStop() アクティビティの停止 [Sub] onDestroy() アクティビティの終了 マルチタスクボタンのタップ時(Main) Sub画面での実行時はMain→Subに置き換わる。 ライフサイクル 処理 [Main] onPause() アクティビティの一時的な停止 [Main] onStop() アクティビティの停止 マルチタスク画面によるアプリの終了時(Main) Sub画面での実行時はMain→Subに置き換わる。 ※Main画面のonDestroy()は実行されない ライフサイクル 処理 [Main] onDestroy() アクティビティの終了 「戻る」ボタンによるアプリの終了時 ライフサイクル 処理 [Main] onPause() アクティビティの一時的な停止 [Main] onStop() アクティビティの停止 [Main] onDestroy() アクティビティの終了 Androidのログレベル Logcatに表示される、Android OSまたはそのアプリが発するログメッセージの深刻度。 各ログレベルに対応するメソッドは、Logクラスで用意される。 ログレベル 内容 対応メソッド Assert 重大なエラー wtf() Error エラーを引き起こした問題 e() Warn エラーとはいえない潜在的な問題 w() Info 通常の使用で発生するログメッセージ i() Debug 製品版アプリでも出力されるデバッグログメッセージ d() Verbose 製品版アプリでは出力されないデバッグログメッセージ v() Logクラス ログの出力をLogcatに送信するAPI。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kotlin研修3日目】SimpleAdapterを用いたアクティビティ間のデータ共有と画面遷移

SimpleAdapter 参考1: 研修2日目 参考2: SimpleAdapter MutableList<MutableMap<String, *>>型のデータ構造をとるAdapterクラス。 MutableList 「キーと値をもち、要素数が可変」なMutableMap<String, *>型のデータを、各インデックスに格納したリスト。 SimpleAdapterの生成 定義 SimpleAdapter( context: Context!, data: MutableList<out MutableMap<String!, *>!>!, resource: Int from: Array<String>! to: IntArray! ) // パラメータ // context: コンテキストとなるアクティビティオブジェクト // data: リスト形式ビューに反映するリストデータ // resource: リスト形式ビューの各Itemのレイアウトを表現するR値 // from: MutableMapのキーのみを格納した配列 // to: Item内の複数のビュー(=TextView)を識別するR値(=ID)を格納した配列 // -> toで指定したビュー(=TextView)に対して、 // fromで指定したキーに対応する値を格納 値を加工して表示するListView MainActivity.kt // 発展: 値を加工したListViewの生成 class MainActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... val nameList = createNameList() val from = arrayOf("name", "sex") val to = intArrayOf(R.id.tvName, R.id.imSex) // Adapterオブジェクトの生成 val adapter = SimpleAdapter( applicationContext, nameList, R.layout.row, from, to ) // AdapterにViewBinderオブジェクトをセット adapter.viewBinder = CustomViewBinder() // リストデータを紐づけるListViewの定義 val lvPhones = findViewById<ListView>(R.id.lvNameList) // ListViewにAdapterオブジェクトをセット lvPhones.adapter = adapter } // 加工するリストデータを生成するメソッド private fun createNameList(): MutableList<MutableMap<String, Any>> { // 加工するリストデータを記述 ... // 最終的に"return <リストデータ>"を記述 } // MutableMapの値を基にデータを加工するクラス private inner class CustomViewBinder: SimpleAdapter.ViewBinder { // MutableMapの値を基にデータを加工 // -> ListView生成時に自動的に実行される override fun setViewValue( view: View, data: Any, textRepresentation: String ): Boolean { // データの加工処理 ... // 最終的に"return true/false"を記述 // true: データのバインドが実行された場合 // false: データのバインドが実行されなかった場合 } } } 画面の追加 参考: 研修1日目 アプリに表示される文字列を除き、アプリの1画面を構成しているのは、以下の3つ。 アプリ内処理を担う、app/javaフォルダのアクティビティクラス(=.ktファイル) 画面構成を担う、app/res/layoutフォルダのレイアウトファイル(=.xmlファイル) 1.および2.を認識する、app/manifestsフォルダのAndroidManifest.xmlファイル 画面を追加する場合は、AndroidManifest.xmlファイルにactivityタグを記述する必要がある。 ※Android Studioは、New Activityの作成時に、アクティビティの追加にあたって必要な処理を自動的に行う。 Androidにおける画面遷移 遷移先の画面は、遷移元の画面の前面に表示される。 遷移先から戻る場合は、遷移先の画面が消滅し、背面に隠れていた遷移元の画面が表示される挙動をとる。 インテント(Intent) 参考: インテント 参考2: インテントのクラスメソッド 画面遷移にあたり、画面(=アクティビティ)を起動するクラス。 遷移元アクティビティと遷移先アクティビティの橋渡し役を担う。 Intentクラスのインスタンス化(実体化) 定義 Intent(packageContext: Context!, cls: Class<*>!) // パラメータ // packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト) // cls: Javaクラス化した遷移先アクティビティ // -> KotlinのクラスをJavaに変換する場合は、"<Kotlinクラス名>::class.java"と記述 Intentオブジェクトへのデータの格納 定義 putExtra(name: String!, value: String?): Intent // パラメータ // name: 格納するデータの名称 // value: 格納するデータ 遷移先アクティビティの起動(画面遷移) 定義 Context.startActivity(intent: Intent!): Unit // パラメータ // intent: 画面遷移を実現するIntentオブジェクト サンプルコード MainActivity.kt class MainActivity: AppCompatActivity() { ... // リスナクラス private inner class ListItemClickListener: AdapterView.OnItemClickListener { // "タップ"イベント検知時の処理(イベントハンドラ) override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { // "タップ"されたItemの定義 // parent: AdapterView // getItemAtPosition(): 指定したIndex(position)のtext値を取得(返り値はAny型) val item = parent?.getItemAtPosition(position) as MutableMap<String, String> // 指定したキーの値 val menuName = item["name"] val menuPrice = item["price"] // 画面遷移を実現するIntentオブジェクトの生成 // Intent(packageContext:cls:): Intentオブジェクトの生成 // packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト) // cls: Javaクラス化した遷移先アクティビティ val intent2MenuThanks = Intent( this@MainActivity, MenuThanksActivity::class.java ) // Intentオブジェクトへのデータの格納 // putExtra(name:value:): Intentオブジェクトにデータを格納 // name: 格納するデータの名称 // value: 格納するデータ intent2MenuThanks.putExtra("menuName", menuName) intent2MenuThanks.putExtra("menuPrice", menuPrice) // 遷移先アクティビティの起動 // Context.startActivity(intent:): Intentオブジェクトによる画面遷移の実行 // intent: Intentオブジェクト startActivity(intent2MenuThanks) } } } apply関数を用いたIntentオブジェクトの生成・定義 MainActivity.kt // 発展: apply関数の使用 // 本来はこっち // 画面遷移を実現するIntentオブジェクトの生成 val intent2MenuThanks = Intent( this@MainActivity, MenuTahnksActivity::class.java ) // Intentオブジェクトへのデータの格納 intent2MenuThanks.putExtra("menuName", menuName) intent2MenuThanks.putExtra("menuPrice", menuPrice) // apply関数(スコープ関数)を用いる場合 // -> applyブロック{...}内では、インスタンス変数(intent2MenuThanks)の記述が不要 val intent2MenuThanks = Intent( this@MainActivity, MenuTahnksActivity::class.java ).apply { putExtra("menuName", menuName) putExtra("menuPrice", menuPrice) } 遷移先アクティビティの終了 定義 finish(): Unit 遷移先による遷移元の値取得 遷移元のデータはIntentオブジェクトが保持しているため、遷移先アクティビティでintentプロパティを用いてデータを取得する。 文字列(String) 定義 Intent.getStringExtra(name: String!): String? // パラメータ // name: Intentオブジェクト(=intentプロパティ)に格納されたデータの名称 数値(Int) 定義 Intent.getIntExtra(name: String!, defaultValue: Int): Int // パラメータ // name: Intentオブジェクト(=Activity.intent)に格納されたデータの名称 // defaultValue: 取得するデータの初期値 // <- 指定したnameのデータが存在しない場合のnullを避ける サンプルコード MenuThanksActivity.kt class MenuThanksActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... // Intentオブジェクトが保持するデータの取得 val menuName = intent.getStringExtra("menuName") val menuPrice = intent.getStringExtra("menuPrice") // 値を反映する遷移先ビューの定義 val tvMenuName = findViewById<TextView>(R.id.tvMenuName) val tvMenuPrice = findViewById<TextView>(R.id.tvMenuPrice) // 遷移先ビューの値(=TextView.text)の変更 tvMenuName.text = menuName tvMenuPrice.text = menuPrice } } レイアウトファイルによるリスナ定義 参考: タップイベントのイベント処理 イベントを検知するリスナを定義する方法は以下の2つ。 Activityファイルでリスナクラスを定義 レイアウトファイルにandroid:onClick属性を追加し、その属性値と一致するイベントハンドラをActivityファイルに記述 サンプルコード activity_menu_thanks.xml <Button ... android:onClick="onBackButtonClick" <!-- リスナ定義 --> /> MenuThanksActivity.kt class MenuThanksActivity: AppCompatActivity() { ... // "タップ"イベント検知時の処理(イベントハンドラ) // ※実装にあたって制約が存在(後述) fun onBackButtonClick(view: View) { ... } } 制約 レイアウトファイルでリスナの定義を行う場合、イベントハンドラは以下の要件を満たす必要がある。 publicメソッドであること(Kotlinではpublicが規定値) 返り値がない(=Unit型である)こと View型1つのみの引数をとること
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kotlin研修3日目】SimpleAdapterを用いたアクティビティ間のデータ共有と画面遷移、レイアウトファイルでのリスナ定義

SimpleAdapter 参考1: 研修2日目 参考2: SimpleAdapter MutableList<MutableMap<String, *>>型のデータ構造をとるAdapterクラス。 MutableList 「キーと値をもち、要素数が可変」なMutableMap<String, *>型のデータを、各インデックスに格納したリスト。 SimpleAdapterの生成 定義 SimpleAdapter( context: Context!, data: MutableList<out MutableMap<String!, *>!>!, resource: Int from: Array<String>! to: IntArray! ) // パラメータ // context: コンテキストとなるアクティビティオブジェクト // data: リスト形式ビューに反映するリストデータ // resource: リスト形式ビューの各Itemのレイアウトを表現するR値 // from: MutableMapのキーのみを格納した配列 // to: Item内の複数のビュー(=TextView)を識別するR値(=ID)を格納した配列 // -> toで指定したビュー(=TextView)に対して、 // fromで指定したキーに対応する値を格納 値を加工して表示するListView MainActivity.kt // 発展: 値を加工したListViewの生成 class MainActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... val nameList = createNameList() val from = arrayOf("name", "sex") val to = intArrayOf(R.id.tvName, R.id.imSex) // Adapterオブジェクトの生成 val adapter = SimpleAdapter( applicationContext, nameList, R.layout.row, from, to ) // AdapterにViewBinderオブジェクトをセット adapter.viewBinder = CustomViewBinder() // リストデータを紐づけるListViewの定義 val lvPhones = findViewById<ListView>(R.id.lvNameList) // ListViewにAdapterオブジェクトをセット lvPhones.adapter = adapter } // 加工するリストデータを生成するメソッド private fun createNameList(): MutableList<MutableMap<String, Any>> { // 加工するリストデータを記述 ... // 最終的に"return <リストデータ>"を記述 } // MutableMapの値を基にデータを加工するクラス private inner class CustomViewBinder: SimpleAdapter.ViewBinder { // MutableMapの値を基にデータを加工 // -> ListView生成時に自動的に実行される override fun setViewValue( view: View, data: Any, textRepresentation: String ): Boolean { // データの加工処理 ... // 最終的に"return true/false"を記述 // true: データのバインドが実行された場合 // false: データのバインドが実行されなかった場合 } } } 画面の追加 参考: 研修1日目 アプリに表示される文字列を除き、アプリの1画面を構成しているのは、以下の3つ。 アプリ内処理を担う、app/javaフォルダのアクティビティクラス(=.ktファイル) 画面構成を担う、app/res/layoutフォルダのレイアウトファイル(=.xmlファイル) 1.および2.を認識する、app/manifestsフォルダのAndroidManifest.xmlファイル 画面を追加する場合は、AndroidManifest.xmlファイルにactivityタグを記述する必要がある。 ※Android Studioは、New Activityの作成時に、アクティビティの追加にあたって必要な処理を自動的に行う。 Androidにおける画面遷移 遷移先の画面は、遷移元の画面の前面に表示される。 遷移先から戻る場合は、遷移先の画面が消滅し、背面に隠れていた遷移元の画面が表示される挙動をとる。 インテント(Intent) 参考: インテント 参考2: インテントのクラスメソッド 画面遷移にあたり、画面(=アクティビティ)を起動するクラス。 遷移元アクティビティと遷移先アクティビティの橋渡し役を担う。 Intentクラスのインスタンス化(実体化) 定義 Intent(packageContext: Context!, cls: Class<*>!) // パラメータ // packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト) // cls: Javaクラス化した遷移先アクティビティ // -> KotlinのクラスをJavaに変換する場合は、"<Kotlinクラス名>::class.java"と記述 Intentオブジェクトへのデータの格納 定義 putExtra(name: String!, value: String?): Intent // パラメータ // name: 格納するデータの名称 // value: 格納するデータ 遷移先アクティビティの起動(画面遷移) 定義 Context.startActivity(intent: Intent!): Unit // パラメータ // intent: 画面遷移を実現するIntentオブジェクト サンプルコード MainActivity.kt class MainActivity: AppCompatActivity() { ... // リスナクラス private inner class ListItemClickListener: AdapterView.OnItemClickListener { // "タップ"イベント検知時の処理(イベントハンドラ) override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { // "タップ"されたItemの定義 // parent: AdapterView // getItemAtPosition(): 指定したIndex(position)のtext値を取得(返り値はAny型) val item = parent?.getItemAtPosition(position) as MutableMap<String, String> // 指定したキーの値 val menuName = item["name"] val menuPrice = item["price"] // 画面遷移を実現するIntentオブジェクトの生成 // Intent(packageContext:cls:): Intentオブジェクトの生成 // packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト) // cls: Javaクラス化した遷移先アクティビティ val intent2MenuThanks = Intent( this@MainActivity, MenuThanksActivity::class.java ) // Intentオブジェクトへのデータの格納 // putExtra(name:value:): Intentオブジェクトにデータを格納 // name: 格納するデータの名称 // value: 格納するデータ intent2MenuThanks.putExtra("menuName", menuName) intent2MenuThanks.putExtra("menuPrice", menuPrice) // 遷移先アクティビティの起動 // Context.startActivity(intent:): Intentオブジェクトによる画面遷移の実行 // intent: Intentオブジェクト startActivity(intent2MenuThanks) } } } apply関数を用いたIntentオブジェクトの生成・定義 MainActivity.kt // 発展: apply関数の使用 // 本来はこっち // 画面遷移を実現するIntentオブジェクトの生成 val intent2MenuThanks = Intent( this@MainActivity, MenuTahnksActivity::class.java ) // Intentオブジェクトへのデータの格納 intent2MenuThanks.putExtra("menuName", menuName) intent2MenuThanks.putExtra("menuPrice", menuPrice) // apply関数(スコープ関数)を用いる場合 // -> applyブロック{...}内では、インスタンス変数(intent2MenuThanks)の記述が不要 val intent2MenuThanks = Intent( this@MainActivity, MenuTahnksActivity::class.java ).apply { putExtra("menuName", menuName) putExtra("menuPrice", menuPrice) } 遷移先アクティビティの終了 定義 finish(): Unit 遷移先による遷移元の値取得 遷移元のデータはIntentオブジェクトが保持しているため、遷移先アクティビティでintentプロパティを用いてデータを取得する。 文字列(String) 定義 Intent.getStringExtra(name: String!): String? // パラメータ // name: Intentオブジェクト(=intentプロパティ)に格納されたデータの名称 数値(Int) 定義 Intent.getIntExtra(name: String!, defaultValue: Int): Int // パラメータ // name: Intentオブジェクト(=Activity.intent)に格納されたデータの名称 // defaultValue: 取得するデータの初期値 // <- 指定したnameのデータが存在しない場合のnullを避ける サンプルコード MenuThanksActivity.kt class MenuThanksActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... // Intentオブジェクトが保持するデータの取得 val menuName = intent.getStringExtra("menuName") val menuPrice = intent.getStringExtra("menuPrice") // 値を反映する遷移先ビューの定義 val tvMenuName = findViewById<TextView>(R.id.tvMenuName) val tvMenuPrice = findViewById<TextView>(R.id.tvMenuPrice) // 遷移先ビューの値(=TextView.text)の変更 tvMenuName.text = menuName tvMenuPrice.text = menuPrice } } レイアウトファイルによるリスナ定義 参考: タップイベントのイベント処理 イベントを検知するリスナを定義する方法は以下の2つ。 Activityファイルでリスナクラスを定義 レイアウトファイルにandroid:onClick属性を追加し、その属性値と一致するイベントハンドラをActivityファイルに記述※フラグメントでは実装不可 サンプルコード activity_menu_thanks.xml <Button ... android:onClick="onBackButtonClick" <!-- リスナ定義 --> /> MenuThanksActivity.kt class MenuThanksActivity: AppCompatActivity() { ... // "タップ"イベント検知時の処理(イベントハンドラ) // ※実装にあたって制約が存在(後述) fun onBackButtonClick(view: View) { ... } } 制約 レイアウトファイルでリスナの定義を行う場合、イベントハンドラは以下の要件を満たす必要がある。 publicメソッドであること(Kotlinではpublicが規定値) 返り値がない(=Unit型である)こと View型1つのみの引数をとること
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

広告IDを使用したパーソナライズがオプトアウトされると広告IDが使用できなくなる予定

タイトルの通りで、広告 ID を使用したパーソナライズがオプトアウトされると広告 ID が使用できなくなるというアナウンスがあった。 何が起きるのか As part of Google Play services update in late 2021, the advertising ID will be removed when a user opts out of personalization using advertising ID in Android Settings. Any attempts to access the identifier will receive a string of zeros instead of the identifier. ユーザーが設定で広告のパーソナライズをオプトアウトすると、広告 ID が削除される アプトアウトされた状態で広告 ID を取得しようとすると 0 の文字列が返ってくるようになる いつから起きるのか This Google Play services phased rollout will affect apps running on Android 12 devices starting late 2021 and will expand to affect apps running on devices that support Google Play in early 2022. 2021 年後半の Google Play サービス アップデートで段階的に適用される 2021 年後半からは Android 12 デバイスが対象 2022 年初頭には Google Play をサポートするデバイスが対象 どう対応するのか In July, we will provide more details and an alternate solution to support essential use cases such as analytics and fraud prevention. 7 月により詳細な情報と、分析や不正防止などの必須ユースケースをサポートする代替ソリューションが出てくるらしい。 一意の識別子のベストプラクティスは Best practices for unique identifiers を参考にとのこと。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kotlin研修3日目】ConstraintLayoutの制約とチェイン機能

ConstraintLayout 参考: 研修1日目 Android Studio標準のレイアウト部品(ビューグループ)。 ビュー(ウィジェット)の相対的配置を可能にするレイアウト。 RelativeLayoutは、任意のビューを基点とし、基点を基にした相対配置を行う。 ConstrainLayoutは、全てのビューを相対指定して配置を行う。 制約(Constraint) ビューのx/y方向に存在するビュー(親ビューも指定可能)の指定。 制約は、x/y方向に対して1つ以上のビューを指定する。 制約の属性(attribute) 属性 内容 app:layout_constraintTop_toTopOf 上方向のビュー親部品: parentそれ以外: ビューのid app:layout_constraintTop_toBottomOf 上方向のビュー親部品: parentそれ以外: ビューのid app:layout_constraintStart_toStartOf 左方向のビュー親部品: parentそれ以外: ビューのid app:layout_constraintEnd_toEndOf 右方向のビュー親部品: parentそれ以外: ビューのid ConstraintLayoutにおけるlayout_width/height 親ビューの上限サイズまで拡張する場合は、layout_width/height属性に0dpを指定する(=Match Constraints)。 または、DesignモードのConstraint Widgetアイコンで変更することができる。 ※ConstraintLayoutではmatch_parentが使用不可 3種類のlayout_width/height アイコン(属性値) 内容 Wrap Contentビューの表示に必要な最小サイズ Fixed具体的なサイズ単位 Match Constraints制約内での最大サイズ※設定値: 0dp ベースライン ビュー間で、文字列の位置を制約できる線。 ガイドライン ビュー間で、ビューの位置を制約できる線。 チェイン機能 互いに制約し合う、複数のビューのグループ化。 チェインスタイル(chain style) スタイル 内容 spread 均等配置 spread inside 親レイアウト境界に対して、両端ビューが接する均等配置 packed 各ビューが接する配置 weighted spread/spread inside配置のうち、Match Constraintsを適用した配置
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Androidアプリで通知を実装する

はじめに Androidアプリの通知の実装をしたことがなかったので挑戦してみました。 最低限の通知の実装のことしか書いていないので、ボタンをつけたりなど高度な(?)通知を実装したい方は他の記事を参照されることをお勧めします。 環境 macOS Catalina(Version 10.15.7) Android Studio 4.0.1 実装ステップ 大まかに分けると4ステップで実現できます。 通知内容の作成 チャネルの作成 通知タップ時のアクションの設定 通知を表示する 1. 通知内容の作成 1-1. チャネルIDの作成 Android 8.0(API レベル 26)以上の端末をサポートする場合に設定が必要です。 NotificationCompat.Builder オブジェクトを使って表示内容を設定する際、チャネルIDを渡します。 ※チャネルについては後述 1-2. 表示内容の設定 smallアイコン、タイトル、文字などを設定します 表示内容のうち必須の設定項目はsmallアイコンのみで、これが設定されていないとクラッシュします。 その他は任意項目です。(とはいえタイトルもテキストも設定されていない通知とかあるの・・?) smallアイコン:アプリ名の左に表示されるアイコンのこと。設定必須。 通知内容のTitle:1行目に表示されるタイトル。 通知内容のText:タイトルの下に表示されるテキスト。デフォルトでは1行表示。 1-3. 通知の優先度の設定 Android 7.1 以下をサポートする場合、setPriority() で通知の優先度を設定します。 Android 8.0 以上の場合は後述する通知チャネルで設定する値が優先されるので設定は不要です。 重要度の一覧はこちら。 サンプルコード // 1-1. チャネルIDを作成 val channelId = "NOTIFICATION_CHANNEL_ID_TRIAL" val builder = NotificationCompat.Builder(this, channelId) // 1-2. 表示内容の設定 .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("通知のTitle?") .setContentText("通知のText?通知ですよ〜") // 1-3. 優先度の設定 .setPriority(NotificationCompat.PRIORITY_DEFAULT) 2. チャネルの作成 Android 8.0 以上をサポートする場合に必要な処理です。 システムにアプリの通知チャネルを登録することで、設定画面からチャネルごとに表示の大きさやサウンドなどが調節できるようになります。 ※通知チャネルの詳細についてはこちらをご確認ください 2-1. NotificationChannel オブジェクトを作成 チャネルIDや名前を指定してNotificationChannelオブジェクトを作成します。 - チャネルID:一意のID。ここでは 1-1. チャネルIDの作成 で作成したものを設定。 - チャネル名:ユーザー向けのチャネル名。設定画面で表示される。 - 説明文:チャネルの説明文。設定画面で表示されるため、必要に応じて設定。 - 重要度:1-3. 通知の優先度の設定 の8.0以上の端末向けの設定。重要度の一覧はこちら。 2-2. チャネルをシステムに登録 作成したチャネルをシステムに登録します。 登録には NotificationManager のcreateNotificationChannelを使用します。 サンプルコード // Android 8.0以上の場合のみ実行する if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 2-1. NotificationChannel オブジェクトを作成 val name = "お試し通知" val descriptionText = "お試しで通知を送るための通知チャンネルです?!" val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel(channelId, name, importance).apply { description = descriptionText } // 2-2. チャネルをシステムに登録 val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } 3. 通知タップ時のアクションの設定 ユーザーが通知をタップした時のアクションを設定します。 ここでは、通知をタップしたらアプリが開くようにします。 3-1. アプリ内アクティビティへのインテントを設定 通知をタップされた時に開きたいアクティビティを指定してインテントを作成します。 PendingIntentオブジェクトを使って作成することで、指定したタイミング(この場合は通知タップ時)にintentが発行されます。 3-2. インテントをbuilderに設定 setContentIntent() を使って1. 通知内容の作成で作成したbuilderにインテントを設定し、通知タップ時に開くようにします。 ※通知タップ時に通知が消されるようにsetAutoCancel()をtrueにする設定もしておきます。 // 3-1. アプリ内アクティビティへのインテントを設定 val intent = Intent(this, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0) val builder = NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("通知のTitle?") .setContentText("通知のText?通知ですよ〜") .setPriority(NotificationCompat.PRIORITY_DEFAULT) // 3-2. インテントをbuilderに設定 .setContentIntent(pendingIntent) .setAutoCancel(true) 4. 通知を表示する 通知を表示する時はNotificationManagerCompat.notify()を呼び出します。 この時指定するnotificationIdは通知ごとにユニークなIDを設定します。このIDは通知の更新や削除にも使われます。 // 4. 通知を表示する with(NotificationManagerCompat.from(this)) { // notificationIDとbuilder.build()を渡します notify(12345, builder.build()) } ビルドして通知を送ると、こんな感じで表示されます↓↓ わーい成功 ※通知を発火させる用のボタンを用意して動作確認しました。(onClickListener内に↑↑のコードたちを書きました) 参考資料 この記事は以下の情報を参考にして執筆しました。 通知の実装方法について 通知の概要(Androidデベロッパー) 通知を作成する(Androidデベロッパー) 通知のデザインと操作パターンについて Android notifications(Material Design) おわりに 今回はかなり最低限の通知を実装しましたが、ボタンをつけてアクションを設定したり展開可能にするなど色々なオプションがあるのでそちらも試してみるつもりです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む