[Android & Kotlin] アプリの上に重ねて画像を表示

他のアプリ画面上にアイコン画像などを表示させることが、ServiceとWindowManagerを組み合わせるとできます。
 
1x1.trans - [Android & Kotlin] アプリの上に重ねて画像を表示


Android Studio
2021.2.1

 




SYSTEM_ALERT_WINDOW

 

通常、別のアプリが起動すると、当初あったアプリはバックグラウンドに移動させられてしまいます。ここではそのバックグラウンドから画像を表示させて、後から起動したアプリの上にかぶせてみようというものです。
 
Serviceなので確かにバックグラウンドで長期間のタスクを実行してくれますが、システムがユーザーに電池を消費していると知らせたりしますので、アプリをアンインストールされないように注意しましょう。

このアプリを作成するうえで仕様変更が続いています

 

 

Settings.canDrawOverlays()

 

Settings.canDrawOverlays() からアプリに重ねて表示することが許可されているかを確認

 
システム権限の「他のアプリに重ねて表示を許可」を尋ねる表示が出てきます。
面倒な操作が増えましたが、権限を付与する際の意識を高めることで
ユーザーを保護するのが目的だそうです

アプリ一覧から当該アプリを選択
 
1x1.trans - [Android & Kotlin] アプリの上に重ねて画像を表示

許可を与える

1x1.trans - [Android & Kotlin] アプリの上に重ねて画像を表示

許可した後は、バック2回でアプリ画面戻ります
AppOpsManagerを使うと1回にできるなど工夫はあるようです

 

TYPE_APPLICATION_OVERLAY

 

API level 26まではいくつかのレイヤーが使えたのですが、残念ながら使用することは非推奨となりました。代わりにTYPE_APPLICATION_OVERLAYを使います。これは通常のアプリの上に表示できますが、設定画面などはできません

レイヤー表示はWindowManager.LayoutParamsを使って設定していきます。

レイヤータイプとflagsは様々ありますのでWindowManager.LayoutParams Referenceを確認してください。

 

サンプルコード

 

常時表示するアプリとするためにServiceの startService() あるいは startForegroundService() を使い、画像としてImageViewのアイコン(少々大きめですが)にしました。

service 00 100x100 - [Android & Kotlin] アプリの上に重ねて画像を表示
Servce はバックグラウンドで作業をさせたい場合に使います。システムは直ぐにスリープに入れてしまいます。それでも裏で色々やりたい場合に有...

また、startしたServiceは停止させるようにしておかないとトラブルになりますので、この常駐アイコンをタッチすることにより停止できるようにします。

 
MainActivity.kt

 
Serviceが呼ばれたら、WindowManagerにViewを追加して表示させます。
TestService.kt

マニュフェストには、

  • FOREGROUND_SERVICE のPermissionをAndroidManifestに記述
  • SYSTEM_ALERT_WINDOWのPermissionの設定
  • Serviceクラスの記述

AndroidManifest.xml

 

 
MainActivityのレイアウトでは、サービスを起動するだけのボタンをとりあえずつくっておきます
activity_main.xml

 
アプリ上に表示する画像を(ここでは umbrella.png)をdrawableに入れて、OverlayするViewのレイアウトを作成します。

今回はテストのためちょっと大きめの画像を張り付けてみます。

service_layer.xml

 
strings.xml

Permissionを許可した後に、Serviceをスタートすると画像が表示されて、他のレイヤーの上位にいることがわかります。
 
1x1.trans - [Android & Kotlin] アプリの上に重ねて画像を表示


 
 
 
関連ページ:

 

References:
WindowManager.LayoutParams
SYSTEM_ALERT_WINDOW
ACTION_MANAGE_OVERLAY_PERMISSION
canDrawOverlays(android.content.Context)
 

シェアする

  • このエントリーをはてなブックマークに追加

フォローする