转载地址:http://blog.youkuaiyun.com/guolin_blog/article/details/8689140
主界面启动服务,在服务中根据不同状态对悬浮窗进行管理
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button)findViewById(R.id.btn_float_window);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
Intent intent = new Intent(MainActivity.this,FloatWindowService.class);
startService(intent);
finish();
}
});
}
}
自定义大悬浮窗VIEW
public class BigFloatView extends LinearLayout implements View.OnClickListener
{
public static int viewHeight;
public static int viewWidth;
public BigFloatView(Context context){
super(context);
LayoutInflater.from(context).inflate(R.layout.big_float_window,this);
View view = findViewById(R.id.big_window);
viewWidth = view.getLayoutParams().width;
viewHeight = view.getLayoutParams().height;
Button btnClose = (Button)view.findViewById(R.id.close);
Button btnBack = (Button)view.findViewById(R.id.back);
btnClose.setOnClickListener(this);
btnBack.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
switch(v.getId()){
//关闭所有悬浮窗并停止服务
case R.id.close:
Intent intent = new Intent(getContext(),FloatWindowService.class);
getContext().stopService(intent);
MyWindowManager.removeBigWindow(getContext());
MyWindowManager.removeSmallView(getContext());
break;
//从大悬浮窗返回到小悬浮窗
case R.id.back:
MyWindowManager.removeBigWindow(getContext());
MyWindowManager.createSmallWindow(getContext());
break;
}
}
//回退键进入小悬浮窗
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getAction()==KeyEvent.ACTION_DOWN&&event.getKeyCode()==KeyEvent.KEYCODE_BACK){
MyWindowManager.removeBigWindow(getContext());
MyWindowManager.createSmallWindow(getContext());
return true;
}
return super.dispatchKeyEvent(event);
}
}
自定义可拖拽的小悬浮窗VIEW
public class SmallFloatView extends LinearLayout
{
/**
* 记录小悬浮窗的宽度
*/
public static int viewWidth;
/**
* 记录小悬浮窗的高度
*/
public static int viewHeight;
/**
* 记录系统状态栏的高度
*/
private static int statusBarHeight;
/**
* 用于更新小悬浮窗的位置
*/
private WindowManager windowManager;
/**
* 小悬浮窗的参数
*/
private WindowManager.LayoutParams mParams;
/**
* 记录当前手指位置在屏幕上的横坐标值
*/
private float xInScreen;
/**
* 记录当前手指位置在屏幕上的纵坐标值
*/
private float yInScreen;
/**
* 记录手指按下时在屏幕上的横坐标的值
*/
private float xDownInScreen;
/**
* 记录手指按下时在屏幕上的纵坐标的值
*/
private float yDownInScreen;
/**
* 记录手指按下时在小悬浮窗的View上的横坐标的值
*/
private float xInView;
/**
* 记录手指按下时在小悬浮窗的View上的纵坐标的值
*/
private float yInView;
public SmallFloatView(Context context){
super(context);
windowManager = (WindowManager)context.getSystemService(context.WINDOW_SERVICE);
LayoutInflater.from(context).inflate(R.layout.small_float_window,this);
View view = findViewById(R.id.small_window);
TextView tvPercent = (TextView)view.findViewById(R.id.percent);
viewWidth = view.getLayoutParams().width;
viewHeight = view.getLayoutParams().height;
tvPercent.setText(MyWindowManager.getMemoryUsedPercent(context));
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
Log.d("TAG",slop+"");
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
xInView = event.getX();
yInView = event.getY();
xDownInScreen = event.getRawX();
yDownInScreen = event.getRawY() - getStatusBarHeight();
xInScreen = event.getRawX();
yInScreen = event.getRawY() - getStatusBarHeight();
break;
case MotionEvent.ACTION_MOVE:
xInScreen = event.getRawX();
yInScreen = event.getRawY() - getStatusBarHeight();
//更新小悬浮窗的位置
updateViewPosition();
break;
case MotionEvent.ACTION_UP:
// 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
if (xDownInScreen == xInScreen && yDownInScreen == yInScreen) {
openBigWindow();
}
break;
}
return true;
}
//获取状态栏高度
private int getStatusBarHeight(){
if(statusBarHeight==0){
Class<?> c;
try
{
c = Class.forName("com.android.internal.R$dimen");
Object o = c.newInstance();
Field field = c.getField("status_bar_height");
int x = (Integer) field.get(o);
statusBarHeight = getResources().getDimensionPixelSize(x);
}catch(Exception e)
{
e.printStackTrace();
}
}
return statusBarHeight;
}
//给小悬浮窗设置窗口布局参数
public void setParams(WindowManager.LayoutParams params) {
mParams = params;
}
private void updateViewPosition() {
mParams.x = (int) (xInScreen - xInView);
mParams.y = (int) (yInScreen - yInView);
windowManager.updateViewLayout(this, mParams);
}
public void openBigWindow(){
MyWindowManager.createBigWindow(getContext());
MyWindowManager.removeSmallView(getContext());
}
}
封装大小悬浮窗的添加、移除操作
public class MyWindowManager
{
/**
* 小悬浮窗View的实例
*/
private static SmallFloatView smallWindow;
/**
* 大悬浮窗View的实例
*/
private static BigFloatView bigWindow;
/**
* 小悬浮窗View的参数
*/
private static WindowManager.LayoutParams smallWindowParams;
/**
* 大悬浮窗View的参数
*/
private static WindowManager.LayoutParams bigWindowParams;
/**
* 用于控制在屏幕上添加或移除悬浮窗
*/
private static WindowManager mWindowManager;
/**
* 用于获取手机可用内存
*/
private static ActivityManager mActivityManager;
/**
* 创建小悬浮窗在右边中间位置
* @param context
*/
public static void createSmallWindow(Context context){
WindowManager windowManager = getWindowManager(context);
int screenWidth = windowManager.getDefaultDisplay().getWidth();
int screenHeight = windowManager.getDefaultDisplay().getHeight();
if(smallWindow==null){
Toast.makeText(context,"new smallWindow",Toast.LENGTH_SHORT).show();
smallWindow = new SmallFloatView(context);
if(smallWindowParams==null){
Toast.makeText(context,"new params",Toast.LENGTH_SHORT).show();
smallWindowParams = new LayoutParams();
smallWindowParams.type = LayoutParams.TYPE_PHONE;
smallWindowParams.format = PixelFormat.RGBA_8888;
smallWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_NOT_FOCUSABLE;
smallWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
smallWindowParams.width = SmallFloatView.viewWidth;
smallWindowParams.height = SmallFloatView.viewHeight;
//TAG
smallWindowParams.x = screenWidth - SmallFloatView.viewWidth;
smallWindowParams.y = screenHeight / 2 - SmallFloatView.viewHeight/2;
}
//TAG
smallWindow.setParams(smallWindowParams);
windowManager.addView(smallWindow,smallWindowParams);
}
}
public static void removeSmallView(Context context){
if(smallWindow!=null){
WindowManager windowManager = getWindowManager(context);
windowManager.removeView(smallWindow);
smallWindow = null;
}
}
/**
* 创建大悬浮窗在屏幕中间位置
* @param context
*/
public static void createBigWindow(Context context){
WindowManager windowManager = getWindowManager(context);
int screenWidth = windowManager.getDefaultDisplay().getWidth();
int screenHeight = windowManager.getDefaultDisplay().getHeight();
if(bigWindow==null){
bigWindow = new BigFloatView(context);
if(bigWindowParams==null){
bigWindowParams = new LayoutParams();
bigWindowParams = new LayoutParams();
bigWindowParams.x = screenWidth / 2 - BigFloatView.viewWidth / 2;
bigWindowParams.y = screenHeight / 2 - BigFloatView.viewHeight / 2;
bigWindowParams.type = LayoutParams.TYPE_PHONE;
bigWindowParams.format = PixelFormat.RGBA_8888;
bigWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
bigWindowParams.width = BigFloatView.viewWidth;
bigWindowParams.height = BigFloatView.viewHeight;
}
windowManager.addView(bigWindow,bigWindowParams);
}
}
public static void removeBigWindow(Context context){
if(bigWindow!=null){
WindowManager windowManager = getWindowManager(context);
windowManager.removeView(bigWindow);
bigWindow = null;
}
}
public static WindowManager getWindowManager(Context context){
if(mWindowManager==null)
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return mWindowManager;
}
public static ActivityManager getActivityManager(Context context){
if(mActivityManager==null)
mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return mActivityManager;
}
/**
* 获取当前可用内存,字节为单位
* @param context
* @return
*/
public static long getAvailableMemory(Context context){
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
getActivityManager(context).getMemoryInfo(memoryInfo);
return memoryInfo.availMem;
}
public static String getMemoryUsedPercent(Context context){
String filePath = "/proc/meminfo";
try {
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String memoryLine = bufferedReader.readLine();
String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
bufferedReader.close();
long totalMemorySize = Integer.parseInt(subMemoryLine.replaceAll("\\D+", ""));
long availableSize = getAvailableMemory(context) / 1024;
int percent = (int) ((totalMemorySize - availableSize) / (float) totalMemorySize * 100);
return percent + "%";
} catch (Exception e) {
e.printStackTrace();
}
return "Error";
}
public static boolean isWindowShow(){
return smallWindow!=null||bigWindow!=null;
}
/**
* 小悬浮窗数据更新
* @param context
*/
public static void updateMemoryUsedPercent(Context context){
if(smallWindow!=null){
TextView tv = (TextView) smallWindow.findViewById(R.id.percent);
tv.setText(getMemoryUsedPercent(context));
}
}
}
服务中开启新线程,每隔0.5S刷新状态
//在服务中管理悬浮窗的显示,刷新悬浮窗数据
public int onStartCommand(Intent intent, int flags, int startId) {
if (timer == null) {
timer = new Timer();
timer.scheduleAtFixedRate(new RefreshTask(), 0, 500);
}
return super.onStartCommand(intent, flags, startId);
}
//服务销毁时定时器取消任务
public void onDestroy() {
super.onDestroy();
if (timer != null)
timer.cancel();
timer = null;
}
//刷新任务,每500ms执行一次
class RefreshTask extends TimerTask {
@Override
public void run() {
//在桌面且没有悬浮窗显示
if (isHome() && !MyWindowManager.isWindowShow()) {
mHandler.post(new Runnable() {
@Override
public void run() {
MyWindowManager.createSmallWindow(FloatWindowService.this);
}
});
//不在桌面且有悬浮窗显示
} else if (!isHome() && MyWindowManager.isWindowShow()) {
mHandler.post(new Runnable() {
@Override
public void run() {
MyWindowManager.removeBigWindow(FloatWindowService.this);
MyWindowManager.removeSmallView(FloatWindowService.this);
}
});
//在桌面且有悬浮窗显示
} else if (isHome() && MyWindowManager.isWindowShow()) {
mHandler.post(new Runnable() {
@Override
public void run() {
MyWindowManager.updateMemoryUsedPercent(FloatWindowService.this);
}
});
}
}
}
//判断当前界面是否在桌面
private boolean isHome() {
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
return getHome().contains(runningTasks.get(0).topActivity.getPackageName());
}
private List<String> getHome() {
PackageManager packageManager = getPackageManager();
List<String> names = new ArrayList<String>();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo info : resolveInfos) {
names.add(info.activityInfo.packageName);
}
return names;
}