Android如何监听音量按钮事件?

51

我知道你们可能已经厌倦了这类帖子,但为什么按下音量减键时没有任何反应?我只是想编写一个简单的代码,但显然它不起作用。

package com.cakemansapps.lightwriter;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.view.KeyEvent;
import android.util.Log;

public class LightWriter extends Activity implements OnTouchListener {
private static final String TAG = "Touch" ;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) 
{
    Log.w("LightWriter", "I WORK BRO.");
    return true;
}
return super.onKeyLongPress(keyCode, event);
}

public boolean onTouch(View view, MotionEvent me) {
    throw new UnsupportedOperationException("Not supported yet.");
}

}

相关:https://dev59.com/m1vUa4cB1Zd3GeqPt3ht - whostolemyhat
你不需要将关键事件与控件相关联吗?你检查了这个链接http://www.vogella.de/articles/AndroidMedia/article.html吗? - kosa
请看这里:链接 - adneal
5个回答

69

我不知道是否可以获取硬件按键的长按事件。

之前我曾使用以下代码监听音量按钮。

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
        // Do something
    }
    return true;
}

如果这对你不起作用,请告诉我们你正在测试的设备是什么。

Kotlin

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
        // Do something
    }
    return true
}

1
“returns true”这行代码应该放在‘if’语句块内部吗?默认情况下它应该返回false。只有在处理事件时才应该返回true。 - Birdnado
24
最后一行应该是“return super.onKeyDown(keyCode, event);”而不是“return true”。 - TechAurelian
3
这段代码是正确的,但它会禁用主要目的,即降低音量。它会优先执行“//做一些事情”部分的语句。 - ajdeguzman
2
@ajdeguzman 如果你返回 false 而不是 true,我认为它也会相应地改变音量。 - FoamyGuy
3
太棒了。我怎样知道是哪个音量被调低了?例如,是系统音量、音乐音量还是闹钟音量? - Si8
显示剩余2条评论

17

另一种方法

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    int action = event.getAction();
    int keyCode = event.getKeyCode();
        switch (keyCode) {
        case KeyEvent.KEYCODE_VOLUME_UP:
            if (action == KeyEvent.ACTION_DOWN) {
                //TODO
            }
            return true;
        case KeyEvent.KEYCODE_VOLUME_DOWN:
            if (action == KeyEvent.ACTION_DOWN) {
                //TODO
            }
            return true;
        default:
            return super.dispatchKeyEvent(event);
        }
    }

2
请问当设备被锁定时,它是如何工作的? - Abhishek
很好...当按下音量按钮时如何静音/禁用/隐藏通知?=( - KingRider
如何处理屏幕锁定? @Abhisheck,你找到处理锁屏的答案了吗? - Cheerag
有没有可用于监听按下键的广播呢? - Hitesh Dhamshaniya

8
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
        // ... your code
        return true;
    } else if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
        // ... your code
        return true;
    } else
        return super.onKeyDown(keyCode, event);
}

5

试试这些。我刚测试过:

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    super.onKeyLongPress(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        Log.w("LightWriter", "I WORK BRO.");
        return true;
    }
    return false;
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
    super.onKeyDown(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        Log.w("LightWriter", "I WORK BRO.");
        return true;
    }
    return true;
}

@Sergery,你能告诉我设备锁定时它是如何工作的吗? - Abhishek
1
@Abhishek 我从未这样做过...但我的理解/猜测是:当屏幕锁定时,您的应用程序需要获得运行权限 (https://dev59.com/oGbWa4cB1Zd3GeqPU0Od#11546168),并且可能需要设置广播接收器来接收按键事件(可能是其中之一(它“可能”会更改使用的设备)https://developer.android.com/reference/android/media/AudioManager.html)。 (很抱歉表述不清(我通常处理ContentProviders,Services,IPC等),但希望这有助于引导您走向正确的方向) - mawalker
onKeyLongPress() 在我的设备上无法工作。但是 onKeyDown() 可以正常工作。看起来这与设备有关。 - ka3ak
好的,我知道问题出在哪里了。我必须在onKeyDown()中调用event.startTracking()。之后就会调用onKeyLongPress()。 - ka3ak

4

使用以下代码处理音量键事件

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    super.onKeyUp(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
    {
        Toast.makeText(MainActivity.this,"Up working",Toast.LENGTH_SHORT).show();
        return true;
    }
    return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    super.onKeyDown(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
    {
        Toast.makeText(MainActivity.this,"Down working",Toast.LENGTH_SHORT).show();
        return true;
    }
    return false;
}

3
虽然这个可能在运行上可行,但我认为这种方法是错误的。如果你查看文档,onKeyDown 在任何按钮按下时都会被调用,而 onKeyUp 在任何按钮释放时都会被调用。你可以在其中一个函数中处理 KeyEvent.KEYCODE_VOLUME_UPKeyEvent.KEYCODE_VOLUME_DOWN 两个按钮。 - Micer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接