現在は、テストが十分ではない実験的なリリースです。多くのバグを含む可能性があります。
android(ルート権限不要)でフローティングウィンドウを実現し、片手操作に最適化したライブラリです。
よく似たフレームワークは、XperiaのSmall App APIですが、より多くの端末で動作します。
言語はKotlinを採用しています。
容易にマルチウィンドウのアプリを作成し、追加することが出来ます。 ウィンドウの操作は片手に最適化し、ウィンドウの拡大/縮小、移動は四隅の縁に対しての操作で行います。
小窓でフレームワークに実装したアプリを表示することが出来ます。 アプリ一覧やアプリ履歴はコアに含まれるランチャーから呼び出しします。 Activityから特定のマルチウィンドウアプリを呼び出したりことが出来ます。
Coreアプリ(マルチウィンドウ機能)と、フレームワーク(アプリ追加用)にモジュールが分かれています。
サンプルアプリケーションのデモ動画です
サンプルアプリケーション操作中のスクリーンショットです
-
ランチャー起動
-
アプリ一覧表示
-
サンプルのブラウザ起動
-
非アクティブ
-
ウィジェット
このフレームワークの基本的な特徴になります
- Xperiaも含め多数の端末で動作
- マルチウィンドウで動作(同じアプリを複数開ける)
- 片手操作への最適化(ウィンドウの拡大縮小、移動)
- 端末の領域外に移動しても、最小化しない
- 閉じるボタンなどの固定ボタンを廃止し、画面を広く使える(四隅のフチで操作)
- 四隅のフチはスライドするとウィンドウの移動、長押し後にスライドするとウィンドウの拡大縮小(角は近接する2辺の拡大縮小)
- 四隅のフチはダブルタップで最小化、上の角は最大化、下の角は最小化
- Kotlinで実装
非システムアプリの為、利用しているWindowManager(TYPE_SYSTEM_ALERT
、TYPE_APPLICATION_OVERLAY
)に制限があり、幾つかの機能に制約があります。
- ウィンドウが全て非アクティブになった場合、ランチャーを選択しないと復帰できない。
- コア機能を持つアプリのインストールが必須
- 「他のアプリの上に重ねて描画」の許可が必要
- layoutにincludeタグが使えない
- Android 6.0 marshmallow 以上
- マルチウィンドウ機能の利用について
- コアのインストール必須
- アプリ追加について
- フレームワーク必須
現状はαリリースのため、Coreはデバッグ向けと署名なしAPKを公開し、 FrameworkライブラリはGitPagesの仮Mavenリポジトリで公開。
-
Core
-
Framework
build.gradleに下記のリポジトリとライブラリを追加してください。
repositories { maven { url 'http://kght6123.github.io/maven-repositories/android' } } dependencies { compile 'jp.kght6123.floating.window:floating-window-framework:latest' }
-
Android
- Android Emulator 6.0〜8.0
- Galaxy Note8
-
Develop Machine
- macOS High Sierra 10.13.3
- Android Studio 3.2 Canary 7
最小限のアプリケーション実装のサンプルと解説です
-
アプリケーションのメインクラスを作成
class FloatWindowHelloApplication : FloatWindowApplication() { /** * Ankoでウィンドウのレイアウトを定義 */ class HelloUi: AnkoComponent<FloatWindowHelloApplication> { override fun createView(ui: AnkoContext<FloatWindowHelloApplication>) = with(ui) { verticalLayout { textView { text = "Hello, Floating Window!!" } } } } /** * Ankoで最小化時のアイコンのレイアウトを定義 */ class HelloMiniUi: AnkoComponent<FloatWindowHelloApplication> { override fun createView(ui: AnkoContext<FloatWindowHelloApplication>) = with(ui) { imageView { imageResource = R.mipmap.ic_launcher isFocusableInTouchMode = true isFocusable = true } } } /** * メインウィンドウのファクトリークラス(MultiFloatWindowViewFactory)を実装して返す。 */ override fun onCreateFactory(index: Int): MultiFloatWindowViewFactory { return object : MultiFloatWindowViewFactory(multiWindowContext) { /** * メインウィンドウに表示するViewを生成し、Viewにイベントや初期値を設定して返してください。 * 引数のindexは、0から始まる生成するウィンドウの一意の番号です。 */ override fun createWindowView(arg: Int): View { return HelloUi().createView(AnkoContext.Companion.create(sharedContext!!, this@FloatWindowHelloApplication, setContentView = false)) } /** * ImageViewなどを生成し、ImageViewに最小化時のアイコン画像を設定して返してください。 * アイコン画像は75dp×75dpで表示されます。 */ override fun createMinimizedView(arg: Int): View { return HelloMiniUi().createView(AnkoContext.Companion.create(sharedContext!!, this@FloatWindowHelloApplication, setContentView = false)) } /** * 起動時に設定されたIntent情報を元に、初期化する処理を実装してください。 */ override fun start(intent: Intent?) { Toast.makeText(applicationContext, "start", Toast.LENGTH_SHORT).show() } /** * 更新時に設定されたIntent情報を元に、初期化する処理を実装してください。 * positionNameはMultiWindowUpdatePositionの名称で、更新方法によって変化します。 */ override fun update(intent: Intent?, index: Int, positionName: String) { Toast.makeText(applicationContext, "update", Toast.LENGTH_SHORT).show() } /** * ウィンドウのイベント発生時に実行されるイベントメソッドです。 */ override fun onActive() { Toast.makeText(applicationContext, "onActive", Toast.LENGTH_SHORT).show() } override fun onDeActive() { Toast.makeText(applicationContext, "onDeActive", Toast.LENGTH_SHORT).show() } override fun onDeActiveAll() { Toast.makeText(applicationContext, "onDeActiveAll", Toast.LENGTH_SHORT).show() } override fun onChangeMiniMode() { Toast.makeText(applicationContext, "onChangeMiniMode", Toast.LENGTH_SHORT).show() } override fun onChangeWindowMode() { Toast.makeText(applicationContext, "onChangeWindowMode", Toast.LENGTH_SHORT).show() } } } /** * ウィンドウの初期設定クラス(MultiFloatWindowInitSettings)のコンストラクタに値を設定して返してください。 */ override fun onCreateSettingsFactory(index: Int): MultiFloatWindowSettingsFactory { return object : MultiFloatWindowSettingsFactory(multiWindowContext) { override fun createInitSettings(arg: Int): MultiFloatWindowInitSettings { return MultiFloatWindowInitSettings( width = getDimensionPixelSize(R.dimen.width),// dp単位の指定を推奨 height = getDimensionPixelSize(R.dimen.height),// dp単位の指定を推奨 theme = MultiFloatWindowConstants.Theme.Light,// `Light`または`Dark` anchor = MultiFloatWindowConstants.Anchor.Edge// `Edge`または`SinglePoint` ) } } } }
-
AndroidManifest.xmlの修正
-
manifestタグに属性を追加
android:sharedUserId="jp.kght6123"
-
uses-permissionタグ追加
<uses-permission android:name="jp.kght6123.floating.window.core.manifest.permission.APPS" />
-
serviceタグ追加
- ServiceクラスはFloatWindowApplicationクラスを継承して作成したクラスを指定
android:icon
属性を指定してください、ランチャーのアイコンになります。android:exported="true"
を追加してください
-
serviceタグ内にintent-filterを追加
<intent-filter> <action android:name="jp.kght6123.floating.window.core.intent.action.MAIN" /> <category android:name="jp.kght6123.floating.window.core.intent.category.LAUNCHER" /> </intent-filter>
-
このライブラリをクローンしてビルドする方法です。リポジトリをcloneして、AndroidStudioにインポートしてください。
ターミナルはAndroidStudioを使用しています
-
Debug、Run
- 「floating-window-core」と「floating-window-sample」モジュールをデバッグまたは実行する
-
Coreのapkを作成し、コピー
署名なしでapkを作成し、downloadフォルダにコピーします
./makeapk.sh
-
FrameworkのMavenリポジトリを作成し、Commit&Push
floating-window-framework/build.gradle
のpom.version
のバージョンで作成し、Mavenリポジトリへコミットします
./updatemaven.sh "${comment}"
Licenceに「Apache License Version 2.0」を選択しており、修正いただいた場合は「Pull Request」をお願いします。
- Fork (https://github.com/tcnksm/tool/fork)
- Create a feature branch
- Commit your changes
- Rebase your local changes against the master branch
- Run and Test
- Create new Pull Request
公開内容の詳細に関しては@kght6123まで、お気軽にお問い合わせ下さい。
Copyright (c) 2018 Hirotaka Koga