zoukankan      html  css  js  c++  java
  • android 桌面工具

    引用:http://blog.csdn.net/shinay/article/details/7783276

    这是一篇Android悬浮窗的介绍,能够实现例如360,QQ管家那样的悬浮窗效果。后台运行了一个服务,用于控制在运行非桌面app情况下隐藏悬浮窗。



    下面先上Demo截图:





    上图就是所实现的简单悬浮窗示例,当然可以根据项目需要改变其相应布局。
    给出Demo的源代码地址:http://download.csdn.net/detail/shinay/4450976


    下面是创建悬浮窗的方法:

    1. private boolean isAdded = false// 是否已增加悬浮窗  
    2. private static WindowManager wm;  
    3. private static WindowManager.LayoutParams params;  
    4. private Button btn_floatView;  
    1. /** 
    2.  * 创建悬浮窗 
    3.  */  
    4. private void createFloatView() {  
    5.     btn_floatView = new Button(getApplicationContext());  
    6.        btn_floatView.setText("悬浮窗");  
    7.          
    8.        wm = (WindowManager) getApplicationContext()  
    9.         .getSystemService(Context.WINDOW_SERVICE);  
    10.        params = new WindowManager.LayoutParams();  
    11.          
    12.        // 设置window type  
    13.        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;  
    14.        /* 
    15.         * 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE; 
    16.         * 那么优先级会降低一些, 即拉下通知栏不可见 
    17.         */  
    18.          
    19.        params.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明  
    20.          
    21.        // 设置Window flag  
    22.        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL  
    23.                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
    24.        /* 
    25.         * 下面的flags属性的效果形同“锁定”。 
    26.         * 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。 
    27.        wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL 
    28.                               | LayoutParams.FLAG_NOT_FOCUSABLE 
    29.                               | LayoutParams.FLAG_NOT_TOUCHABLE; 
    30.         */  
    31.          
    32.        // 设置悬浮窗的长得宽  
    33.        params.width = 100;  
    34.        params.height = 100;  
    35.          
    36.        // 设置悬浮窗的Touch监听  
    37.        btn_floatView.setOnTouchListener(new OnTouchListener() {  
    38.         int lastX, lastY;  
    39.         int paramX, paramY;  
    40.           
    41.         public boolean onTouch(View v, MotionEvent event) {  
    42.             switch(event.getAction()) {  
    43.             case MotionEvent.ACTION_DOWN:  
    44.                 lastX = (int) event.getRawX();  
    45.                 lastY = (int) event.getRawY();  
    46.                 paramX = params.x;  
    47.                 paramY = params.y;  
    48.                 break;  
    49.             case MotionEvent.ACTION_MOVE:  
    50.                 int dx = (int) event.getRawX() - lastX;  
    51.                 int dy = (int) event.getRawY() - lastY;  
    52.                 params.x = paramX + dx;  
    53.                 params.y = paramY + dy;  
    54.                 // 更新悬浮窗位置  
    55.                 wm.updateViewLayout(btn_floatView, params);  
    56.                 break;  
    57.             }  
    58.             return true;  
    59.         }  
    60.     });  
    61.          
    62.        wm.addView(btn_floatView, params);  
    63.        isAdded = true;  
    64. }  


    做完这步,基本上就可以在桌面显示一个悬浮窗并且可以自由拖动了。

    如果想要控制它在桌面显示,而进入到别的应用程序时隐藏它的话,就需要用一个后台运行的Service来实现了。

    首先需要先获取到手机上的桌面程序的包名(桌面程序指的是按下HOME键所列出的程序,如go桌面等):

    1. /**  
    2.  * 获得属于桌面的应用的应用包名称  
    3.  * @return 返回包含所有包名的字符串列表  
    4.  */  
    5. private List<String> getHomes() {  
    6.     List<String> names = new ArrayList<String>();    
    7.     PackageManager packageManager = this.getPackageManager();    
    8.     // 属性    
    9.     Intent intent = new Intent(Intent.ACTION_MAIN);    
    10.     intent.addCategory(Intent.CATEGORY_HOME);    
    11.     List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,    
    12.             PackageManager.MATCH_DEFAULT_ONLY);    
    13.     for(ResolveInfo ri : resolveInfo) {    
    14.         names.add(ri.activityInfo.packageName);    
    15.     }  
    16.     return names;    
    17. }  


    接着是判断当前运行的Activity是否为桌面应用程序,这里需要用到ActivityManager:

    1. /**  
    2.  * 判断当前界面是否是桌面  
    3.  */    
    4. public boolean isHome(){    
    5.     if(mActivityManager == null) {  
    6.         mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);    
    7.     }  
    8.     List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);    
    9.     return homeList.contains(rti.get(0).topActivity.getPackageName());    
    10. }  


    有了上面两个方法,就可以实现这个功能了。只不过我们需要定时去判断,例如可以用一个Handler每一秒去检查一次:

    1. private Handler mHandler = new Handler() {  
    2.     @Override  
    3.     public void handleMessage(Message msg) {  
    4.         switch(msg.what) {  
    5.         case HANDLE_CHECK_ACTIVITY:  
    6.             if(isHome()) {  
    7.                 if(!isAdded) {  
    8.                     wm.addView(btn_floatView, params);  
    9.                     isAdded = true;  
    10.                 }  
    11.             } else {  
    12.                 if(isAdded) {  
    13.                     wm.removeView(btn_floatView);  
    14.                     isAdded = false;  
    15.                 }  
    16.             }  
    17.             mHandler.sendEmptyMessageDelayed(HANDLE_CHECK_ACTIVITY, 1000);  
    18.             break;  
    19.         }  
    20.     }  
    21. };  


    在我的Demo中,悬浮窗都是通过Service来控制的,那么我的启动与隐藏就都扔给Service处理就OK。

    1. public void onClick(View v) {  
    2.     switch(v.getId()) {  
    3.     case R.id.btn_show:  
    4.         Intent show = new Intent(this, FloatingWindowService.class);  
    5.         show.putExtra(FloatingWindowService.OPERATION, FloatingWindowService.OPERATION_SHOW);  
    6.         startService(show);  
    7.         break;  
    8.     case R.id.btn_hide:  
    9.         Intent hide = new Intent(this, FloatingWindowService.class);  
    10.         hide.putExtra(FloatingWindowService.OPERATION, FloatingWindowService.OPERATION_HIDE);  
    11.         startService(hide);  
    12.         break;  
    13.     }  
    14. }  


    在Service里的onStart方法中,只需要根据传过来的操作参数,对handler检查进行操作即可。

    1. @Override  
    2. public void onStart(Intent intent, int startId) {  
    3.     super.onStart(intent, startId);  
    4.       
    5.     int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW);  
    6.     switch(operation) {  
    7.     case OPERATION_SHOW:  
    8.         mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);  
    9.         mHandler.sendEmptyMessage(HANDLE_CHECK_ACTIVITY);  
    10.         break;  
    11.     case OPERATION_HIDE:  
    12.         mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);  
    13.         break;  
    14.     }  
    15. }  

    另外:需要增加以下权限!!

    1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>  
    2. <uses-permission android:name="android.permission.GET_TASKS"/>  






    最后给出源代码地址:http://download.csdn.net/detail/shinay/4450976

  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/sode/p/3040303.html
Copyright © 2011-2022 走看看