2010-12-19 51 views
234

我試圖創建一直保持在所有窗口之上的始終爲頂部的按鈕/可點擊圖片 。創建一個系統覆蓋窗口(總是在最上面)

的 概念證明是

我已經成功,現在有一個正在運行的服務。服務 一直在屏幕的左上角顯示一些文本,而 用戶可以以正常方式與其餘應用程序自由交互。

我在做什麼 做的是子類ViewGroup並將其添加到根窗口管理器與 標誌TYPE_SYSTEM_OVERLAY。現在我想添加一個按鈕/可點擊圖片 來代替可以接收本身觸摸事件的文本。 I 嘗試覆蓋整個ViewGroup的「onTouchEvent」,但它確實沒有收到任何事件 。

我怎樣才能接收我的始終在頂部視圖組的某些部分 的事件?請建議。

public class HUD extends Service { 
    HUDView mView; 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show(); 
     mView = new HUDView(this); 
     WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.WRAP_CONTENT, 
       WindowManager.LayoutParams.WRAP_CONTENT, 
       WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
       0, 
//    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
//      | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, 
       PixelFormat.TRANSLUCENT); 
     params.gravity = Gravity.RIGHT | Gravity.TOP; 
     params.setTitle("Load Average"); 
     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
     wm.addView(mView, params); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show(); 
     if(mView != null) 
     { 
      ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView); 
      mView = null; 
     } 
    } 
} 

class HUDView extends ViewGroup { 
    private Paint mLoadPaint; 

    public HUDView(Context context) { 
     super(context); 
     Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show(); 

     mLoadPaint = new Paint(); 
     mLoadPaint.setAntiAlias(true); 
     mLoadPaint.setTextSize(10); 
     mLoadPaint.setARGB(255, 255, 0, 0); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawText("Hello World", 5, 15, mLoadPaint); 
    } 

    @Override 
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     //return super.onTouchEvent(event); 
     Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show(); 
     return true; 
    } 
} 
+1

@coreSOLO,我希望你得到你的答案,我奇怪的類似的問題沒得到任何迴應。:) +1 – st0le 2010-12-19 06:44:59

+2

@ st0le我保證我會度過我的每一天,直到我找到解決方案並與你分享:) – coreSOLO 2010-12-19 08:02:57

+0

@coreSOLO,hehe;) – st0le 2010-12-19 08:15:09

回答

140

這可能是一個愚蠢的解決方案。但它的工作。如果你能改善它,請告訴我。

創建您的服務:我已使用WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH標誌。這是服務中唯一的變化。

@Override 
    public void onCreate() { 
     super.onCreate(); 
     Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show(); 
     mView = new HUDView(this); 
     WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
       WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
       PixelFormat.TRANSLUCENT); 
     params.gravity = Gravity.RIGHT | Gravity.TOP; 
     params.setTitle("Load Average"); 
     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
     wm.addView(mView, params); 
    } 

現在,您將開始獲取每個點擊事件。所以,你需要糾正你的事件處理程序。

在你的ViewGroup觸摸事件

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    // ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER 
    // THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA 


    Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show(); 
    return true; 
} 

你也可能需要這個權限添加到您的清單:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 
+0

真棒! !謝謝一堆。我會嘗試一下並讓你知道,但我確定它確實有效:)是的,我對可能優化事件處理的原始服務有一些可能的改進。我會盡快通知你!再次感謝! – coreSOLO 2010-12-19 14:02:29

+0

你可以給我更多的代碼,當我運行代碼,但得到更多的錯誤 – pengwang 2010-12-27 10:10:55

+1

@pengwang:你得到什麼錯誤?此代碼不是獨立的,您需要將它們放在項目中,並在適當的項目下使用適當的文件名。 – 2010-12-28 03:34:50

1

那麼試試我的代碼,至少它給你一個字符串作爲覆蓋,你可以很好地用一個按鈕或圖像替換它。你不會相信這是我的第一個Android應用程序大聲笑。不管怎麼說,如果你是比較有經驗有Android應用超過我,請儘量

  • 改變參數2和3「新WindowManager.LayoutParams」
  • 嘗試一些不同的事件的方法
+0

我最終沒有找到時間去追求這個,因此我仍然缺乏細節... – st0le 2010-12-19 11:06:41

16

與Android 4.x的開始,Android團隊固定一個潛在的 安全問題通過添加新功能adjustWindowParamsLw()其中它 將添加FLAG_NOT_FOCUSABLE,FLAG_NOT_TOUCHABLE並刪除FLAG_WATCH_OUTSIDE_TOUCH標誌爲TYPE_SYSTEM_OVERLAY窗口。

也就是說,一個TYPE_SYSTEM_OVERLAY窗口不會在ICS平臺上收到任何觸摸事件,當然,使用TYPE_SYSTEM_OVERLAY不是ICS和未來設備的可行解決方案。

+4

我有什麼替代方案嗎? – radhoo 2012-04-04 08:56:56

+1

看到關於ICS的這個問題:http:// stackoverflow。com/questions/9656185/type-system-overlay-in-ics – clemp6r 2012-06-28 07:46:03

56

正在關注@Sam Lu的回答, 事實上,Android 4.x確實可以阻止某些類型的設備偵聽外部觸摸事件,但某些類型(例如TYPE_SYSTEM_ALERT)仍然可以完成這項工作。

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
      WindowManager.LayoutParams.MATCH_PARENT, 
      WindowManager.LayoutParams.MATCH_PARENT, 
      WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
      WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 
        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
      PixelFormat.TRANSLUCENT); 

    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 
    View myView = inflater.inflate(R.layout.my_view, null); 
    myView.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      Log.d(TAG, "touch me"); 
      return true; 
     } 
    }); 

    // Add layout to window manager 
    wm.addView(myView, params); 

權限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 
+4

它使我的屏幕被絞死..任何想法 – 2013-04-05 16:38:05

+0

偉大的職位。希望這在未來的版本中也不會被禁用。 – Cookster 2013-04-23 16:47:27

+0

動畫不會在它上面工作...... :(而且它無法捕捉4.2.X中的任何視圖上的點擊任何建議? – 2013-06-01 05:26:42

5

嘗試此。在ICS中運行良好。 如果您想停止服務,只需單擊狀態欄中生成的通知即可。

public class HUD extends Service 
{ 
    protected boolean foreground = false; 
    protected boolean cancelNotification = false; 
    private Notification notification; 
    private View myView; 
    protected int id = 0; 
    private WindowManager wm; 
    private WindowManager.LayoutParams params; 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // System.exit(0); 
     Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_SHORT).show(); 
     params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, 
       WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 
         | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); 
     params.gravity=Gravity.TOP|Gravity.LEFT; 
    wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
    inflateview(); 
    foregroundNotification(1); 
    //moveToForeground(1,n,true); 
    }  
    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(0); 
     Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_SHORT).show(); 
     if(myView != null) 
     { 
      ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(myView); 
      myView = null; 
     } 
    } 
    protected Notification foregroundNotification(int notificationId) 
    {  
    notification = new Notification(R.drawable.ic_launcher, "my Notification", System.currentTimeMillis());  
     notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_ONLY_ALERT_ONCE; 
     notification.setLatestEventInfo(this, "my Notification", "my Notification", notificationIntent());   
     ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(id, notification);    
     return notification; 
    } 
    private PendingIntent notificationIntent() { 
     Intent intent = new Intent(this, stopservice.class);  
     PendingIntent pending = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
     return pending; 
    } 
    public void inflateview() 
    { 
     LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 
      myView = inflater.inflate(R.layout.activity_button, null); 
      myView.setOnTouchListener(new OnTouchListener() { 
       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        Toast.makeText(getBaseContext(),"onToasttt", Toast.LENGTH_SHORT).show(); 
        return false; 
       } 
      }); 
      // Add layout to window manager 
      wm.addView(myView, params); 
    } 
} 

UPDATE

樣品here

創建疊加圖,設立時的LayoutParams沒有設置TYPE_SYSTEM_OVERLAY類型。

Instead set it to TYPE_PHONE. 

Use the following flags: 

FLAG_NOT_TOUCH_MODAL 

FLAG_WATCH_OUTSIDE_TOUCH 
+0

這不適合我,我的屏幕不會與背景交互。任何其他方法,你知道... – Vinuthan 2013-07-16 13:51:48

+0

@Vinuthan你的輸出是什麼,它是否響應 – 2013-07-18 16:35:11

+0

不,它沒有迴應。我已將上面的活動填充到屏幕的一半,以便我可以與背景進行交互,但我無法與背景進行交互。 – Vinuthan 2013-07-19 11:18:41

11

一直在努力TOP圖像按鈕

首先對不起的,我的英語

我編輯的代碼,使工作圖像按鈕,監聽他的觸摸事件 不給觸摸控制自己背景元素。

也是它給觸摸聽衆了其他元素的

按鈕alingments是底部和左側

你可以恰克alingments但你需要chages cordinats在觸摸事件中,如果元素

import android.annotation.SuppressLint; 

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.PixelFormat; 
import android.os.IBinder; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.view.ViewGroup; 
import android.view.WindowManager; 
import android.widget.Toast; 

public class HepUstte extends Service { 
    HUDView mView; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show(); 

     final Bitmap kangoo = BitmapFactory.decodeResource(getResources(), 
       R.drawable.logo_l); 


     WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       kangoo.getWidth(), 
       kangoo.getHeight(), 
       WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
       WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
       |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 
       |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
       PixelFormat.TRANSLUCENT); 






     params.gravity = Gravity.LEFT | Gravity.BOTTOM; 
     params.setTitle("Load Average"); 
     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 



     mView = new HUDView(this,kangoo); 

     mView.setOnTouchListener(new OnTouchListener() { 


      @Override 
      public boolean onTouch(View arg0, MotionEvent arg1) { 
       // TODO Auto-generated method stub 
       //Log.e("kordinatlar", arg1.getX()+":"+arg1.getY()+":"+display.getHeight()+":"+kangoo.getHeight()); 
       if(arg1.getX()<kangoo.getWidth() & arg1.getY()>0) 
       { 
       Log.d("tıklandı", "touch me"); 
       } 
       return false; 
      } 
      }); 


     wm.addView(mView, params); 



     } 



    @Override 
    public IBinder onBind(Intent arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 



@SuppressLint("DrawAllocation") 
class HUDView extends ViewGroup { 


    Bitmap kangoo; 

    public HUDView(Context context,Bitmap kangoo) { 
     super(context); 

     this.kangoo=kangoo; 



    } 


    protected void onDraw(Canvas canvas) { 
     //super.onDraw(canvas); 


     // delete below line if you want transparent back color, but to understand the sizes use back color 
     canvas.drawColor(Color.BLACK); 

     canvas.drawBitmap(kangoo,0 , 0, null); 


     //canvas.drawText("Hello World", 5, 15, mLoadPaint); 

    } 


    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { 
    } 

    public boolean onTouchEvent(MotionEvent event) { 
     //return super.onTouchEvent(event); 
     // Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show(); 

     return true; 
    } 
} 
+0

這可行,但我怎麼能確保我的圖像被點擊,而不是圖像周圍的東西? – 2013-07-29 18:24:39

+0

@LiamW,在本例中,觸摸的座標與kangaroo.getWidth()進行比較。您可以根據您繪製圖像的位置推斷出自己代碼中的內容。 – 2013-10-27 21:51:50

+0

非常好!完美的作品。 – 2013-10-27 21:52:08

2

下面是一些簡單的解決方案: 您只需要像在列表適配器上那樣對XML佈局進行充氣,然後只需使用XML佈局來充氣即可。 這裏是你需要的代碼。

public class HUD extends Service { 
    View mView; 

    LayoutInflater inflate; 
    TextView t; 
    Button b; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show(); 


     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 

     Display display = wm.getDefaultDisplay(); get phone display size 
     int width = display.getWidth(); // deprecated - get phone display width 
     int height = display.getHeight(); // deprecated - get phone display height 


     WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       width, 
       height, 
       WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
       WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
       |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 
       |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
       PixelFormat.TRANSLUCENT); 


     params.gravity = Gravity.LEFT | Gravity.CENTER; 
     params.setTitle("Load Average"); 

     inflate = (LayoutInflater) getBaseContext() 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     mView = inflate.inflate(R.layout.canvas, null); 

     b = (Button) mView.findViewById(R.id.button1); 
     t = (TextView) mView.findViewById(R.id.textView1); 
     b.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 
      // TODO Auto-generated method stub 
      t.setText("yes you click me "); 
     } 
     }); 

     wm.addView(mView, params); 

     } 



    @Override 
    public IBinder onBind(Intent arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 
12

我是Tooleap SDK的開發人員之一。我們還爲開發人員提供了一種始終顯示在頂層窗口和按鈕上的方法,而且我們也處理了類似的情況。

這裏的答案沒有解決的一個問題是Android的「安全按鈕」。

安全按鈕具有filterTouchesWhenObscured屬性,這意味着即使該窗口沒有收到任何接觸,它們也不能與其交互。引用Android文檔:

指定當視圖窗口被另一個可見窗口遮擋 時是否過濾接觸。當設置爲true時,只要烤麪包,對話框或其他窗口出現在視圖窗口上方,視圖就不會收到 觸摸。有關更多詳細信息,請參閱{@link android.view.View}安全 文檔。

當您嘗試安裝第三方apks時,此按鈕的一個示例是安裝按鈕。

android:filterTouchesWhenObscured="true" 

如果顯示始終位於頂部窗口上面的「安全按鈕」,被覆蓋,所有的安全按鈕部分:如果添加到視圖佈局以下行的任何應用程序可以顯示這樣的按鈕通過疊加層不會處理任何觸摸,即使該疊加層不可點擊。因此,如果您計劃顯示這樣一個窗口,您應該爲用戶提供一種移動或解除它的方法。 如果您的疊加層的一部分是透明的,請考慮到您的用戶可能會感到困惑,爲什麼基礎應用中的某個按鈕突然不適合他。

+0

您可以請回答我的問題:http://stackoverflow.com/questions/28964771/application-level-floating-views-with-navigation-in-android – 2015-03-11 06:41:10

1

如果有人仍然閱讀此線程並且無法獲得此工作,我很遺憾地告訴您這種攔截運動事件的方式被認爲是bug>,並在android> = 4.2中修復。

截獲的動作事件雖然具有ACTION_OUTSIDE動作,但在getX 和getY中返回0。這意味着您無法在屏幕上看到所有的動作位置,也無法做任何事情。我知道文檔說它會得到x和y,但事實是它不會。看來這是阻止關鍵記錄器。

如果有人有解決方法,請留下您的評論。

裁判: Why does ACTION_OUTSIDE return 0 everytime on KitKat 4.4.2?

https://code.google.com/p/android/issues/detail?id=72746

1

通過使用服務,您可以做到這一點:

public class PopupService extends Service{ 

    private static final String TAG = PopupService.class.getSimpleName(); 
    WindowManager mWindowManager; 
    View mView; 
    String type ; 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
//  registerOverlayReceiver(); 
     type = intent.getStringExtra("type"); 
     Utils.printLog("type = "+type); 
     showDialog(intent.getStringExtra("msg")); 
     return super.onStartCommand(intent, flags, startId); 
    } 

    private void showDialog(String aTitle) 
    { 
     if(type.equals("when screen is off") | type.equals("always")) 
     { 
      Utils.printLog("type = "+type); 
      PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE); 
      WakeLock mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourServie"); 
      mWakeLock.acquire(); 
      mWakeLock.release(); 
     } 

     mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); 
     mView = View.inflate(getApplicationContext(), R.layout.dialog_popup_notification_received, null); 
     mView.setTag(TAG); 

     int top = getApplicationContext().getResources().getDisplayMetrics().heightPixels/2; 

     LinearLayout dialog = (LinearLayout) mView.findViewById(R.id.pop_exit); 
//  android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) dialog.getLayoutParams(); 
//  lp.topMargin = top; 
//  lp.bottomMargin = top; 
//  mView.setLayoutParams(lp); 

     final EditText etMassage = (EditText) mView.findViewById(R.id.editTextInPopupMessageReceived); 

     ImageButton imageButtonSend = (ImageButton) mView.findViewById(R.id.imageButtonSendInPopupMessageReceived); 
//  lp = (LayoutParams) imageButton.getLayoutParams(); 
//  lp.topMargin = top - 58; 
//  imageButton.setLayoutParams(lp); 
     imageButtonSend.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Utils.printLog("clicked"); 
//    mView.setVisibility(View.INVISIBLE); 
       if(!etMassage.getText().toString().equals("")) 
       { 
        Utils.printLog("sent"); 
        etMassage.setText(""); 
       } 
      } 
     }); 

     TextView close = (TextView) mView.findViewById(R.id.TextViewCloseInPopupMessageReceived); 
     close.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       hideDialog(); 
      } 
     }); 

     TextView view = (TextView) mView.findViewById(R.id.textviewViewInPopupMessageReceived); 
     view.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       hideDialog(); 
      } 
     }); 

     TextView message = (TextView) mView.findViewById(R.id.TextViewMessageInPopupMessageReceived); 
     message.setText(aTitle); 

     final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
     ViewGroup.LayoutParams.MATCH_PARENT, 
     ViewGroup.LayoutParams.MATCH_PARENT, 0, 0, 
     WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, 
     WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
       | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
//    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 
       | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON , 
     PixelFormat.RGBA_8888); 

     mView.setVisibility(View.VISIBLE); 
     mWindowManager.addView(mView, mLayoutParams); 
     mWindowManager.updateViewLayout(mView, mLayoutParams); 

    } 

    private void hideDialog(){ 
     if(mView != null && mWindowManager != null){ 
      mWindowManager.removeView(mView); 
      mView = null; 
     } 
    } 
} 
5

其實,你可以試試WindowManager.LayoutParams.TYPE_SYS TEM_ERROR而不是TYPE_SYSTEM_OVERLAY。這可能聽起來像一個黑客,但它可以讓你在所有事情上展示視圖,並且仍然可以獲得觸摸事件。

0

@Sarwar Erfan的答案不再工作,因爲Android不允許使用WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY將窗口添加到窗口,而不是連WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH都可以觸摸。

我找到了解決這個問題的辦法。你可以檢查它在以下問題

When adding view to window with WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, it is not getting touch event

+0

您推薦的解決方案也不起作用棉花糖 – 2016-11-03 14:55:04

+0

@AhmadShahwaiz請再次檢查鏈接我已爲您在那裏提到的問題添加了評論 – patilmandar2007 2016-11-04 14:04:01

+0

是的,現在它的工作。但在調用startActivityForResult(intent,OVERLAY_REQ_CODE)後沒有獲得回調響應;在protected void onActivityResult(int requestCode,int resultCode,Intent data)方法中。 – 2016-11-07 12:55:59