Skip to content Skip to sidebar Skip to footer

Any Way To Detect Volume Key Presses Or Volume Changes With Android Service?

Some Android apps generate a notification when the device's volume changes and some lock the volume. For the life of me, I cannot find out how that's done. Please, can someone he

Solution 1:

There is no Broadcast Action to detect volume changes, but you could maybe every second or two check what the volume is with getStreamVolume and if you need to lock it at a specific volume, every second or two use: setStreamVolume

Check http://developer.android.com/reference/android/media/AudioManager.htm for more info.

You could use the AlarmManager class or a handler to check the volume every second or so.

If it's an activity, you can override onKeyDown to detect key presses. See http://developer.android.com/reference/android/view/View.html

Solution 2:

Actually there is one way you can do in service by using Content Observer. It works like a broadcast receiver, listen to the event of changing content such as volume, contacts, call log...

Using the following code in your service

publicclassVolumeServiceextendsService{ 
AudioManager mAudioManager;
Handler mHandler;

privateContentObservermVolumeObserver=newContentObserver(mHandler) {
    @OverridepublicvoidonChange(boolean selfChange) {
        super.onChange(selfChange);
        if (mAudioManager != null) {

            finalintvolume= mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
            System.out.println("Volume thay đổi: " +volume);

            IntentphotoIntent=newIntent(VolumeService.this,TakePhotoActivity.class);
            photoIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(photoIntent);
        }
    }
};





@OverridepublicvoidonCreate() {
    super.onCreate();

    System.out.println("Volume Service started");

    mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

    Uriuri= Settings.System.getUriFor(Settings.System.VOLUME_SETTINGS[AudioManager.STREAM_RING]);
    getContentResolver().registerContentObserver(uri, true, mVolumeObserver);

    System.out.println("Đã đăng ký Volume listener");
}



@OverridepublicvoidonDestroy() {
    super.onDestroy();      
    System.out.println("Volume service destroied");

    getContentResolver().unregisterContentObserver(mVolumeObserver);
}



@Overridepublic IBinder onBind(Intent arg0) {

    returnnull;
}

}

Don't forget to declare it in the Android Manifest.xml

<serviceandroid:name=".service.VolumeService" >

Solution 3:

This is one way to do it, you could just fix to a set volume instead of changing. My goal was to adjust system volume Service.

Also, avoid doing this only when needed.

publicclassVolumeKeyController {

    private MediaSessionCompat mMediaSession;
    privatefinal Context mContext;

    publicVolumeKeyController(Context context) {
        mContext = context;
    }

    privatevoidcreateMediaSession() {
        mMediaSession = newMediaSessionCompat(mContext, KeyUtil.log);

        mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mMediaSession.setPlaybackState(newBuilder()
                .setState(PlaybackStateCompat.STATE_PLAYING, 0, 0)
                .build());
        mMediaSession.setPlaybackToRemote(getVolumeProvider());
        mMediaSession.setActive(true);
    }

    private VolumeProviderCompat getVolumeProvider() {
        finalAudioManageraudio= mContext.getSystemService(Context.AUDIO_SERVICE);

        intSTREAM_TYPE= AudioManager.STREAM_MUSIC;
        intcurrentVolume= audio.getStreamVolume(STREAM_TYPE);
        intmaxVolume= audio.getStreamMaxVolume(STREAM_TYPE);
        finalintVOLUME_UP=1;
        finalintVOLUME_DOWN= -1;

        returnnewVolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) {
            @OverridepublicvoidonAdjustVolume(int direction) {
                // Up = 1, Down = -1, Release = 0// Replace with your action, if you don't want to adjust system volumeif (direction == VOLUME_UP) {
                    audio.adjustStreamVolume(STREAM_TYPE,
                            AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                elseif (direction == VOLUME_DOWN) {
                    audio.adjustStreamVolume(STREAM_TYPE,
                            AudioManager.ADJUST_LOWER, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                }
                setCurrentVolume(audio.getStreamVolume(STREAM_TYPE));
            }
        };
    }

    // Call when control needed, add a call to constructor if needed immediatelypublicvoidsetActive(boolean active) {
        if (mMediaSession != null) {
            mMediaSession.setActive(active);
            return;
        }
        createMediaSession();
    }

    // Call from Service's onDestroy methodpublicvoiddestroy() {
        if (mMediaSession != null) {
            mMediaSession.release();
        }
    }
}

Solution 4:

You can capture volume/hardware key events by using accessibility service.

How to capture key events inside a service?

Post a Comment for "Any Way To Detect Volume Key Presses Or Volume Changes With Android Service?"