Edge-to-Edgeを無効化する

2025年9月21日

開発環境
OS:Windows 11
SDK:Android Studio Narwhal Feature Drop | 2025.1.2

概要

Android15以降、強制的に適用されてしまうEdge-to-Edge。
ステータスバーやナビゲーションバーなどシステムバー付近にボタンを配置している場合、調整が必要になります。

Edge-to-Edge

アプリユーザーの没入感を高めるため、Android 15以降、アプリに強制的に適用されるようになったのがEdge-to-Edge。

この機能によってスタータスバーやナビゲーションバーなどのシステムバーが透過となり、その裏までアプリが表示できるようになりました。

詳細はこちらを参照ください。

その弊害

しかしながら、全てのアプリでEdge-to-Edgeが歓迎されるかと言うとそうではなく、Edge-to-Edgeが適用された結果、システムバーがUIの邪魔になるケースが発生。

まさに自作アプリ「サムズアップ?」がそうで

ステータスバーとボタンが重なり、ナビゲーションバーと広告が重なるという惨状・・・
せっかくならUIの調整を行い、Edge-to-Egdeを有効に生かしたいところですが、ちょっとUIを調整する暇はない、ということでEdge-to-Edgeを無効化することにしました。

Style.xmlで無効化する

Edge-to-Edgeを無効化するにはStyle.xmlのスタイル定義に1行追加するだけです。

 <item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>

そして、動作確認してみた結果がこちら。

ボタン、広告ともにシステムバーと重ならないようになりました!

結局、使いどころは・・・

アプリ「サムズアップ?」においてはEdge-to-Edgeの使いどころはなさそうでした。

Edge-to-Edgeを前提に画面構成を考えるって意外と難しい。。。

全ての画面にEdge-to-Edgeを効かせる、というよりピンポイントで適用させるようなスタイルの使い分けがベターなのかもしれませんね。

今後、アプリを自作するときはそのあたりも考慮したいと思いました。

それでは以上です。

お疲れさまでした。

多言語化におけるインドネシア語の対応について

2025年8月17日

開発環境
OS:Windows 11
SDK:Android Studio Narwhal Feature Drop | 2025.1.2

概要

多言語化としてインドネシア語に対応したつもりでいたら、対応できていませんでした・・・

アプリをインドネシア語に対応させてみる

配信中の投稿系アプリ「 みてみて 」がインドネシアで伸びているということでインドネシア語に対応しようと思い、2か国語(日本語、英語)対応済みのアプリにインドネシア語の追加対応を行いました。

多言語化対応

多言語化の対応は簡単でリソースフォルダ(res)配下に対応したい言語のフォルダを作成した後、すでに格納されている文字列定義ファイル(string.xml)をそのフォルダに複製し、対応言語で定義しなおすだけです。(定義が多いと翻訳が大変ですが)

※アプリで表示する文字列をstring.xmlで一括管理している前提の話です。

2か国語の対応では、英語をデフォルト言語とするためフォルダ「values」に英語の定義ファイル(string.xml)を格納し、フォルダ「values-ja」を新たに作成し、日本語の定義ファイル(string.xml)を格納しました。

新たにインドネシア語に対応するには、フォルダ「values-id」を作成し、このフォルダにインドネシア語に変換した定義ファイル(string.xml)を格納するだけです。

新規に作成するフォルダ名は「values」とIOS639-1に準拠した言語コードをハイフン(-)で連結すればよいということでインドネシア語の言語コード「id」を連結し、「values-id」としました。

これで対応完了、ということでそのままリリース。

新たな機能を追加するつもりが・・・

それからしばらくして新たな機能を追加するために下調べでネット検索を行ったら、思わぬ情報が目に入りました。

えっ、インドネシア語のリソースフォルダは「values-in」・・・

慌ててスマホの言語設定をインドネシア語に切り替えてアプリを立ち上げてみると。

インドネシア語は表示されず、英語のままでした。。。

インドネシア語フォルダ修正

インドネシア語の定義ファイルを格納したフォルダの名前を「values-id」→「values-in」に変更します。

そして、スマホの言語設定をインドネシア語にして検証。

インドネシア語が表示されたことを確認してリリース。

ようやくインドネシア語に対応できました。

それにしても、なぜ?

インドネシア語の言語コードを確かめる

対応言語のPlayConsoleヘルプで確認した結果、インドネシア語の言語コードは、「id / in」となっていました。

これはつまり・・・

どういうこと?

少なくともXperia(SO-53C)でシステム言語をインドネシア語に切り替えて、アプリの表示を確認すると「values-id」ではデフォルト(英語)になり、「values-in」で定義したインドネシア語が表示される結果となりました。

対応するならば、
インドネシア語としては、「id」と「in」、2つの定義を共存させておくのがベターな対応かもしれません。

そして反省・・・

リリースするときはしっかり検証しましょう。。。

お疲れさまでした。

com.google.android.play.coreの警告に対処する

2024年7月15日

開発環境
OS:Windows 11
SDK:Android Studio Iguana | 2023.2.1 Patch 1

概要

Google Play Consoleの受信トレイにcom.google.android.playに関する警告がきており、8月31日までに対処が必要とのことで対応しました。

警告を確認する

Google Play Consoleの受信トレイにcom.google.android.playに関する警告が届きました。

警告の内容を確認すると、

com.google.android.play.core(1.8.0)がAndroid 14(sdk 34)に対応できなくてアプリがクラッシュするため、それを回避するために8月31日までにライブラリの参照を変更しなさい。

とのことのようです。

com.google.android.play.coreって何に使ってたんだろうか?

com.google.android.play.coreの使用状況を確かめる

まずは警告が届いたアプリのソースコードを確認します。

Android Studioで立ち上げ、「com.google.android.play」で検索してみると・・・

検索の結果、In-App Reviewのモジュールがヒットしました。

import com.google.android.play.core.review.ReviewManagerFactory
import com.google.android.play.core.review.ReviewManager

build.gradleのライブラリを確認すると

今回の警告対象である「com.google.android.play:core-kt」が見つかりました。

 dependencies {

    implementation("com.google.android.play:core-ktx:1.8.1")

}

「com.google.android.play:core-kt」を削除してビルドしなおしてみるとReviewManagerのインポートで参照エラーがでました。

「com.google.android.play:core-kt」の代替ライブラリが必要のようです。

ライブラリを差し替える

改めてIn-App Reviewの実装方法を公式サイトで確認するとライブラリが変わっていました。

 dependencies {

    implementation 'com.google.android.play:review-ktx:2.0.1'

}

ということで「com.google.android.play:core-ktx」を「com.google.android.play:review-ktx」に変更し、ビルドしてみると・・・

これで警告の対応が完了です。

お疲れさまでした。

アプリにIn-App Reviewを組み込む

2024年7月15日

開発環境
OS:Windows 11
SDK:Android Studio Iguana | 2023.2.1 Patch 1

概要

AndroidアプリにIn-App Reviewを組み込みます。

In-App Review

In-App Reviewとはアプリの評価やレビューの入力を促すポップアップ機能です。

アプリの操作中に意図したタイミングでポップアップさせることができます。

アプリの評価やレビューはアプリの改善に役に立つため、In-App Reviewの実装はおススメです。

In-App Review実装の流れ

実装していきます。

まずはbuild.gradleにライブラリを組み込みます。

 dependencies {

    implementation 'com.google.android.play:review-ktx:2.0.1'

}

次に必要なモジュールをインポートします。

import com.google.android.play.core.review.ReviewManagerFactory
import com.google.android.play.core.review.ReviewManager

Activityの起動時にレビューマネージャーを生成します。

    private lateinit var reviewmanager : ReviewManager

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

        reviewmanager = ReviewManagerFactory.create(this)

    }

あとは適当な場所(画面起動時やイベント終了後など)でポップアップ処理をコールします。

    val request = reviewmanager.requestReviewFlow()
    request.addOnCompleteListener { task ->
        if (task.isSuccessful) {
            val reviewInfo = task.result
            val flow = reviewmanager.launchReviewFlow(this@MapsActivity, reviewInfo)
            flow.addOnCompleteListener { _ ->

            }
        }
    }

In-App Reivewの実装は以上です。

デバッグ方法

デバッグをしたい場合、FakeReviewManagerを使用します。

FakeReviewManagerをインポートします。

import com.google.android.play.core.review.ReviewManagerFactory
import com.google.android.play.core.review.ReviewManager
import com.google.android.play.core.review.testing.FakeReviewManager

FakeReviewManagerを生成します。

    private lateinit var reviewmanager : ReviewManager

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

//        reviewmanager = ReviewManagerFactory.create(this)
        reviewmanager = FakeReviewManager(this)

    }

ポップアップ処理は変更不要です。

FakeReviewManagerのデバッグではポップアップは表示されず、正常系のシーケンスのみ確認できます。

ステップ実行してみるとrequestReviewFlowに成功し、launchReviewFlowがコンプリートします。

これでIn-App Reviewの組み込みは終了です。

お疲れさまでした。

SHA-1証明書のフィンガープリントを確認する

2023年10月18日

開発環境
OS:Windows 11
SDK:Android Studio Flamingo | 2022.2.1

概要

GCPなどを利用する際に登録が必要となるSHA-1証明書のフィンガープリント。
フィンガープリントの確認の方法を記載します。

デバッグアプリのフィンガープリント

デバッグモードで作成したAndroidアプリのフィンガープリントは同じ開発環境(同一PC内のAndroid Studio)で作成する場合、全てのアプリで共通の値となります。

デバッグアプリのフィンガープリントを確認するには、下記コマンドを実行します。

keytool -keystore path-to-debug-or-production-keystore -list -v

keytoolの実体は、C:\Program Files\Android\Android Studio\jbr\bin\keytool.exeです。

環境変数のパスに「C:\Program Files\Android\Android Studio\jbr\bin」を追加するか、

C:\Program Files\Android\Android Studio\jbr\binのフォルダに移動した後、コマンドを実行する必要があります。

また、path-to-debug-or-production-keystoreは、keystoreのパスです。

通常は下記のように.androidフォルダ内に格納されています

C:\xxxxx\.android\debug.keystore

コマンドを実行すると下記のようになり、フィンガープリントが表示されます。

キーストアのパスワードを聞かれますが、何も入力せずエンターキー押下で出力されました。

リリースアプリのフィンガープリント

リリースアプリの場合はGoogle Play Consoleから確認できます。

まずは確認したいアプリを選択し、タブから設定の「アプリの署名」を選択。

アプリ署名鍵の証明書から確認することができます。

デバッグ用フォルダ

Admob広告ユニットIDをデバッグとリリースで使い分ける

2023年1月23日

開発環境
OS:Windows 10
SDK:Android Studio Dolphin | 2021.3.1

概要

Admobから与えられたアプリID、広告ユニットIDをデバッグモードで使用してしまうとAdmobから警告を来て、収益に影響が出てしまいます。
そうならないためにもリリースとデバッグモードで広告ユニットIDを分けて定義しておくと便利です。

Admobを表示するときに必要となるID

Admobをアプリに表示させるにはアプリIDと広告ユニットID、少なくとも2つのIDを定義する必要があります。

アプリID、広告ユニットIDはAdmobで作成することができますが、

アプリのデバッグ時に使用することはできません。

代わりにデバッグ時にはサンプルIDを使用します。

【 サンプルアプリID 】

ca-app-pub-3940256099942544~3347511713

サンプル広告ユニットID

広告フォーマットサンプル広告ユニットID
アプリ起動ca-app-pub-3940256099942544/3419835294
バナーca-app-pub-3940256099942544/6300978111
インタースティシャルca-app-pub-3940256099942544/1033173712
インタースティシャル動画ca-app-pub-3940256099942544/8691691433
報酬型ca-app-pub-3940256099942544/5224354917
報酬型インタースティシャルca-app-pub-3940256099942544/5354046379
ネイティブアドバンスca-app-pub-3940256099942544/5354046379
ネイティブアドバンス動画ca-app-pub-3940256099942544/1044960115
サンプル広告ユニットID一覧

デバッグ用定義とリリース用定義

アプリIDと広告ユニットIDはstring.xmlに定義して管理します。

まずリリース用のアプリID、広告ユニットIDをstring.xmlに定義します。
(下3行がID定義となります。)

<resources>
    <string name="app_name">Look Look</string>
  ・・・
  ・・・
  ・・・
    <string name="ts_adview">Advertisement will be displayed from now on.</string>
    <string name="ad_attribution">Ad</string>
    <!-- admob -->
    <string name="admob_id_manifest">ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx</string>
    <string name="admob_id_bottom_main">ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx</string>
    <string name="admob_id_bottom_map">ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx</string>
</resources>

次にデバッグ用のアプリID、広告ユニットIDをstring.xmlに定義します。

デバッグ用のstring.xmlは最初は存在しないため、新たにデバッグ用フォルダ内に作成します。

【 デバッグ用フォルダの場所 】

(プロジェクトフォルダ)/app/src/debug/res/values/string.xml

※フォルダがない場合はフォルダも作成します。

※多言語化対応している場合は言語毎のvaluesフォルダ(例えば日本語の場合、values-ja
 フォルダ)にstring.xmlを格納します。
 string.xmlの定義内容は全て同じで問題ありません。

デバッグ用フォルダ
<resources>
    <!-- admob -->
    <string name="admob_id_manifest">ca-app-pub-3940256099942544~3347511713</string>
    <string name="admob_id_bottom_main">ca-app-pub-3940256099942544/6300978111</string>
    <string name="admob_id_bottom_map">ca-app-pub-3940256099942544/6300978111</string>
</resources>

string.xmlには、AdmobのサンプルIDだけ定義すればOKです。

アプリID、広告ユニットIDを参照する

あとはstring定義を参照するだけです。

(AdroidManifestの定義例)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  ・・・
    <application
  ・・・
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="@string/admob_id_manifest" />
  ・・・
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:theme="@style/AppTheme.NoTitleMain">
  ・・・
       </activity>
  ・・・  
    </application>
</manifest>

(レイアウトXMLの定義例)

<?xml version="1.0" encoding="utf-8"?>
<ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapsActivity">


    <com.google.android.gms.ads.AdView
        android:id="@+id/adViewMap"
        ads:adSize="SMART_BANNER"
        ads:adUnitId="@string/admob_id_bottom_map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="0dp">
    </com.google.android.gms.ads.AdView>
</androidx.constraintlayout.widget.ConstraintLayoutt>

これでデバッグとリリースの使い分けができるようになりました。

いつも通りにデバッグを行えばサンプルIDが参照され、リリースアプリの作成を行えば、リリース用IDが参照されるようになります。

アプリのタイトルに☆を付けたらGoogle Playから削除されてしまった話

2023年1月15日

開発環境
OS:Windows 10
SDK:Android Studio Dolphin | 2021.3.1

一難去ってまた一難

ピートークという、Wi-Fi Directチャットアプリがポリシー違反と指摘され、

指摘から9日後の昨年12月30日に改修を行い、リリース。

改修方針は的を得ていたようでポリシー違反が解除されました!

と思ったのも束の間。

またしてもポリシー違反を指摘されてしまいました。。。

前回のポリシー違反、及び、対処方法は下記をご覧ください。

今回の指摘内容が以下。

メタデータポリシーに違反したとのこと。

そして、アプリステータスは、ストア削除。

なんということでしょう。。。

アプリタイトルに☆を付けてはいけない

メタデータポリシーとはなにか?

メール内のリンクを見るにユーザーに誤解を与えるようなテキストや画像に関する制限のようです。

そして、その制限の一つとして「絵文字、顔文字、特殊文字の使用」がありました。


前回のポリシー違反を修正する際にきまぐれにアプリタイトルを「ピートーク」から「ピー☆トーク」に変更したのがダメだったようです。

改修方針

アプリタイトル、及び、ストアのアプリ名から☆を削除します。

改修のその後

改修アプリをリリースした翌日にはポリシー違反は解除されていました。

今回のポリシー違反は明確でしたね。

Pトーク、アプリ内エクスペリエンスに反するってよ

ポリシー違反にざわつく日曜日

久々にポリシー違反メールを受け取ってしまいました。

とは言うものの、

ポリシー違反を指摘をされたアプリの最終更新日は、2022年6月3日。

しばらく違反状態だったようです。。。

それはさておき、指摘内容は何かと言うとこちら。

ポリシー違反メール

そして、これが証拠画像だと添付されていた画像がこちらです。

添付画像を見ても違反らしいものは見えないのですが・・・

アプリ内エクスペリエンス

アプリ内エクスペリエンス、初めての指摘内容です。
(過去に指摘されたものは水平展開しているので同じ指摘をされると困るわけですが。。。

今回指摘されたアプリ内エクスペリエンスを解釈してみるに、

「ユーザー作成コンテンツ」の表示やアクセスができるアプリなのに

ユーザー作成コンテンツに関するポリシーが適用されていないよね?

ってことのようです。

Pトークとはざっくりと言えば、Wi-Fi Directを使ったチャットアプリです。

「アプリ内エクスペリエンス」を考慮しつつ、アプリを動かしてみると

確かに「データを相互に交換できること」に対する考慮が足りてないようです。

改修方針

ユーザー作成コンテンツに関するポリシーの遵守のため、

下記の対策をとります。

・アプリの利用規約の定義

・利用規約の同意画面を表示し、同意しない場合はアプリの使用を遮断する(←添付画像は今、これがないよねという指摘と捉えたが果たして。。。

それでは改修を行い、申請は通るのか。

結果が出たらまた記事にしようかと思います。

追記

ポリシー違反メール受信から5日後、Admob停止の通知がきました。。。

ジェスチャーナビゲーションを一時的に無効化する

2022年10月14日

開発環境
OS:Windows 10
SDK:Android Studio Dolphin | 2021.3.1

概要

Android 10から実装されたジェスチャーナビゲーション。

この機能とDrawerLayoutとの相性が悪いので一時的に無効化します。

ジェスチャーナビゲーションを初めて知る

Android 13のサポート対応のため、伊勢125社巡りをデバッグしていたときのこと。

Android 13の仮想デバイスを用意し、マップ画面を確認していた際に違和感が。

マップ画面は、DrawerLayoutで構成しており、画面左右にNagivationViewをセット。

画面左端から右へスワイプ、または、画面右端から左へスワイプするとメニューが表示される作りになっています。

その想定で画面左端から右へスワイプした結果、画面左端に下記のような矢印(<)が表示されました。

そして、次の瞬間、マップ画面が閉じて、ホーム画面が表示されました。

えっ。。。

戸惑います。

もう1度、同じ操作をしてもやはりホーム画面に戻されます。

そこでネットで調べたところ、ジェスチャーナビゲーションが機能していたことが判明しました。

このとき、初めてジェスチャーナビゲーションの存在を知りました。。。

ジェスチャーナビゲーションを無効化する

このジェスチャーナビゲーション。

有効な状態だとマップ画面でスワイプ操作によるメニュー表示ができません。

そこで、マップ画面表示中だけ無効化するようにします。

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


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val layoutMap = findViewById<DrawerLayout>(R.id.layout_map)
        val rect = Rect(0 , 100, 100, 200)
        layoutMap.systemGestureExclusionRects = listOf(rect)
    }

}

ロジックはいたって簡単。

マップ画面のDrawerLayoutでsystemGestureExclusionRectsをコールし、ジェスチャーを無効化するエリアを指定すればいいだけです。

(念のため、Android 10(APIレベル29)以降でのみ動作するようにしています。

そして、再度、デバッグしてみると。

画面左端から右スワイプするとメニューが表示されるようになりました。

ジェスチャーナビゲーション

設定画面の「システム」ー「ジェスチャー」ー「システムナビゲーション」から設定できます。

機能を有効化すると画面端あたりをスワイプすると戻る操作となるようです。

Android13対応ついでに最小APIレベルを確認する

2022年8月22日

開発環境
OS:Windows 10
SDK:Android Studio Chipmunk | 2021.2.1

概要

いよいよAndroid13がリリースされ、APIレベルも33に。
アプリのターゲットAPIレベルを33に上げていくなかで最小APIレベルをどうするか?
デバイスのインストール状況を確認して決めようかと思います。

APIレベルを33にする

Android13がリリースされたのに伴い、今後、アプリの改修を行う際にはAPIレベル33に適用させていこうと思っています。

android {
    compileSdkVersion 33
    defaultConfig {
        
        minSdkVersion 24
        targetSdkVersion 33
  
    }

}

そんななか、ターゲットAPIレベルを上げるからには合わせてサポート対象の最小APIレベルも上げておきたいところです。

そこでGoogle Play Consoleを使い、実際にインストールされているAndroidバージョンの割合を確認して最小APIレベルの底上げの判断をします。

APIレベルを確認する

アプリのバージョン別普及率を確認します。

まずはGoogle Play Consoleで対象アプリのダッシュボードを表示します。

メニューから「リーチとデバイス」の「概要」を選択します。

Google Play Console

ユーザーと問題の分布/Androidバージョンが表示されるので「探す」をクリック。

Google Play Console

インストール上位バージョンが表示されます。

インストールされているバージョンを全て確認するために「+Androidバージョン」をクリック。

Google Play Console

これで全てのインストールバージョンが表示されます。

こうして見てみるとアプリ「伊勢125社巡り」はいまだにAndroid7.0が1台いらっしゃるようです。

たぶんにアプリをインストールしたままでスマホを廃棄されたのでは、と思うのですが、念のため、アプリ内でサポート切れ告知をしたあと、最小レベルを28まで上げようかと思います。

(Android 8.0の1台は私物のデバッグ機、のはず。

APIレベルについてはこちらでも確認できます。