たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 2811
Android 11 Beta きたぞおおおおおおおおお
🥳←これすき
Google Payが使えないと言いました。が、Suicaで電車に乗れたので多分おサイフケータイアプリでは対応していないNFC Payあたりが使えないんだと思います。
Felica使う系は多分行けるんじゃないですかね?
あとスライダー(RangeTemplate)動いたのでそれも
Android 11 Beta 1 来ました。
わたし的に楽しみにしてる機能は
Google Pay 使えなくなるらしいよ。DP4の段階では使えたんだけどまた使えなくなった。
Suica使えるんかな?
スマートホームなんてする予定なけどせっかくBeta版の登場と一緒にAPIが文書化されてるので試しに追加してみる。
なまえ | あたい |
---|---|
言語 | Kotlin |
Android | 11 Beta 1 |
端末 | Pixel 3 XL |
SDK Manager開いて、SDK Platformsタブを押して、Android 10.0+(R)にチェックを入れてApply押してダウンロードしましょう。
android {
compileSdkVersion 30
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "io.github.takusan23.devicecontrolstest"
minSdkVersion 30
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
compileSdkVersion 30
とtargetSdkVersion 30
になってればいいと思います。多分
ドキュメントがRxJava入れてることを前提にしているので私も入れます。
RxJavaなんて使ったことないんだけどね。
dependencies {
implementation 'org.reactivestreams:reactive-streams:1.0.3'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
}
おまじないです。
<service
android:name=".DeviceControlsService"
android:label="@string/app_name"
android:permission="android.permission.BIND_CONTROLS">
<intent-filter>
<action android:name="android.service.controls.ControlsProviderService" />
</intent-filter>
</service>
DeviceControlsService.kt
を作成します。
作成したら、ControlsProviderService()
を継承します。
class DeviceControlsService : ControlsProviderService() {
override fun createPublisherForAllAvailable(): Flow.Publisher<Control> {
}
override fun performControlAction(p0: String, p1: ControlAction, p2: Consumer<Int>) {
}
override fun createPublisherFor(p0: MutableList<String>): Flow.Publisher<Control> {
}
}
でもこのままだと返り値なにもないのでIDEが赤いなみなみ出すので今から書いていきましょう。
これから追加可能コントローラーを作っていきます。
ここからユーザーが選ぶわけですね。
createPublisherForAllAvailable()
に書いていきます。
// 追加するデバイスのID
val TOGGLE_BUTTON_ID = "toggle_button_id"
/**
* 追加可能コントローラーを用意する。
* */
override fun createPublisherForAllAvailable(): Flow.Publisher<Control> {
// コントローラーを長押しした時に表示するActivity
val intent = Intent(baseContext, MainActivity::class.java)
val pendingIntent =
PendingIntent.getActivity(baseContext, 10, intent, PendingIntent.FLAG_UPDATE_CURRENT)
// まとめてコントローラーを追加するので配列に
val controlList = mutableListOf<Control>()
// ON/OFFサンプル。
val toggleControl = Control.StatelessBuilder(TOGGLE_BUTTON_ID, pendingIntent)
.setTitle("ON/OFFサンプル") // たいとる
.setSubtitle("おすとON/OFFが切り替わります。") // サブタイトル
.setDeviceType(DeviceTypes.TYPE_LIGHT) // あいこんといろの設定。
.build()
// 配列に追加
controlList.add(toggleControl)
// Reactive Streamsの知識が必要な模様。私にはないのでサンプルコピペする。
return FlowAdapters.toFlowPublisher(Flowable.fromIterable(controlList))
}
コメント文は各自消してね。
ここで使うControl
はControl.StatelessBuilder
の方です。
これはまだ状態が(スイッチがONとかOFFとかって話)が分からない時に使うとか書いてあるけど多分この時に使います。
利用可能コントローラーの一覧を用意する
で選んだコントローラーをユーザーが操作できるようにします。
lateinit var updatePublisher: ReplayProcessor<Control>
/**
* ユーザーが選んだコントローラーを用意する
* 電源ボタン長押しでよばれる
* */
override fun createPublisherFor(p0: MutableList<String>): Flow.Publisher<Control> {
// コントローラーを長押ししたときに表示するActivity
val intent = Intent(baseContext, MainActivity::class.java)
val pendingIntent =
PendingIntent.getActivity(baseContext, 12, intent, PendingIntent.FLAG_UPDATE_CURRENT)
// 知識不足でわからん
updatePublisher = ReplayProcessor.create()
// コントローラー
if(p0.contains(TOGGLE_BUTTON_ID)) {
// ON/OFF
val toggle = ToggleTemplate("toggle_template", ControlButton(false, "OFFですねえ!"))
// ここで作るControlは StatefulBuilder を使う。
val control = Control.StatefulBuilder(TOGGLE_BUTTON_ID, pendingIntent)
.setTitle("ON/OFFサンプル") // たいとる
.setSubtitle("おすとON/OFFが切り替わります。") // サブタイトル
.setDeviceType(DeviceTypes.TYPE_LIGHT) // 多分アイコンに使われてる?
.setStatus(Control.STATUS_OK) // 現在の状態
.setControlTemplate(toggle) // 今回はON/OFFボタン
.build()
updatePublisher.onNext(control)
}
return FlowAdapters.toFlowPublisher(updatePublisher)
}
これでエラーは一応消えるので、早速実行してみましょう。
電源ボタン長押しすると、デバイス コントロールが追加されているので、押してみましょう。
押すと、コントローラーが提供されているアプリ一覧画面が表示されるので、今作っているアプリを選びましょう。
すると、さっき作ったコントローラーが現れるのでチェックを入れて、右下の保存ボタンを押しましょう。
するとコントローラーが追加されているはずです。
ですがこの段階では押してもなにも変わらないのでこれから押した時にON/OFF
を切り替える処理を書いていきたいと思います。
ちなみにエミュレータでAndroid 11動かすのにダウンロードが長かった。
押した時にON/OFFを切り替えられるようにします。
/**
* コントローラーを押したとき
* */
override fun performControlAction(p0: String, p1: ControlAction, p2: Consumer<Int>) {
// コントローラーを長押ししたときに表示するActivity
val intent = Intent(baseContext, MainActivity::class.java)
val pendingIntent =
PendingIntent.getActivity(baseContext, 11, intent, PendingIntent.FLAG_UPDATE_CURRENT)
// システムに処理中とおしえる
p2.accept(ControlAction.RESPONSE_OK)
// コントローラー分岐
when (p0) {
TOGGLE_BUTTON_ID -> {
// ON/OFF切り替え
// ToggleTemplate は BooleanAction
if (p1 is BooleanAction) {
// ONかどうか
val isOn = p1.newState
val message = if (isOn) "ONです" else "OFFです"
val toggle = ToggleTemplate("toggle_template", ControlButton(isOn, message))
// Control更新
val control = Control.StatefulBuilder(TOGGLE_BUTTON_ID, pendingIntent)
.setTitle("ON/OFFサンプル") // たいとる
.setSubtitle("おすとON/OFFが切り替わります。") // サブタイトル
.setDeviceType(DeviceTypes.TYPE_LIGHT) // 多分アイコンに使われてる?
.setStatus(Control.STATUS_OK) // 現在の状態
.setControlTemplate(toggle) // 今回はON/OFFボタン
.setStatusText(message)
.build()
updatePublisher.onNext(control)
}
}
}
}
これで押した時にON/OFFが切り替わるようになりました。
DeviceType#TYPE_LIGHT
見た目いい感じ。
スマートホームやってみたい(金ないけど)
ソースコードです。https://github.com/takusan23/DeviceControlsTest
それと本当はスライダー(値を調整できるRangeTemplate
てやつ)コントローラーがあったんですけど、私の環境ではうまく動きませんでした。Beta版だからなのかそもそも私が間違ってるのか?
RangeTemplate動きました。参考にしました
val sliderControl = Control.StatefulBuilder(SLIDER_BUTTON_ID, pendingIntent)
.setTitle("スライダーサンプル") // たいとる
.setSubtitle("スライダーです。") // サブタイトル
.setDeviceType(DeviceTypes.TYPE_LIGHT) // 多分アイコンに使われてる?
.setControlId(SLIDER_BUTTON_ID)
.setStatus(Control.STATUS_OK) // 現在の状態
sliderControl.setControlTemplate(
ToggleRangeTemplate(
"slider_template",
ControlButton(true, "slider_button"),
RangeTemplate("range", 0f, 10f, 1f, 1f, null)
)
)
updatePublisher.onNext(sliderControl.build())
performControlAction()はこうです。
// スライダー
// RangeTemplate は FloatAction
if (p1 is FloatAction) {
// 現在の値
val currentValue = p1.newValue
val sliderControl = Control.StatefulBuilder(SLIDER_BUTTON_ID, pendingIntent)
.setTitle("スライダーサンプル") // たいとる
.setSubtitle("スライダーです。") // サブタイトル
.setDeviceType(DeviceTypes.TYPE_LIGHT) // 多分アイコンに使われてる?
.setControlId(SLIDER_BUTTON_ID)
.setStatus(Control.STATUS_OK) // 現在の状態
val controlButton = ControlButton(true, "slider_button")
sliderControl.setControlTemplate(
ToggleRangeTemplate(
"slider_template",
controlButton,
RangeTemplate("range", 0f, 10f, currentValue, 1f, null)
)
)
updatePublisher.onNext(sliderControl.build())
}
あとDeviceType
がいっぱいあるので全種類アイコンと色を見てみたい。やってみるか。
やりました→ https://github.com/takusan23/DeviceControlAllDeviceTypeSample
Dynamic Intent Filterもやりたい