-
Notifications
You must be signed in to change notification settings - Fork 3
/
OverlayService.java
99 lines (87 loc) · 3.29 KB
/
OverlayService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package jp.dip.sugarhouse.lockscreenoverlay;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
/**
* Activityに関係無くViewを表示し続けるためのサービス。<br>
* サービスがスタートするとWindowManagerを使ってViewをほぼ最前面に表示させる。サービスが終了する時にViewをきちんと後始末することも忘れない。
* Activityとして作ってしまうと、Activityのライフサイクルに従わなければならない為に期待通りの動作をさせるのが面倒くさい。たぶんできない。
* @author YukiAsu
*/
public class OverlayService extends Service {
/** {@link Binder}。{@link #onBind(Intent)}の戻り値が{@link IBinder}なのでIBinderになってる。中身は{@link Binder}のextends */
public final IBinder mBinder = new OverlayServiceBinder();
/** ViewをActivityに関係なく画面に放り込むためのWindowManager */
private WindowManager wm;
/** じっさいに画面に表示されるView */
private FrameLayout view;
/** Viewのパラメータ。これによってロック画面の上に鎮座させる */
private WindowManager.LayoutParams params;
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate(){
// WindowManagerを取得して、xmlから簡素なViewを生成して、Viewの属性も準備しておく
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
LayoutInflater layoutInflater = LayoutInflater.from(this);
this.view = new FrameLayout(getApplicationContext());
((FrameLayout)this.view).addView(layoutInflater.inflate(R.layout.overlay, null));
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // ロック画面より上にくる
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | // タッチイベントを拾わない。ロック画面を邪魔しない。
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, // フォーカスされない。ハードキーで選ぼうとかしても、無理。
PixelFormat.TRANSLUCENT); // ウィンドウの透明化
wm.addView(view, params);
}
/**
* 表示するViewのresourceIDを指定する
* @param resource 表示させたいresource
*/
public void setView(int resource){
view.removeAllViews();
LayoutInflater layoutInflater = LayoutInflater.from(this);
this.view.addView(layoutInflater.inflate(R.layout.overlay, null));
}
/**
* 表示するViewを直接指定する
* @param view 表示させたいView
*/
public void setView(View view){
this.view.removeAllViews();
this.view.addView(view);
}
/**
* サービスの起動時に呼び出される。Viewを表示するだけ。
*/
@Override
public void onStart(Intent intent, int startId) {
}
/**
* サービスの終了時に呼び出される。Viewをきちんと消して死ぬ。
*/
@Override
public void onDestroy() {
wm.removeView(view);
}
/**
* bindするための橋渡し、{@link Binder}<br>
* コレを介して自分自身を渡してあげる事で、Serviceのpublicメソッドが使用できるようになります。
*/
public class OverlayServiceBinder extends Binder {
OverlayService getService() {
// クライアントがpublicメソッドを呼び出せるように、自分自身のインスタンスを返す。
return OverlayService.this;
}
}
}