2011-07-15 26 views
58

Tôi tự hỏi làm thế nào các ứng dụng như SwipePad và Wave Launcher có thể phát hiện cử chỉ cảm ứng/sự kiện chỉ đơn giản thông qua một dịch vụ. Các ứng dụng này có thể phát hiện cử chỉ cảm ứng ngay cả khi nó không có trong Hoạt động của riêng chúng. Tôi đã xem xét trên Internet và không tìm thấy cách họ có thể làm điều đó.Dịch vụ có thể lắng nghe cử chỉ/sự kiện cảm ứng như thế nào?

Câu hỏi chính của tôi là làm thế nào một dịch vụ có thể nghe trong các sự kiện/sự kiện liên lạc giống như một Hoạt động thông thường có thể nhận MotionEvents mặc dù nó có thể không có trong Hoạt động hoặc bối cảnh ban đầu. Về cơ bản, tôi đang cố gắng xây dựng một ứng dụng sẽ kéo dài một cử chỉ cảm ứng cụ thể từ người dùng bất kể Hoạt động nào ở trên đầu và làm điều gì đó khi cử chỉ đó được kéo dài lại. Việc kéo dài cảm ứng sẽ là một chuỗi chạy dưới nền như một dịch vụ.

+1

SwipePad vẻ như nó có thể chỉ sử dụng cửa sổ cảnh báo hệ thống trong suốt cho các khu vực có thể chạm được thay vì toàn bộ màn hình. – Sam

Trả lời

5

Câu hỏi thú vị. Tôi không biết làm thế nào họ đã làm điều đó và tôi tìm thấy bài viết trên google nhóm mà nói với tôi rằng không có người nghe cảm ứng toàn cầu. Nhưng tôi có một ý tưởng nào đó ...

Tôi đã tìm thấy this post nơi ai đó thành công để hiển thị cửa sổ bật lên từ một dịch vụ. Nếu tôi làm cho cửa sổ bật lên đó trong suốt và toàn màn hình, tôi chắc chắn rằng tôi có thể chụp các điểm chạm vì tôi được phép đặt touch interceptor.

Sửa: Đề nghị thông báo kết quả khi bạn cố gắng đó, sẽ rất thú vị để biết nếu làm việc này ...

+0

Điều này có vẻ giống như một phương pháp thú vị. Tôi đã nhìn thấy PopupWindows được sử dụng trước đây cho những điều tương tự nhưng tôi sẽ phải cung cấp cho nó một thử. Hiện tại, tôi cảm thấy thất vọng vì khó có thể liên lạc các sự kiện từ một dịch vụ. Nó sẽ mất một lúc trước khi tôi có cơ hội để thử điều này, nhưng tôi sẽ cho bạn biết làm thế nào nó đi! – Brian

+0

Tôi vừa thử điều này và tôi thậm chí không thể nhận được hộp thoại cảnh báo để hiển thị. Phương thức 'show' đã ném ra một' BadTokenException'. – Sam

+0

Thông báo ngoại lệ là 'Không thể thêm cửa sổ - mã thông báo null không hợp lệ; hoạt động của bạn có đang hoạt động không? ' – Sam

18

Tôi có vấn đề này cùng và cuối cùng tôi đã tìm nó ra! Nhờ bài đăng này: Creating a system overlay window (always on top). Bạn cần phải sử dụng một cửa sổ cảnh báo thay vì một lớp phủ (và điều này cũng có nghĩa là bạn có thể sử dụng nó trong Andoid ICS):

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

Sau đó chỉ cần đính kèm một GestureListener theo cách này:

GestureDetector gestureDetector = new GestureDetector(this, new AwesomeGestureListener()); 
View.OnTouchListener gestureListener = new View.OnTouchListener() { 
     public boolean onTouch(View v, MotionEvent event) { 
      return gestureDetector.onTouchEvent(event); 
     } 
}; 

overlayView.setOnTouchListener(gestureListener); 

Yay!

+0

điều này sẽ ảnh hưởng đến khả năng người dùng nhấp vào các nút trong hoạt động mà họ cho rằng họ đang xem – ChuckKelly

+0

@ChuckKelly có nó sẽ can thiệp –

+3

Tôi đang cố nghe các vòi từ dịch vụ, dịch vụ được đính kèm với Hoạt động. Các hoạt động được sử dụng như bình thường nhưng dịch vụ giữ vòi ghi âm. khi sử dụng TYPE_SYSTEM_OVERLAY hoạt động của nó rất tốt trên Android 2.3 nhưng trên 4.1 onTouchEvent không được gọi. Khi sử dụng TYPE_SYSTEM_ALERT onTouchEvent được gọi nhưng sự kiện cảm ứng không được truyền cho hoạt động và nó không phản hồi. Vui lòng giúp –

2

Tôi đã thử nghiệm tất cả các giải pháp có thể nhưng không có gì làm việc một số đã không bắn sự kiện cảm ứng mà họ đã đóng băng màn hình.

Vì vậy, tôi đã làm một số kỹ thuật đảo ngược và giải pháp hiện nay đăng mà làm việc

WindowManager.LayoutParams params = new android.view.WindowManager.LayoutParams(0, 0, 0, 0, 2003, 0x40028, -3); 
     View mView = new View(this); 

     mView.setOnTouchListener(this); 

     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
     wm.addView(mView, params); 
+0

Điều này dường như chỉ hoạt động cho chế độ xem/hoạt động đầu tiên. Không cho các hoạt động tiếp theo được tạo ra. Tôi nhận được cảnh báo sau: W/ViewRootImpl ﹕ Sự kiện rơi do không có tiêu điểm cửa sổ: MotionEvent {action = ACTION_OUTSIDE, actionButton = 0, id [0] = 0, x [0] = 0.0, y [0] = 0.0, toolType [0] = TOOL_TYPE_FINGER, buttonState = 0, metaState = 0, cờ = 0x0, edgeFlags = 0x0, pointerCount = 1, historySize = 0, eventTime = 220247332, downTime = 220247332, deviceId = 4, source = 0x1002} –

3

tôi thử nghiệm này trên API 21 và một mối quan hệ 5 và tôi đã có thể đăng nhập, từ một dịch vụ, khi một sự kiện liên lạc đã bị sa thải bởi hệ thống. Tuy nhiên, dữ liệu bên trong đối tượng MotionEvent, ví dụ như tọa độ, trả về 0.0 khi OUTSIDE của những gì có vẻ là gói ứng dụng của tôi.

Hai nguồn integration, permission

tôi tò mò là tại sao event.getX(), event.getY() và event.getPressure() trả về 0.0 khi không một hoạt động của ứng dụng nơi dịch vụ sống.

Sửa

Giải pháp này không ngăn cản người nghe khác từ nhận sự kiện liên lạc capured bởi dịch vụ vì

public boolean onTouch(View v, MotionEvent e){ 
    Log.d(LOG_TAG, "Touch event captured"); 
    return false;  

Bằng cách trả về false, nó cho phép người nghe khác để nhận sự kiện này.

Edit2

Rõ ràng, điều phối đầu vào trong hệ điều hành sẽ thiết lập tọa độ và áp suất là 0 nếu các hoạt động hiện tại và người nghe không chia sẻ một UID, đây là source

+0

bạn có thấy một cách để giải quyết vấn đề này? như thay đổi UID động? – keinabel

+0

Trừ khi bạn có hệ điều hành riêng của bạn, tôi không nghĩ rằng nó sẽ có thể. Có thể nếu dịch vụ được đăng ký như một dịch vụ hệ thống? Tôi có nghĩa là các giá trị có nhưng hệ điều hành sẽ loại bỏ các giá trị quan tâm và tuyên truyền các sự kiện liên lạc lên đến bất kỳ người nghe khác. – Clocker

Các vấn đề liên quan