Android Context Set sendKey(Context c, int action, int keycode)

Here you can find the source of sendKey(Context c, int action, int keycode)

Description

Create and send a KeyEvent through the AudioService, failback to a simple intent broadcast if necessary.On KitKat, the event should be send by the service, otherwise it's not working with SELinux enforced mode.

License

Apache License

Parameter

Parameter Description
c Context
action KeyEvent.ACTION_
keycode KeyEvent.KEYCODE_

Declaration

private static void sendKey(Context c, int action, int keycode) 

Method Source Code

//package com.java2s;
/*//from w w w  . j a  va2 s.c  om
 * Copyright 2012 Laurent Constantin <android@blackcrowsteam.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.view.KeyEvent;

public class Main {
    /**
     * Create and send a KeyEvent through the AudioService, failback to a simple
     * intent broadcast if necessary.On KitKat, the event should be send by the
     * service, otherwise it's not working with SELinux enforced mode.
     * 
     * @param c
     *            Context
     * @param action
     *            KeyEvent.ACTION_*
     * @param keycode
     *            KeyEvent.KEYCODE_*
     */
    private static void sendKey(Context c, int action, int keycode) {
        long eventtime = SystemClock.uptimeMillis();
        KeyEvent keyEvent = new KeyEvent(eventtime, eventtime, action,
                keycode, 0);

        if (!sendMediaKeyEventViaAudioService(keyEvent)) {
            Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
            downIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
            c.sendOrderedBroadcast(downIntent, null);
        }

    }

    /**
     * Send two KeyEvent, one with Action_down and then one with Action_up
     * 
     * @param c
     *            Context
     * @param keyCode
     *            See KeyEvent.KEYCODE_
     */
    private static void sendKey(Context c, int keyCode) {

        sendKey(c, KeyEvent.ACTION_DOWN, keyCode);
        sendKey(c, KeyEvent.ACTION_UP, keyCode);
    }

    /**
     * Send a key event using audioService.dispatchMediaKeyEvent(keyEvent) using
     * reflection.
     * 
     * @param keyEvent
     * @return true on success, false otherwise
     */
    public static boolean sendMediaKeyEventViaAudioService(KeyEvent keyEvent) {
        return sendMediaKeyEventViaAudioService(keyEvent,
                "dispatchMediaKeyEvent");
    }

    /**
     * Send a key event using audioService.dispatchMediaKeyEvent OR
     * audioService.dispatchMediaKeyEventUnderWakelock(keyEvent) using
     * reflection.
     * 
     * Source: http://stackoverflow.com/questions/12573442/
     * is-google-play-music-hogging-all-action-media-button-intents
     * 
     * @param keyEvent
     * @param method
     *            dispatchMediaKeyEvent or dispatchMediaKeyEventUnderWakelock
     * @return true on success, false otherwise
     */
    private static boolean sendMediaKeyEventViaAudioService(
            KeyEvent keyEvent, String method) {
        /*
         * Attempt to execute the following with reflection.
         * 
         * [Code] IAudioService audioService =
         * IAudioService.Stub.asInterface(b);
         * audioService.dispatchMediaKeyEvent(keyEvent);
         */
        try {

            // Get binder from ServiceManager.checkService(String)
            IBinder iBinder = (IBinder) Class
                    .forName("android.os.ServiceManager")
                    .getDeclaredMethod("checkService", String.class)
                    .invoke(null, Context.AUDIO_SERVICE);

            // get audioService from IAudioService.Stub.asInterface(IBinder)
            Object audioService = Class
                    .forName("android.media.IAudioService$Stub")
                    .getDeclaredMethod("asInterface", IBinder.class)
                    .invoke(null, iBinder);

            // Dispatch keyEvent using
            // IAudioService.dispatchMediaKeyEvent(KeyEvent) or
            // dispatchMediaKeyEventUnderWakelock
            Class.forName("android.media.IAudioService")
                    .getDeclaredMethod(method, KeyEvent.class)
                    .invoke(audioService, keyEvent);
            return true;
        } catch (Exception e1) {
            e1.printStackTrace();
            return false;
        }
    }
}

Related

  1. scanMediaFiles(final Context context, String[] files, String[] mimeTypes)
  2. sendKey(Context c, int keyCode)
  3. sendPlayPauseKey(Context c)
  4. sendSms(@Nonnull Context context, @CheckForNull String number, @Nullable String text)
  5. sendStopKey(Context c)