エミュレータでカメラ起動すると映るコレ。

微妙に動いてるんですけど...

何かのキャラなのか、
家にも見えたりするだけども、動いてるし。
一体、何なのっ?!
サンプル見てましたが。

android-PictureInPicture/README.md at master · googlesamples/android-PictureInPicture
...。
ただ、縮小されたActivityを常駐的に端末画面の上に載せたいだけなのですが...。
BlankActivityで実装するだけ。
これぐらいまで。

AndroidManifest.xml
<activity android:name=".MainActivity"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (VERSION.SDK_INT >= VERSION_CODES.O) {
text.setOnClickListener {
val params = PictureInPictureParams.Builder().apply {
setAspectRatio(Rational(4, 3))
}.build()
enterPictureInPictureMode(params)
}
}
}
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean,
newConfig: Configuration) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
if (isInPictureInPictureMode) {
text.text = "small"
setFullScreen(true)
} else {
text.text = "normal"
setFullScreen(false)
}
}
private fun setFullScreen(on: Boolean) {
window.decorView.systemUiVisibility = if (on) {
SYSTEM_UI_FLAG_LAYOUT_STABLE or
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
SYSTEM_UI_FLAG_HIDE_NAVIGATION or
SYSTEM_UI_FLAG_FULLSCREEN or
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
} else {
SYSTEM_UI_FLAG_LAYOUT_STABLE
}
}
}
PinPモードに入ったときのレイアウト変更は、フルスクリーンモードでツールバーを隠すのみ。
Preview 公開当時のサンプルが多いので、今現在の最小限実装でやってみたメモ的な。
関連APIは変化している様子。
便利そうなのでました!
Android Developers Blog: Announcing new SDK versioning in Google Play services and Firebase
com.google.android.gms:play-services-*
com.google.firebase:firebase-*
に関しては、それぞれが独立したバージョンで記述してよい。
なので、以下のような「バージョンをを揃える」記述は不要。
buildscript {
ext {
play_version = '15.0.0'
}
}
dependencies {
// DON'T DO THIS!!
// The following use of the above buildscript property is no longer valid.
implementation "com.google.android.gms:play-services-auth:${play_version}"
implementation "com.google.firebase:firebase-auth:${play_version}"
implementation "com.google.firebase:firebase-firestore:${play_version}"
}
利用方法は以下2パターン。
classpath 'com.google.gms:google-services:3.3.0'
// 最終行
apply plugin: 'com.google.gms.google-services'
かまたは、
classpath 'com.google.android.gms:strict-version-matcher-plugin:1.0.0'
// 最終行
apply plugin: 'com.google.android.gms.strict-version-matcher-plugin'
とのこと。
エラー。
ビルドできず。
The library com.google.android.gms:play-services-measurement-base
is being requested by various other libraries at [[15.0.0,15.0.0], [15.0.2,15.0.2]],
but resolves to 15.0.2. Disable the plugin and check your dependencies tree
using ./gradlew :app:dependencies.
記述にはない「play-services-measurement-base」が
内部的に呼ばれてこけている。
メッセージに書いてある
./gradlew :app:dependencies
は実行すらできない。
それぞれは、Andrid Studioの自動チェックで最新のはずなのだが。

目視でGoogleリポジトリを確認。


AndroidStudioの自動チェックで最新版の「15.0.0」だと思っていたが
実は、古いバージョンのままだった。
実際は「15.0.2」が最新。

これに書き換えたらいけた。
しかし、AndroidStudioの自動最新バージョンチェック機能らしきは、
機能してなくね?
かまたは、微妙に古くね?
「Preference」-「Editor」-「Inspections」 にある
「Lint」-「Newer Library Versions Available」

OFFになってるが。
Description
Newer Library Versions Available This detector checks with a central repository to see if there are newer versions available for the dependencies used by this project. This is similar to the GradleDependency check, which checks for newer versions available in the Android SDK tools and libraries, but this works with any MavenCentral dependency, and connects to the library every time, which makes it more flexible but also much slower.
「毎回チェックするのでとろい」ということで
デフォルトでOFFになっているのか。
毎回でなく適時、意図的に実行したい場合は、
「Analyze」-「Run Inspection by Name」からいきましょう。

グレーのハイライトと同時にツールチップで最新版である
「15.0.2」
をサジェストしてくれました!
IntelliJ IDEAベースのIDEで使えるプラグインです。
なので、Android Studioでも使えます。
こういうかんじに括弧に色が付きます。



最近は、言語進化の影響か、
そういえば、多重に入れ子になった括弧を
使うことが多くなったような気もしますね。
👉 Rainbow Brackets - IntelliJ IDEs Plugin | Marketplace
👉 【AndroidStudio】プラグイン Rainbow Brackets が括弧だけでなく 変数 まで色が付くようになる【IDEA】
つづいて、インデントも色付けしますか。
なんだか微妙な感じします。
APIの仕様がなのか、
サンプルのコードがなのか、
Camera2。
android-Camera2Basic/Camera2BasicFragment.kt at master · googlesamples/android-Camera2Basic
いくつかのコールバック処理が
連続して処理されますが
kotlin の芸当で分かりやすくしてみましょう。
多くの非同期処理APIは
コールバックスタイルのインターフェースを持ってます。
suspendCoroutine の 「suspend function」 を使うと
簡単にコールバックをその中にラッピングすることができます。
簡単な例を挙げてみます。
fun longComputation(params: Params, callback: (Result) -> Unit)
longComputation という function があって、
それのコールバックは Result という計算結果を受け取ります。
これは、以下のように簡単にラッピングできます。
suspend fun longComputation(params: Params): Result = suspendCoroutine { cont ->
longComputation(params) { cont.resume(it) }
}
分かりやすく計算結果を返し、同じ非同期ですがスレッドをブロックしません。
kotlin-coroutines/kotlin-coroutines-informal.md at master · Kotlin/kotlin-coroutines
例えば、Camera2 APIでは必須のこれ。
void openCamera (String cameraId,
CameraDevice.StateCallback callback,
Handler handler)
CameraManager | Android Developers
コールバックとバックグラウンドハンドラやスレッドの
準備や後始末の処理が必要ですが、
それらがあちこちに分散してしまい辛くなりますが、
Kotlin coroutine に頼ると、
きれいにラッピングできます。
suspend fun CameraManager.openCamera(cameraId: String): CameraDevice? =
suspendCoroutine { cont ->
val callback = object : CameraDevice.StateCallback() {
override fun onOpened(camera: CameraDevice) {
cont.resume(camera)
}
override fun onDisconnected(camera: CameraDevice) {
cont.resume(null)
}
override fun onError(camera: CameraDevice, error: Int) {
cont.resume(null)
}
}
openCamera(cameraId, callback, null)
}
android - Existing 3-function callback to Kotlin Coroutines - Stack Overflow
他のいくつかのコールバックも
同じように書き換えていくと
かなり見通しよくなります。
しかし、
このGサンプルコードは分かりづらすぎぢゃんね?