在来电屏幕上浮动 window
Floating window on incoming call screen
我想在有人给我打电话时显示一些信息。
我有服务此服务已注册广播接收器。此接收器侦听 android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED。
当我的 phone 解锁时,我可以显示 toast,但是当我锁定 phone 并且有人呼唤我时,不会显示 toast。
当有人给我打电话时显示一些信息的最佳方式是什么?
更新:
我创建了浮动 window,当 phone 响起时我会打开它。
这工作得很好,但是当 phone 被锁定并且有人打电话给我时 window 没有显示。当我接起电话时,浮动 window 就在那里。这里有什么方法可以在锁屏来电屏幕上显示这个浮动 window 吗?
这就是我打开浮动 window:
的方式
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startService(new Intent(context, FloatingWindow.class));
}
}, 2000);
这是我的漂浮物window
public class FloatingWindow extends Service{
private WindowManager wm;
private LinearLayout ll;
private Button btnStop;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
ll = new LinearLayout(this);
btnStop = new Button(this);
ViewGroup.LayoutParams btnParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
btnStop.setText("Stop");
btnStop.setLayoutParams(btnParameters);
LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
ll.setBackgroundColor(Color.argb(66, 255, 0, 0));
ll.setLayoutParams(llParameters);
final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(400, 150, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
parameters.x = 0;
parameters.y = 0;
parameters.gravity = Gravity.CENTER | Gravity.CENTER;
ll.addView(btnStop);
wm.addView(ll, parameters);
ll.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams updatedParameters = parameters;
int x, y;
float touchedX, touchedY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = updatedParameters.x;
y = updatedParameters.y;
touchedX = event.getRawX();
touchedY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
updatedParameters.x = (int) (x + (event.getRawX() - touchedX));
updatedParameters.y = (int) (y + (event.getRawY() - touchedY));
wm.updateViewLayout(ll, updatedParameters);
break;
default:
break;
}
return false;
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wm.removeView(ll);
stopSelf();
}
});
}
}
好的,所以我一年前就解决了,但是还没有人写这个问题,所以我给出我的解决方案。
这是我打开浮动的方式window:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
context.startService(new Intent(context, FloatingWindow.class));
}
}, 1000);
在这里,来自我的 FloatingWindow 服务的 onCreate
@Override
public void onCreate() {
super.onCreate();
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
ll = new LinearLayout(this);
btnStop = new Button(this);
gestureDetector = new GestureDetector(this, new GestureListener());
ViewGroup.LayoutParams btnParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
btnStop.setText("X");
btnStop.setLayoutParams(btnParameters);
ViewGroup.LayoutParams tvParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
ll.setBackgroundColor(Color.argb(255, 255, 0, 0));
ll.setLayoutParams(llParameters);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
View popup_view = ((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.popup_window, ll, false);
tvInfo = (TextView) popup_view.findViewById(R.id.message);
tvInfo.setText(this.getMessage());
ll.addView(popup_view);
wm.addView(ll, params);
ll.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams updatedParameters = params;
int x, y;
float touchedX, touchedY;
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = updatedParameters.x;
y = updatedParameters.y;
touchedX = event.getRawX();
touchedY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
updatedParameters.x = (int) (x + (event.getRawX() - touchedX));
updatedParameters.y = (int) (y + (event.getRawY() - touchedY));
wm.updateViewLayout(ll, updatedParameters);
break;
default:
break;
}
return false;
}
});
gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
stopSelf();
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
});
}
即使在锁定屏幕上也能完美运行。
我想在有人给我打电话时显示一些信息。 我有服务此服务已注册广播接收器。此接收器侦听 android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED。 当我的 phone 解锁时,我可以显示 toast,但是当我锁定 phone 并且有人呼唤我时,不会显示 toast。 当有人给我打电话时显示一些信息的最佳方式是什么?
更新: 我创建了浮动 window,当 phone 响起时我会打开它。 这工作得很好,但是当 phone 被锁定并且有人打电话给我时 window 没有显示。当我接起电话时,浮动 window 就在那里。这里有什么方法可以在锁屏来电屏幕上显示这个浮动 window 吗? 这就是我打开浮动 window:
的方式new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startService(new Intent(context, FloatingWindow.class));
}
}, 2000);
这是我的漂浮物window
public class FloatingWindow extends Service{
private WindowManager wm;
private LinearLayout ll;
private Button btnStop;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
ll = new LinearLayout(this);
btnStop = new Button(this);
ViewGroup.LayoutParams btnParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
btnStop.setText("Stop");
btnStop.setLayoutParams(btnParameters);
LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
ll.setBackgroundColor(Color.argb(66, 255, 0, 0));
ll.setLayoutParams(llParameters);
final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(400, 150, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
parameters.x = 0;
parameters.y = 0;
parameters.gravity = Gravity.CENTER | Gravity.CENTER;
ll.addView(btnStop);
wm.addView(ll, parameters);
ll.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams updatedParameters = parameters;
int x, y;
float touchedX, touchedY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = updatedParameters.x;
y = updatedParameters.y;
touchedX = event.getRawX();
touchedY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
updatedParameters.x = (int) (x + (event.getRawX() - touchedX));
updatedParameters.y = (int) (y + (event.getRawY() - touchedY));
wm.updateViewLayout(ll, updatedParameters);
break;
default:
break;
}
return false;
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wm.removeView(ll);
stopSelf();
}
});
}
}
好的,所以我一年前就解决了,但是还没有人写这个问题,所以我给出我的解决方案。
这是我打开浮动的方式window:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
context.startService(new Intent(context, FloatingWindow.class));
}
}, 1000);
在这里,来自我的 FloatingWindow 服务的 onCreate
@Override
public void onCreate() {
super.onCreate();
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
ll = new LinearLayout(this);
btnStop = new Button(this);
gestureDetector = new GestureDetector(this, new GestureListener());
ViewGroup.LayoutParams btnParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
btnStop.setText("X");
btnStop.setLayoutParams(btnParameters);
ViewGroup.LayoutParams tvParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams llParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
ll.setBackgroundColor(Color.argb(255, 255, 0, 0));
ll.setLayoutParams(llParameters);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
View popup_view = ((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.popup_window, ll, false);
tvInfo = (TextView) popup_view.findViewById(R.id.message);
tvInfo.setText(this.getMessage());
ll.addView(popup_view);
wm.addView(ll, params);
ll.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams updatedParameters = params;
int x, y;
float touchedX, touchedY;
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = updatedParameters.x;
y = updatedParameters.y;
touchedX = event.getRawX();
touchedY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
updatedParameters.x = (int) (x + (event.getRawX() - touchedX));
updatedParameters.y = (int) (y + (event.getRawY() - touchedY));
wm.updateViewLayout(ll, updatedParameters);
break;
default:
break;
}
return false;
}
});
gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
stopSelf();
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
});
}
即使在锁定屏幕上也能完美运行。