2012-10-18 21 views
8

Tôi muốn ứng dụng của tôi phản ứng khác với một Sự kiện quan trọng được nhấn lâu của các nút âm lượng.onKeyDown và onKeyLongPress

Tôi đã xem this, nhưng nếu tôi giữ nút âm lượng được nhấn, tôi nhận được rất nhiều sự kiện KeyDown trước khi tôi nhận được sự kiện KeyLongPressed.

Tôi muốn có một sự kiện hoặc sự kiện khác, không phải cả hai, để tôi có thể điều chỉnh Âm lượng ở một báo chí ngắn và bỏ qua một bản nhạc ở một lần bấm dài.

Bạn có thể giúp tôi ở đây không?

Đây là mã của tôi:

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) 
    { 
     Log.d("Test", "Long press!"); 
     return true; 
    } 
    return super.onKeyLongPress(keyCode, event); 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
     event.startTracking(); 
     Log.d("Test", "Short"); 
     return true; 
    } 

    return super.onKeyDown(keyCode, event); 
} 

Bất kỳ giúp đánh giá cao! - Iris

+0

sau đó thử với khóa (KeyEvent.KEYCODE_VOLUME_UP) thay vì khóa phím; nếu bấm lâu sẽ gọi trước khi bấm phím, nếu bấm lâu gọi là dừng hành động trong khóa bằng cách sử dụng cờ – Sandy09

+0

Đó là phím tăng âm lượng, không phải chỉ báo cho biết khóa được giữ hoặc thứ gì đó tương tự. –

+0

Tôi đang thử mọi thứ ở thời điểm này –

Trả lời

14

Đây là mã mà tôi đã viết. Nó hoạt động như một say mê. Có thể bạn có thể tối ưu hóa nó cho logic tốt hơn. Nhưng bạn sẽ nhận được điểm với nó. Điều quan trọng là sử dụng cờ. Báo chí ngắn là một báo chí trong đó chúng tôi nhấn nút âm lượng trong thời gian ngắn và nhả. Vì vậy, onKeyUp là một trong đó sẽ giúp chúng tôi phát hiện các máy ép ngắn.

package com.example.demo; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.Menu; 

public class TestVolumeActivity extends Activity { 
    boolean flag = false; 

    boolean flag2 = false; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_splash_screen); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_splash_screen, menu); 
     return true; 
    } 

    @Override 
    public boolean onKeyLongPress(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
      Log.d("Test", "Long press!"); 
      flag = false; 
      flag2 = true; 
      return true; 
     } 
     return super.onKeyLongPress(keyCode, event); 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
      event.startTracking(); 
      if (flag2 == true) { 
       flag = false; 
      } else { 
       flag = true; 
       flag2 = false; 
      } 

      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

    @Override 
    public boolean onKeyUp(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 

      event.startTracking(); 
      if (flag) { 
       Log.d("Test", "Short"); 
      } 
      flag = true; 
      flag2 = false; 
      return true; 
     } 

     return super.onKeyUp(keyCode, event); 
    } 
} 

Logcat cho tất cả các máy ép dài (Không báo chí ngắn phát hiện):

10-18 02:06:15.369: D/Test(16834): Long press! 
10-18 02:06:18.683: D/Test(16834): Long press! 
10-18 02:06:21.566: D/Test(16834): Long press! 
10-18 02:06:23.738: D/Test(16834): Long press! 

Logcat cho tất cả các máy ép ngắn:

10-18 02:07:42.422: D/Test(16834): Short 
10-18 02:07:43.203: D/Test(16834): Short 
10-18 02:07:43.663: D/Test(16834): Short 
10-18 02:07:44.144: D/Test(16834): Short 
+1

+1 Đánh bại tôi đến một phút :) Tôi cho rằng một số lý do anh ấy sẽ không được thông qua các sự kiện quan trọng –

+0

cảm ơn bạn rất nhiều, điều này hoạt động tuyệt vời! – friday

+0

Bạn được chào đón !!! – VendettaDroid

0

Tôi không biết nếu câu trả lời này sẽ cung cấp một giải pháp chấp nhận được cho vấn đề của bạn, vì nó có dựa vào việc thường xuyênKeyDown sự kiện trên cơ sở liên tục.

Bạn có thể thử nhớ thời gian hệ thống khi sự kiện KeyDown cuối cùng được ném (Tôi sẽ đặt tên là tLast) và bỏ qua tất cả sự kiện KeyDown cho đến khi bạn nhận được sự kiện KeyLongPressed.

Để nhận được sự kiện "đúng" KeyDown (những điều bạn đã bỏ qua ở bước trước), bạn có thể kiểm tra xem sự khác biệt thời gian giữa thời gian hệ thống hiện tại và tLast (Tôi sẽ đặt tên là tDelta) đủ lớn để không được coi là báo chí liên tục.

Cho rằng rất nhiều sự kiện KeyDown được ném trong một khoảng thời gian ngắn, bạn có thể xác định về mặt lý thuyết nút âm lượng không được nhấn liên tục khi đủ sự kiện (tDelta lớn hơn giá trị cố định). Sự thiếu hụt của giải pháp này là nếu người dùng nhấn nút âm lượng thực sự nhanh (tDelta giữa các lần nhấn thấp hơn giá trị cố định được sử dụng để đánh giá báo chí liên tục), nhiều lần nhấn phím sẽ bị bỏ qua/xem xét như một phím bấm liên tục.

Khác (sắp tới) sắp tới là sẽ có sự chậm trễ trước khi diễn giải các phím bấm thông thường, vì tDelta sẽ phải lớn hơn giá trị cố định được sử dụng khi đánh giá nếu bạn đang xử lý một phím bấm thông thường hoặc liên tục .

Kính trọng,

Lucian

EDIT: Hmm ... nghĩ thứ hai: Không phải bạn sử dụng một cài đặt Android KeyListener?

Nếu bạn đang sử dụng, hãy kiểm tra phương pháp onKeyUp được xác định cho điều này.

Tôi nghĩ nó sẽ thanh lịch hơn nếu bạn chỉ mở rộng lớp này (hoặc một trong các lớp dẫn xuất của nó) và sử dụng phương thức onKeyUp để xác định xem bạn có đang xử lý các lần bấm liên tục hay không. được giữ lại lớn hơn giá trị cố định).

Nếu bạn có thể sử dụng phương pháp này, vui lòng thực hiện. Nó cũng hiệu quả hơn, dễ bảo trì hơn và đơn giản hơn so với công việc xung quanh được trình bày ở trên.

KeyListener Javadoc

4

Khi tôi sắp sửa gửi của tôi câu trả lời tôi phát hiện ra một số đã có một số loại giải pháp ....

Nhưng đây là của tôi, đơn giản và hoạt động như một sự quyến rũ. Chỉ cần một lá cờ;)

Mã này phát hiện các phím tắt và long, khi thời gian dài xảy ra không có shortpress nào được kích hoạt!

Lưu ý: nếu bạn muốn khối lượng bình thường và hành vi xuống thay đổi sự trở lại đúng trong phương pháp OnKeyPress cuộc gọi siêu như thế này:

event.startTracking(); 
if(event.getRepeatCount() == 0){ 
    shortPress = true; 
} 
//return true; 
return super.onKeyDown(keyCode, event); 

Mã mà không gọi siêu:

private boolean shortPress = false; 

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
     shortPress = false; 
     Toast.makeText(this, "longPress", Toast.LENGTH_LONG).show(); 
     return true; 
    } 
    //Just return false because the super call does always the same (returning false) 
    return false; 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
     if(event.getAction() == KeyEvent.ACTION_DOWN){ 
      event.startTracking(); 
      if(event.getRepeatCount() == 0){ 
       shortPress = true; 
      } 
      return true; 
     } 
    } 
    return super.onKeyDown(keyCode, event); 
} 

@Override 
public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
     if(shortPress){ 
      Toast.makeText(this, "shortPress", Toast.LENGTH_LONG).show(); 
     } else { 
      //Don't handle longpress here, because the user will have to get his finger back up first 
     } 
     shortPress = false; 
     return true; 
    } 
    return super.onKeyUp(keyCode, event); 
} 

Mã dưới đây là với phím tăng âm lượng, chỉ cần chọn mặt của bạn;)

private boolean shortPress = false; 

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
     shortPress = false; 
     Toast.makeText(this, "longPress Volume Down", Toast.LENGTH_LONG).show(); 
     return true; 
    } else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){ 
     shortPress = false; 
     Toast.makeText(this, "longPress Volume Up", Toast.LENGTH_LONG).show(); 
     return true; 
    } 
    //Just return false because the super call does always the same (returning false) 
    return false; 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 
     if(event.getAction() == KeyEvent.ACTION_DOWN){ 
      event.startTracking(); 
      if(event.getRepeatCount() == 0){ 
       shortPress = true; 
      } 
      return true; 
     } 
    } 
    return super.onKeyDown(keyCode, event); 
} 

@Override 
public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
     if(shortPress){ 
      Toast.makeText(this, "shortPress Volume Down", Toast.LENGTH_LONG).show(); 
     } else { 
      //Don't handle longpress here, because the user will have to get his finger back up first 
     } 
     shortPress = false; 
     return true; 
    } else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){ 
     if(shortPress){ 
      Toast.makeText(this, "shortPress Volume up", Toast.LENGTH_LONG).show(); 
     } else { 
      //Don't handle longpress here, because the user will have to get his finger back up first 
     } 
     shortPress = false; 
     return true; 

    } 
    return super.onKeyUp(keyCode, event); 
} 
+1

Đây là câu trả lời tốt hơn, vì nó sử dụng các biến nhỏ hơn và mã mnemonic. Làm tốt. – Avijit

3

Cách đúng theo SDK để xử lý các lần nhấn nút dài.

import android.app.Activity; 
import android.util.Log; 
import android.view.KeyEvent; 


public class TestVolumeActivity extends Activity 
{ 
    private static final String TAG = TestVolumeActivity.class.getSimpleName(); 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if(keyCode == KeyEvent.KEYCODE_VOLUME_UP || 
      keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) 
     { 
      event.startTracking(); 
      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

    @Override 
    public boolean onKeyLongPress(int keyCode, KeyEvent event) 
    { 
     if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){ 
      Log.d(TAG, "Long press KEYCODE_VOLUME_UP"); 
      return true; 
     } 
     else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){ 
      Log.d(TAG, "Long press KEYCODE_VOLUME_DOWN"); 
      return true; 
     } 
     return super.onKeyLongPress(keyCode, event); 
    } 

    @Override 
    public boolean onKeyUp(int keyCode, KeyEvent event) 
    { 
     if((event.getFlags() & KeyEvent.FLAG_CANCELED_LONG_PRESS) == 0){ 
      if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){ 
       Log.e(TAG, "Short press KEYCODE_VOLUME_UP"); 
       return true; 
      } 
      else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){ 
       Log.e(TAG, "Short press KEYCODE_VOLUME_DOWN"); 
       return true; 
      } 
     } 
     return super.onKeyUp(keyCode, event); 
    } 
} 
+0

Tiêu chuẩn hơn và sạch hơn nhiều.Vấn đề duy nhất của tôi là thiết bị của tôi sẽ phát ra tiếng bíp ngay sau khi báo chí dài, mà tôi đã giải quyết bằng cách thêm 'else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { trả về true; } ' tới' onKeyUp'. –