之前参照网上例子写过一个demo,实现在Activity中点击最小化按钮,将该Activity finish,并启动servie生成一个悬浮按钮,可点击也可拖拽;
最近工作需要也做一个相似的悬浮窗,悬浮按钮生成了,App被Home也能存在,不会
消失,但该悬浮按钮却没法捕获点击和拖拽事件。
这两个代码几乎一摸一样,请大神们帮忙看下是哪里出的问题,谢谢!
代码如下:
package com.example.menqi.myapplication;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
public class MyService extends Service {
private WindowManager mWindowManager;
private WindowManager.LayoutParams mLayoutParams;
/**
* float的布局view
*/
private View mFloatView;
private ViewGroup glSurfaceView;
private int mFloatWinWidth,mFloatWinHeight;//悬浮窗的宽高
//private int mFloatWinMarginTop,mFloatWinMarginRight;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
createWindowManager();
createFloatView();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
removeFloatView();
}
private void createWindowManager() {
// 取得系统窗体
mWindowManager= (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
//计算得出悬浮窗口的宽高
DisplayMetrics metric =new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(metric);
int screenWidth = metric.widthPixels;
mFloatWinWidth = screenWidth *1/3;
mFloatWinHeight=mFloatWinWidth*4/3;
//mFloatWinMarginTop= (int)this.getResources().getDimension(R.dimen.rkcloud_av_floatwin_margintop);
//mFloatWinMarginRight= (int)this.getResources().getDimension(R.dimen.rkcloud_av_floatwin_marginright);
// 窗体的布局样式
// 获取LayoutParams对象
mLayoutParams=new WindowManager.LayoutParams();
// 确定爱悬浮窗类型,表示在所有应用程序之上,但在状态栏之下
//TODO? 在android2.3以上可以使用TYPE_TOAST规避权限问题
mLayoutParams.type= WindowManager.LayoutParams.TYPE_TOAST;//TYPE_PHONE
mLayoutParams.format= PixelFormat.RGBA_8888;
mLayoutParams.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
// 悬浮窗的对齐方式
mLayoutParams.gravity= Gravity.LEFT| Gravity.TOP;
// 悬浮窗的位置
mLayoutParams.x=70;
mLayoutParams.y=210;
mLayoutParams.width=mFloatWinWidth;
mLayoutParams.height=mFloatWinHeight;
}
//开始触控的坐标,移动时的坐标(相对于屏幕左上角的坐标)
private int mTouchStartX, mTouchStartY, mTouchCurrentX, mTouchCurrentY;
//开始时的坐标和结束时的坐标(相对于自身控件的坐标)
private int mStartX, mStartY, mStopX, mStopY;
//判断悬浮窗口是否移动,这里做个标记,防止移动后松手触发了点击事件
private boolean isMove;
/**
* 创建悬浮窗
*/
private void createFloatView() {
LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
mFloatView= inflater.inflate(R.layout.floatlayout, null);
glSurfaceView= (ViewGroup)mFloatView.findViewById(R.id.VOIPFloatView);
//glSurfaceView.setPreserveEGLContextOnPause(true);
glSurfaceView.setKeepScreenOn(true);
mWindowManager.addView(mFloatView,mLayoutParams);
mFloatView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v,MotionEvent event) {
int action = event.getAction();
/*if(MotionEvent.ACTION_DOWN == action) {
mStartX=mLastX= (int) event.getRawX();
mStartY=mLastY= (int) event.getRawY();
}else if(MotionEvent.ACTION_UP == action) {
int dx = (int) event.getRawX() -mStartX;
int dy = (int) event.getRawY() -mStartY;
if(Math.abs(dx) >5|| Math.abs(dy) >5) {
return true;
}
}else if(MotionEvent.ACTION_MOVE == action) {
int dx = (int) event.getRawX() -mLastX;
int dy = (int) event.getRawY() -mLastY;
mLayoutParams.x=mLayoutParams.x- dx;
mLayoutParams.y=mLayoutParams.y+ dy;
mWindowManager.updateViewLayout(mFloatView,mLayoutParams);
mLastX= (int) event.getRawX();
mLastY= (int) event.getRawY();
}
return false;*/
switch (action) {
case MotionEvent.ACTION_DOWN:
isMove = false;
mTouchStartX = (int) event.getRawX();
mTouchStartY = (int) event.getRawY();
mStartX = (int) event.getX();
mStartY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
mTouchCurrentX = (int) event.getRawX();
mTouchCurrentY = (int) event.getRawY();
mLayoutParams.x += mTouchCurrentX - mTouchStartX;
mLayoutParams.y += mTouchCurrentY - mTouchStartY;
mWindowManager.updateViewLayout(mFloatView, mLayoutParams);
mTouchStartX = mTouchCurrentX;
mTouchStartY = mTouchCurrentY;
break;
case MotionEvent.ACTION_UP:
mStopX = (int) event.getX();
mStopY = (int) event.getY();
if (Math.abs(mStartX - mStopX) >= 1 || Math.abs(mStartY - mStopY) >= 1) {
isMove = true;
}
break;
}
//如果是移动事件不触发OnClick事件,防止移动的时候一放手形成点击事件
return isMove;
}
});
mFloatView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ToVOIPActivity();
MyService.this.stopSelf();
}
});
/*VideoRendererGui.setView(glSurfaceView, new Runnable() {
@Override
public void run() {
if(WebRtcHelperEx.getInstance().isWebRtcChanelAlive()) {
WebRtcHelperEx.getInstance().updateVideoUI(WebRtcHelperEx.latestLocalVideoSize,WebRtcHelperEx.latestRemoteVideoSize);
}
}
});
if(WebRtcHelperEx.getInstance().isWebRtcChanelAlive()) {
LogEx.d(TAG,"createFloatView: webrtc instance is alive and we will call resetRenders");
WebRtcHelperEx.getInstance().resetRenders();
WebRtcHelperEx.getInstance().updateVideoUI(WebRtcHelperEx.VIDEOSIZE_SMALL,WebRtcHelperEx.VIDEOSIZE_BIG);
}*/
}
private void removeFloatView() {
if(mFloatView != null && mWindowManager != null) {
mWindowManager.removeView(mFloatView);
}
}
/**
* 单击后回到@WebRTCActivity以切换为大尺寸页面
*/
private void ToVOIPActivity() {
//TODO跳转到Activity
Intent intentToActivity = new Intent(this, Main2Activity.class);//WebPhoneIncomingCallActivity来电页面
intentToActivity.setFlags(FLAG_ACTIVITY_NEW_TASK);
startActivity(intentToActivity);
}
}
layout
<?xml version="1.0" encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/VOIPFloatView"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/avcallfloat"
android:scaleType="centerInside" />