java - 如何检测后台服务或 Android native 环境中的音量按钮单击?

标签 java android c service

我想在Android的后台服务或原生环境中检测音量按钮点击事件,希望它能随时检测到该事件。

我用ContentObserver 尝试了下面的代码,但这只能检测到AUDIO_SERVICE 发生变化的事件,如果前台应用程序正在运行音乐,则此方法无法检测到它,我认为是因为它是 STREAM_MUSIC 而不是 AUDIO_SERVICE。我想要的是随时检测音量按钮点击和任何音量按钮点击。

有人知道怎么做吗? 我可以在 native 代码中使用 C 实现它吗?

public class SettingsContentObserver extends ContentObserver {
    int previousVolume;
    Context context;

    public SettingsContentObserver(Context c, Handler handler) {
        super(handler);
        context=c;

        AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        previousVolume = audio.getStreamVolume(AudioManager.AUDIO_SERVICE);
    }

    @Override
    public boolean deliverSelfNotifications() {
        return super.deliverSelfNotifications();
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);

        AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        int currentVolume = audio.getStreamVolume(AudioManager.AUDIO_SERVICE);

        int delta=previousVolume-currentVolume;

        if(delta>0)
        {
            Logger.d("Volume Up!");
            previousVolume=currentVolume;
        }
        else if(delta<0)
        {
            Logger.d("Volume Down!");
            previousVolume=currentVolume;
        }
    }
}

然后在我的服务 onCreate 中注册:

mSettingsContentObserver = new SettingsContentObserver(this,new Handler());
getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver );

然后在onDestroy注销:

getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);

最佳答案

你试过了吗this

import android.provider.Settings;
import android.provider.Settings.System;
mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(Settings.System.VOLUME_SETTINGS[AudioManager.STREAM_M‌​USIC]), true, mVolumeObserver);

在 native 代码上实现相同的方法可能行不通,因为您需要将每个方法从 ContentObserver 绑定(bind)到 native 调用,如下所示:

public class NativeContentObserver extends ContentObserver {
    public static final String TAG = "NativeContentObserver";

    private native boolean natDeliverSelfNotifications();
    private native void natDispatchChange(boolean selfChange, Uri uri);
    private native void natDispatchChange(boolean selfChange);
    private native void natOnChange(boolean selfChange, Uri uri);
    private native void natOnChange(boolean selfChange);

     /// ... Delegate work from here ... ///

    static {
        System.loadLibrary("NativeContentObserver");
    }
}

所以你需要先做ContentObserver,然后再转到native code。

关于java - 如何检测后台服务或 Android native 环境中的音量按钮单击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18803591/

相关文章:

python - 将任意长度的列表或元组传递给用 C 编写的 Python 扩展

java - 列表-RemoveFirst 获取 NullPointerException

java - 安卓。如何使用改造发布原始数据或帮助使用 asynctask

java - 在sqlite中插入不起作用

android - 使用自定义适配器实现过滤器的 ListView 出现 IndexOutOfBoundsException

c - 使用C编程打开不同的文件

java - jqgrid 将 Jqgrid 数据发布回 Action 类

java - Cassandra Java 驱动程序 - QueryBuilder API 与 PreparedStatements

java - Android:调用 Context.startService() 后未启动嵌套 Intent 服务

无法弄清楚我是如何遇到段错误的