Serviceを利用した、フローティングアプリのテスト


2014年4月11日現在、私が理解している内容です。
間違っている場合があります。


Serviceを利用した、画面に浮遊するフローティングアプリのテスト

フローティングアプリとは、android画面に浮いている小さい画面のアプリのことです。
ノンモーダルダイアログという言い方もあります。
アプリが表示・実行されつつ、他のアプリも操作できるという便利なものです。

Serviceというものを使いますと、そういう便利なしくみが利用できるというわけです。

というわけで、さわりだけテストしてみました。

アクティビティの画面遷移のこととか」のコードを改造しています。




AndroidManifest.xmlの確認

サービスの利用には、AndroidManifest.xmlに、次の記述が必要になります。
アラートウィンドウを利用する設定と、
Activity_Sub1をサービスとして使う設定。


<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <service android:name="Activity_Sub1"/>



<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.test02" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.test02.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="Activity_Sub1"/> </application> </manifest>


前回まで必要だった<activity android:label="@string/app_name" android:name=".Activity_Sub1"/>は、削除してかまいません。
半透明指定も、無くて構いません。




フローティングアプリのテスト


「OPEN」ボタンを押すと、赤いウィンドウのActivity_Sub1画面が出てきます。
「CLOSE」ボタンで、Activity_Sub1画面が消えます。
「END」ボタンで終了しますが、赤いウィンドウのActivity_Sub1画面が出ているままだと、そのまま出たままです。
他のアプリを起動させたりできます。


ちなみに、android2.3.3のエミュレータでは重なって見えますが、
android4.4.2のエミュレータでは、青い画面が表示された時、下の赤画面が消されるみたいですので、
重なって見えることがありません。
実際にアプリにするときは、挙動がおかしくならないように注意が必要ですね。


まだ、細かい処理はしてないので、赤いウィンドウを出したままOPENボタンを何度も押したり、
CLOSEボタンを何度も押したりするとエラーになります。
実際にアプリに組み込む時は、注意しましょう。


起動すると、「OPEN」「CLOSE」「END」の3つのボタンが出ます。



「OPEN」ボタンを押すと、赤い画面が出てきます。ウィンドウを半透明にしてるので、茶色に見えますが。
「CLOSE」ボタンを押すと消えます。



赤い画面を出したまま、「END」で終了させると、
赤い画面が表示されたままになります。



端末のメッセージより上に重なって表示されています。





Activity_Sub1.java

package com.example.test02; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.PixelFormat; import android.os.IBinder; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.Button; import android.widget.LinearLayout; public class Activity_Sub1 extends Service { WindowManager windowManager; //ウィンドウマネージャーのデータを格納 LinearLayout L_layout1; //レイアウトのデータを格納 @Override public int onStartCommand(Intent intent, int flags, int startId) { //レイアウトをつくる L_layout1 = new LinearLayout(this); //レイアウトの背景を赤にする L_layout1.setBackgroundColor(Color.argb(128, 255, 0, 0)); //ボタンをつくる Button button1 = new Button(this); //ボタンに文字を表示 button1.setText("CLOSE"); //ボタンをレイアウトに追加 L_layout1.addView(button1); //ウィンドウのパラメータを設定 WindowManager.LayoutParams params = new WindowManager.LayoutParams( 300, //横サイズ 400, //縦サイズ WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, //なるべく上の階層で表示 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | //他のアプリと端末ボタンを操作できる WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | //座標系をスクリーンに合わせる WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| //WATCH_OUTSIDE_TOUCHと同時利用で WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, //外側にタッチできる//端末ボタンが無効になる? PixelFormat.TRANSLUCENT); //透過指定 //ウィンドウマネージャーを使う windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); //ウィンドウに、レイアウトを表示 windowManager.addView(L_layout1, params); //----------------------------------------- //ボタンが押されたかどうか監視する button1.setOnClickListener( new OnClickListener() { //ボタンが押されたら何かする @Override public void onClick(View v) { //この画面を終了 onDestroy(); } }); return START_STICKY; } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); // サービスを終了するときに画面を消す windowManager.removeView(L_layout1); } @Override public IBinder onBind(Intent arg0) { // TODO 自動生成されたメソッド・スタブ return null; } }


MainActivity.java

package com.example.test02; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.app.Activity; import android.content.Intent; import android.graphics.Color; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //-------------------------------------------------- //緑のレイアウトを作る LinearLayout Red_layout1 = new LinearLayout(this); //レイアウトの背景を緑にする Red_layout1.setBackgroundColor(Color.argb(128, 0, 255, 0)); //画面にセットする setContentView(Red_layout1); //----------------------------------------- //新しいボタンを作る Button button1 = new Button(this); //ボタンに文字を表示 button1.setText("OPEN"); //ボタンをレイアウトに追加 Red_layout1.addView(button1); //新しいボタンを作る Button button2 = new Button(this); //ボタンに文字を表示 button2.setText("CLOSE"); //ボタンをレイアウトに追加 Red_layout1.addView(button2); //新しいボタンを作る Button button3 = new Button(this); //ボタンに文字を表示 button3.setText("END"); //ボタンをレイアウトに追加 Red_layout1.addView(button3); //----------------------------------------- //OPENボタンが押されたかどうか監視する button1.setOnClickListener( new OnClickListener() { //ボタンが押されたら何かする @Override public void onClick(View v) { //サービスを呼び出す startService(new Intent(MainActivity.this,Activity_Sub1.class)); } }); //----------------------------------------- //CLOSEボタンが押されたかどうか監視する button2.setOnClickListener( new OnClickListener() { //ボタンが押されたら何かする @Override public void onClick(View v) { //サービスを終了させる stopService(new Intent(MainActivity.this, Activity_Sub1.class)); } }); //----------------------------------------- //ENDボタンが押されたかどうか監視する button3.setOnClickListener( new OnClickListener() { //ボタンが押されたら何かする @Override public void onClick(View v) { //自分を終了させる finish(); } }); //----------------------------------------- } }














戻る