5

I want to detect the volume button click event in the background service or in native environment in Android.I hope it can detect the event at anytime.

I tried the code below with ContentObserver, but this can detect only event of AUDIO_SERVICE changing, if the foreground application is running with music, this method can not detect it, I think because it's STREAM_MUSIC but not AUDIO_SERVICE.What I want is detecting the volume button click at anytime and any volume button click.

Does anyone know how to do it? Can I implement it with C in native code?

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;
        }
    }
}

Then in my service onCreate register it with:

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

Then unregister in onDestroy:

getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
Suge
  • 2,808
  • 3
  • 48
  • 79

1 Answers1

-1

Have you tried 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);

Implementing same on native code maybe would't work as you need to bind each method from ContentObserver to native calls, something like this:

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");
    }
}

So you need to make work first ContentObserver before going to native code.

Community
  • 1
  • 1
Cedmundo
  • 682
  • 4
  • 12