做了一个桌面悬浮窗的demo,其中悬浮窗是用Service来实现的,点击系统home键显示桌面悬浮窗,点击桌面悬浮窗再返回demo主界面并且隐藏悬浮窗。。发现这么一个现象,如果在demo主界面,按下系统home键返回系统桌面,出现悬浮窗后立即点击悬浮窗,要等待3秒钟才能跳转到demo主界面;如果返回系统桌面出现悬浮窗后,等超过3秒钟的时间,再去点击悬浮窗,就能立即响应,跳转到demo主界面。
下面贴源码,非常简单的用Service来实现悬浮窗:public class FloatingWindowService extends Service {public static final String OPERATION = "operation";
public static final int OPERATION_SHOW = 100;
public static final int OPERATION_HIDE = 101;private static final int HANDLE_CHECK_ACTIVITY = 200;private boolean isAdded = false; // 是否已增加悬浮窗
private static WindowManager wm;
private static WindowManager.LayoutParams params;
private Button btn_floatView;private List<String> homeList; // 桌面应用程序包名列表
private ActivityManager mActivityManager;@Override
public IBinder onBind(Intent intent) {
return null;
}@Override
public void onCreate() {
super.onCreate();homeList = getHomes();
createFloatView();
}@Override
public void onDestroy() {
super.onDestroy();
}@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW);
switch(operation) {
case OPERATION_SHOW:
mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
mHandler.sendEmptyMessage(HANDLE_CHECK_ACTIVITY);
break;
case OPERATION_HIDE:
mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
break;
}
}private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case HANDLE_CHECK_ACTIVITY:
if(isHome()) {
if(!isAdded) {
wm.addView(btn_floatView, params);
isAdded = true;
}
} else {
if(isAdded) {
wm.removeView(btn_floatView);
isAdded = false;
}
}
mHandler.sendEmptyMessageDelayed(HANDLE_CHECK_ACTIVITY, 500);
break;
}
}
};/**
 * 创建悬浮窗
 */
private void createFloatView() {
btn_floatView = new Button(getApplicationContext());
        btn_floatView.setText("悬浮窗");
        
        wm = (WindowManager) getApplicationContext()
         .getSystemService(Context.WINDOW_SERVICE);
        params = new WindowManager.LayoutParams();        
        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        params.format = PixelFormat.RGBA_8888; 
        
        // 设置Window flag
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            
        // 设置悬浮窗的长得宽
        params.width = 100;
        params.height = 100;
        
        btn_floatView.setOnClickListener(new OnClickListener() {       public void onClick(View v) {
       // TODO Auto-generated method stub
               Log.e("点击悬浮窗", "点击悬浮窗");
               Intent intent = new Intent();
               intent.setClass(getApplicationContext(), Floating_windowActivity.class);
               intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);
               Log.e("DeskTopService", "1111111111");
               startActivity(intent);
               Log.e("DeskTopService", "2222222222");
          }
         });
               wm.addView(btn_floatView, params);
               isAdded = true;
               Log.e("demo悬浮窗位置", params.x+"  "+params.y );
}/** 
 * 获得属于桌面的应用的应用包名称 
 * @return 返回包含所有包名的字符串列表 
 */
private List<String> getHomes() {
List<String> names = new ArrayList<String>();  
    PackageManager packageManager = this.getPackageManager();  
    // 属性  
    Intent intent = new Intent(Intent.ACTION_MAIN);  
    intent.addCategory(Intent.CATEGORY_HOME);  
    List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,  
            PackageManager.MATCH_DEFAULT_ONLY);  
    for(ResolveInfo ri : resolveInfo) {  
        names.add(ri.activityInfo.packageName);  
    }
    return names;  

//  判断当前界面是否是桌面 
 
public boolean isHome(){  
if(mActivityManager == null) {
mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);  
}
    List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);  
    return homeList.contains(rti.get(0).topActivity.getPackageName());  
}}用handler每隔500毫秒检查一次当前是否在系统桌面,用来判断是否展示悬浮窗,跳转就非常简单了,用intent跳转。
大家看看这段代码有什么问题,为何点击系统Home键返回桌面,再立即点击悬浮窗,需要等待3秒钟的时间才会跳转;而如果返回桌面后等待3秒钟以上再点击悬浮窗,就可以立即响应跳转到demo主界面。
我打印Log日志,发现立即点击悬浮窗,等待3秒钟的时间里已经打印出 Log.e("DeskTopService", "2222222222"),也就是说,已经执行了startActivity(intent); 为什么就不跳转呢?

解决方案 »

  1.   

    在你的demo第一个acitivty的oncreate方法添加 if (!isTaskRoot()) {
                finish();
                return;
            }应该会有效
      

  2.   

    http://blog.csdn.net/ixiaobu/article/details/18226917 
      

  3.   

    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        try {
            pendingIntent.send(); // 监听到Home键按下后立即调用startActivity启动Activity会有5s延迟
        } catch (PendingIntent.CanceledException e) {
            e.printStackTrace();
        }
      

  4.   

    同样的问题
    检测home按键到桌面
    然后startactivity到某个Activity
    1.等待时间过长(3-5s才会进去)
    2.如果到桌面后点击其他app,就不会跳转到指定的activity