Android関連のことを調べてみた

Android関連のことを調べてみた

[WIP]Google I/O 2024で驚いたところメモ

特に驚いたところを赤く表示しています。(ちょっと風邪引いてまとめるのがいつもより遅くなっています。 :pray: )

# Keynote

(いつも通り夜ふかししながら書いているのでクオリティ低めです。)

* Gemini
AI Overview

Photos
ナンバープレートの番号を聞ける。

Geminiはcontextが長いのがいいらしい。
コードのコメントについてGeminiが返してくれるなどの開発者の話など。

1.5 Pro

1Mコンテキストで 35言語で使えるように。

2Mトークン。 private previewが始まった。

### NotebookLM

https://notebooklm.google/

pdfとかドキュメントとかを入れられる。

靴の写真を撮ってそれで、購

KMPのandroidMainの中でContextを取得する

sharedモジュールのandroidMainの中でContextを取得する方法がわからなかったため、調べてみました。

# 概要
JetpackライブラリのApp Startライブラリを使うと、アプリの起動時にコンポーネントを初期化することができるようです。
今回はこの仕組みを使って、`applicationContext`のグローバル変数を作成します。

# コンポーネント初期化子を実装する
`Initializer`を実装したクラスを作成します。
“`kotlin
package klocation

import android.content.Context
import androidx.startup.Initializer

// androidMainの中で参照するContext
internal lateinit var applicationContext: Context
private set

public object KLocationContext

/**
* applicationContextを

【Flutter】文字列操作: 特定の文字列を語尾に含む場合に削除する方法

## 本記事で紹介すること

Flutterの文字列(String)において、特定の文字列を含む場合、該当の語尾を削除する方法

## 解決方法

replaceAll関数を用いて、正規表現で文末を意味する”$”を使って、文末に特定の文字列が一致するかを検索して、空文字””で入れ替える。

## 実際のコード

“`dart:main.dart
void main() {
// 例の文字列
String text1 = “bukunya”;
String text2 = “bukuku”;
String text3 = “bukumu”;
String text4 = “This is a test”;

// 文末が “nya”、”ku”、”mu” のいずれかであれば削除
String result1 = removeEnding(text1);
String result2 = removeEnding(text2);
String result3 = removeEnding(text3);
String result4 = remove

Androidアプリの構成

# Androidアプリの構成

![20240521_233943.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/670414a2-ce9e-cd92-765a-d3acab2f21f7.jpeg)

classpathなどを使わずAndroidにOSS Licenses Gradle Pluginを組み込む方法

コピペです。

https://github.com/google/play-services-plugins/issues/223#issuecomment-1236159132

https://stackoverflow.com/a/77404419

“`kotlin:settings.gradle.kts
pluginManagement {
repositories {
google {
content {
includeGroupByRegex(“com\\.android.*”)
includeGroupByRegex(“com\\.google.*”)
includeGroupByRegex(“androidx.*”)
}
}
mavenCentral()
gradlePluginPortal()
}
// 追加
resolut

ネットワーク復旧後にモバイルアプリの計装データが送信されることを確認してみた!

# 概要
モバイルアプリをNew Relicのエージェントを使ってモニタリングしている際にネットワークがオフラインになるとその間のデータはNew Relicに送付できない可能性があります。

New Relic アップデート(2024年3月)の中で、**『オフラインストレージでデータロストを最小限に』** というアップデートがあったので、今回はAndroidのエミュレーターを使ってイベントデータがネットワーク復旧後に送信されることを確認してみたいと思います!

:::note info
このアップデートの詳細はこちら
[New Relic アップデート(2024年3月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202403 “New Relic アップデート(2024年3月)”)
:::

# 手順
## 1. AndroidのアプリにNew Relicのエージェントを設定
今回はAndroid StudioのNew Projectから[Empty Activity]を作成して、New RelicのAndroidエ

List<>よりも、ImmutableList<>を使った方が、パフォーマンスが上がる

Kotlin実装で学んだことの、自分用の覚え書きです。m(_ _)m
# ポイント
– List<>よりも、ImmutableList<>を使った方が、パフォーマンスが上がる
#
– 可変であるList<>を使うと、更新したComposeのアイテム以外も再度作り直しが発生する
– 全く変更がされない(読み取り専用)のImmutableList<>を使うと、変更が無かったComposeのアイテムの作り直しは発生しない
(入力に変更が無ければスキップされるため)
– **ImmutableList<>の方が、無駄な再描画がかからないため、パフォーマンスがいい**

# 参考サイト
– そもそもImmutableがよく分からなくて調べたサイト
https://qiita.com/TOM117/items/383460b8f262f74afd6e

– Immutableにする理由は、このサイトが参考になるかも

DjangoChannelsを用いたWebsocket非同期通信(UnityとAndroidでの同時通信,APIをPaaSにデプロイするまで)

この記事ではDjangoChannelsを用いた非同期通信を実現するための方法について記載する.

# 非同期通信とは?
プロセスやプログラムがタスクを実行する際に,その完了を待たずに次の操作に移ることができる通信方式のこと.この通信方式では,リクエストを送信した後,レスポンスが返ってくるまでの間にも他の作業を同時並行で進めることが可能である.

非同期通信が実装できると以下のようなプロダクトが開発できる.
1.リアルタイムチャットアプリ
2.ライブアップデートを提供するダッシュボード
3.非同期処理を必要とする幅広いWebサービス
4.リアルタイムゲーム

# 開発概要
![スクリーンショット 2024-05-19 18.10.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/89a2a64b-af3d-0755-8c95-91406152b66d.png)

今回は簡単にこのようにUnity(VRなど)上でカメラの位置を送信し,Androidでそのカメラの位置(赤円)を受信すること

【Android】キーボード表示

# はじめに
キーボードを表示する方法が調べたところ二つ出てきたので、どちらも調べ直さなくいていいようにメモがわりに記事にしておきます。

# 表示(Java)

“`
binding.edtMessage.requestFocus();
InputMethodManager keyboardManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInput(binding.edtMessage, 0);
“`
または、
“`
binding.edtMessage.requestFocus();
InputMethodManager keyboardManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
keyboardManager.toggleSoftInput(1, InputMetho

JetpackCompose LazyColumnを使用して、指定したindexにスクロールする方法

LazyColumnを使用して、指定したindexにスクロールする方法です。

今後も使うことがありそうなので、こちらに実装方法を記載します。

# サンプルコード

“`Sample.kt
@Composable
fun Sample() {
val sampleList = mutableListOf()
repeat(100) {
sampleList.add(“アイテム$it”)
}
Column(
modifier = Modifier
.fillMaxSize()
) {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()

LazyColumn(
state = listState
) {
items(sampleList) {

【Flutter】Patrolでテストを書く(基本編)

## はじめに

[【Flutter】Patrolでテストを書く(導入まで)](https://qiita.com/yyyy_yk/items/371c9ef67e81e39a7f58) の続きです。
実際に`patrol`で統合テストを書いて実行します。
最終的なゴールはネイティブビューをテストすることですが、まずは`patrol`で基本のテストを書いてみます。

※ [Finder](https://api.flutter.dev/flutter/flutter_test/Finder-class.html)や[WidgetTester](https://api.flutter.dev/flutter/flutter_test/WidgetTester-class.html)の基本的な使い方については触れません。

## 環境

・flutter: 3.19.6
・dart: 3.3.4
・patrol: 3.6.1
・patrol_cli: 2.7.0

## 基本のテスト

まずはFlutterプロジェクト作成時にデフォルトで用意されているDemoアプリに対してテストを書いてみ

AGP8以降からnamespaceはgradleへ

# はじめに
AGP8.0がリリースされたのは去年の4月ごろなのでもう1年が経過しているのですね。
本当にあっという間だと感じますが、AGP8以前はmanifestのnamespace設定は警告表示となっていました。
ですがAGP8からはgradleへの記述が必須になりましたので、詳細などを備忘録的にまとめたいと思います。

# gradleへ記述が必須となった背景
以前のAGPバージョンでは、アプリケーションIDとパッケージ名を区別していましたが、Manifestでパッケージ名が定義され、Gradle内でアプリケーションIDが設定される形となることで混乱を招くと判断し、Gradleへの記述が必須となったようです。

また、AGP 8.0以降では、プロジェクトごとに一意のnamespaceを指定することが必須になったことにより、コードとリソースが一貫性のある名前空間内で管理されるようになります。
それによりビルドパフォーマンスの向上するとのこと。

# 設定方法
これは非常に簡単で、app以下のgradleへnamespace設定を記述するのみです。

“`app/build.gra

子供向けにチャットアプリを作ってみた

## はじめに
ここ数年間React Nativeを触れる機会がなかったのですが、キャッチアップのために子供が使えそうなチャットのアプリを作ってみました。普段からWebのフロントエンドもReactで実装することがほとんどなのでやはり大きく迷うことはなく、Expo(特にEASのよるビルド、デプロイ)とFirebase、React Native Paperでかなりスムーズに進んだ印象です。本記事では使用した開発スタックと少し実装面の説明、出来上がったアプリの紹介などをしたいと思います。

## 開発Stack

ざっとこのような感じです。

– [Expo](https://expo.dev/)(EAS、Expo Routerが便利)
– [Firebase](https://firebase.google.com/)(Authentication、Firestore)
– [React Native Paper](https://reactnativepaper.com/)(Material Designのコンポーネントライブラリ)
– [RevenueCat](https://www.

ViewPager2でページ境界にドロップシャドウを入れる方法

ViewPager2でもPageTransformerを使うことで、様々なページ遷移を実装できます。

https://qiita.com/ryo_mm2d/items/2826037e1a0b6bed8213

ただ、これだけではページそのものに細工することしかできません。
例えば、2ページ目がかぶってくるように変更した場合は、以下のようにページ境界にドロップシャドウぐらい入れたくなりますよね。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/64e3548d-5e16-02fb-dd1f-c5a2e0670cee.gif)

この実装方法について説明します。

# PageTransformer

まずは左側のページが右側のページの上にかぶってくるような遷移をするPageTransformerを実装します。

“`kotlin
binding.viewPager.setPageTransformer { page, position ->
page.translationX =

【Flutter】ボタンの連打を無効にする対応メモ。onPressedの処理中は押せないボタンを作成する方法

## この記事でやりたいこと・紹介すること

:::note info
ボタンを押した後の処理を実行中は、ボタンを押せないようにするボタンを作成して、ユーザーが連打や実行中に比較的短い時間内でボタンを再度タップする動作等をしても二重で処理が発生しないようにする
:::

## 実施した概要
ボタンクラスのラッパークラスを作成して、処理中はボタンの”onPressed”パラメータにNullを渡すことでタップ動作を無効にする。

:::note info
上記の実装をすることで、容易に連打防止対応をしたボタンをコード全体で簡単に何度も使用することができます。
:::

## 実際の方法とソースコード

実際の導入方法を紹介します。

### ボタンクラスのラッパークラスを作成

ボタンクラスのラッパークラスである`WaitableElevatedButton`クラスと`WaitableOutlinedButton`クラスを作成

以下のファイルを任意の場所に作成します。

:::note info
私は、基本的にUtilディレクトリ等を作成して、その配下に以下の`waitable_butt

[Android] Scroll Custom Calendar

![untitled.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3639815/e49943fa-a391-2a9d-82b3-a0f6c603b745.gif)

# *月別 カレンダー*

スクロールができるカスタムカレンダーを作成する必要があったため、研修で作成したカスタムカレンダーを参考にし、新しくカレンダーを作成しました。
スクロール時に月が変わる必要があるため、“`ViewPager2“`を活用し、“`ViewPager2“`のアダプターアイテムとして“`RecyclerView“`を入れて活用しました。


## *object*
日付関連の作業はオブジェクトを作成して実行するようにしました。

“`kotlin
object Dates {

fun generateDates(calendar: Calendar): List {

val dates = mutableListOf()

FlutterのPlatform Viewsの表示モードを整理する

## はじめに
FlutterはiOSやAndroidなど複数のプラットフォームで動作するUIフレームワークです。Flutterは独自のUIレンダリングの仕組みを持っており、基本的には各プラットフォームのネイティブUIを使用しないため、プラットフォーム間での動作の差異がほとんどないという特徴があります。

しかしながらマップやウェブビューなど、プラットフォームが提供しているUIをFlutterで表示したいことがあります。そのようなケースに対応するための仕組みが **Platform Views** です。

あるプラットフォーム上でそのプラットフォーム向けのUIを表示する(例えばiOSで`UIButton`を表示する)というのは当たり前なことです。しかし、それをFlutterで構築されたアプリの中で表示する場合、Flutterが独自にレンダリングするUIとプラットフォームのUIを同時に組み合わせて表示しなければならないことになります。

iOS/Androidにおけるそのような課題をFlutterはどのように解決しているのか?を整理する機会があったため、こちらの記事にまとめます。

:

flutterのAndroidアプリでGoogleログインする時の12500エラー

# 12500エラーが止まらない
1ヶ月半程前からFlutterでAndroidアプリの作成の練習をしていました。
練習でGoogleログインを組み込もうとしたときに良くあるらしいエラー12500に遭いました。

“`zsh:デバッグログ
PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 12500: , null)
“`

それで、調べると大体出てくるFirebaseAuthのSHA-1の登録やサポートメールの登録、build.gradleの設定を何回見てもおかしいところはない・・・。
というか、今回の場合は朝方まで組み込んでて一度動作したのを確認して寝て起きて再度動かそうとしたらこのエラーが出だしたので、そもそも間違っている気がしない・・・。

# 原因
気づけば何のことはないAndroidエミュレーターが原因だったというオチです。
コールドブートすればあっさり動きました・・・。

“`bash:コールドブート
./emulator -avd Pixel_8_AP

firebasecrashlytics settings request failed

## firebasecrashlytics settings request failed

私の解決策:動作検証している端末やエミュレータの通信状態をONにする。
※検証している端末の通信状態がOFFになっていることが原因でした。他の記事をご覧になっても初期化失敗する方は確認してみてください。

ModalBottomSheetで発生したニアミス

# はじめに
今回はModal BottomSheetを実装していて発生したニアミスを紹介していきます
### 本文
***表示切替***
ModalBottomSheetを実装するときに`rememberModalBottomSheetState`を使うと思うのですが、`show()`や`hide()`で切り替えようとするとボトムシートを置いている親のViewに対するタップが効かなくなります。
これはbackgroundを設定したりModalBottomSheetの中を見てみるとわかるのですが、`BoxWithConstraints`で`constraints.maxHeight`が設定されているため親の高さいっぱいまで見えないBottomSheetが伸びてるせいでタップが全て吸われている状態です。
そのためif文での切り替えが最適となります。
***padding***
ナビゲーションバー分の余白を開けようとして`navigationBarsPadding`のみを設定すると少しだけ余白が足りません。
これは`dragHandle`分の余白が考慮されていないため発生しています。
Bo