是否有可能创建一个类似的锁屏谷歌播放音乐的小工具?有可能、创建一个、小工具、类似

2023-09-05 07:26:42 作者:落笔映惆怅丶

我开发的音乐播放器。我有两个家,锁屏,工程一个小部件。我不想让用户从锁屏放置或删除插件的选项。

我的目标是:

小部件自动显示在主机锁屏上,取出小部件,有作为的时间,日期窗口小部件,或将在其。

管理MusicService和Widget一致。 (清除锁屏小工具,当我离开音乐播放器。 这是谷歌究竟是如何播放音乐小工具在我的Galaxy Nexus的(或许多其他手机)。这可能吗?难道我需要的东西,这不是一个小部件,如自定义锁屏?

解决方案

好了,解决的办法很简单,不使用任何插件,只需使用的 RemoteControlClientCompat 类。这是我的lockScreenControls()方法,code,我打电话时,我想表明这种类型的控制。

 私人无效lockScreenControls(){

        //使用媒体按钮的API(如果有的话)来注册自己的媒体按钮
        //事件

        MediaButtonHelper.registerMediaButtonEventReceiverCompat(mAudioManager,mMediaButtonReceiverComponent);
        //使用遥控器的API(如果可用)设置播放状态
        如果(mRemoteControlClientCompat == NULL){
            意向意图=新的意图(Intent.ACTION_MEDIA_BUTTON);
            intent.setComponent(mMediaButtonReceiverComponent);
            mRemoteControlClientCompat =新RemoteControlClientCompat(PendingIntent.getBroadcast(本/ *中* / 0 / *请求code,忽略​​ /,意图/ *意图* / 0 / *标志* /));
            RemoteControlHelper.registerRemoteControlClient(mAudioManager,mRemoteControlClientCompat);
        }
        mRemoteControlClientCompat.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
        mRemoteControlClientCompat.setTransportControlFlags(
                RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
                RemoteControlClient.FLAG_KEY_MEDIA_ preVIOUS |
                RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
                RemoteControlClient.FLAG_KEY_MEDIA_STOP);

        //更新遥控器
        mRemoteControlClientCompat.editMetadata(真)
                .putString(MediaMetadataRetriever.METADATA_KEY_ARTIST,NombreArtista)
                .putString(MediaMetadataRetriever.METADATA_KEY_ALBUM,TITULO专辑)
                .putString(MediaMetadataRetriever.METADATA_KEY_TITLE,nombreCancion)
                //。putLong(MediaMetadataRetriever.METADATA_KEY_DURATION,playingItem.getDuration())
                        // TODO:提取实物艺术品
                .putBitmap(RemoteControlClientCompat.MetadataEditorCompat.METADATA_KEY_ARTWORK,getAlbumArt())
                。应用();
        }
    }
 

*********** EDIT ************

RemoteControlClientCompat类:

  @燮pressWarnings({rawtypes,未})
公共类RemoteControlClientCompat {

私有静态最后字符串变量=RemoteControlCompat;

私有静态类sRemoteControlClientClass;

// RCC简称RemoteControlClient
私有静态方法sRCCEditMetadataMethod;
私有静态方法sRCCSetPlayStateMethod;
私有静态方法sRCCSetTransportControlFlags;

私有静态布尔sHasRemoteControlAPIs = FALSE;

静态{
    尝试 {
        类加载器的类加载器= RemoteControlClientCompat.class.getClassLoader();
        sRemoteControlClientClass = getActualRemoteControlClientClass器(classloader);
        //动态填充playstate和标志值的情况下,他们改变
        //在将来的版本。
        对于(场场:RemoteControlClientCompat.class.getFields()){
            尝试 {
                字段realField = sRemoteControlClientClass.getField(field.getName());
                对象realValue = realField.get(空);
                field.set(NULL,realValue);
            }赶上(NoSuchFieldException E){
                Log.w(TAG,无法获得真正的现场:+ field.getName());
            }赶上(抛出:IllegalArgumentException E){
                Log.w(TAG,错误试图拉字段值:+ field.getName()
                        ++ e.getMessage());
            }赶上(IllegalAccessException E){
                Log.w(TAG,错误试图拉字段值:+ field.getName()
                        ++ e.getMessage());
            }
        }

        //得到RemoteControlClient所需要的公共方法
        sRCCEditMetadataMethod = sRemoteControlClientClass.getMethod(editMetadata
                boolean.class);
        sRCCSetPlayStateMethod = sRemoteControlClientClass.getMethod(setPlaybackState
                int.class);
        sRCCSetTransportControlFlags = sRemoteControlClientClass.getMethod(
                setTransportControlFlags,int.class);

        sHasRemoteControlAPIs = TRUE;
    }赶上(ClassNotFoundException异常E){
        ICS之前的操作系统上运行时,//静默失败。
    }赶上(NoSuchMethodException E){
        ICS之前的操作系统上运行时,//静默失败。
    }赶上(抛出:IllegalArgumentException E){
        ICS之前的操作系统上运行时,//静默失败。
    }赶上(SecurityException异常E){
        ICS之前的操作系统上运行时,//静默失败。
    }
}

公共静态类getActualRemoteControlClientClass(类加载器的类加载器)
        抛出ClassNotFoundException的{
    返回classLoader.loadClass(android.media.RemoteControlClient);
}

私有对象mActualRemoteControlClient;

公共RemoteControlClientCompat(PendingIntent pendingIntent){
    如果(!sHasRemoteControlAPIs){
        返回;
    }
    尝试 {
        mActualRemoteControlClient =
                sRemoteControlClientClass.getConstructor(PendingIntent.class)
                        .newInstance(pendingIntent);
    }赶上(例外五){
        抛出新的RuntimeException(E);
    }
}

公共RemoteControlClientCompat(PendingIntent pendingIntent,活套活套){
    如果(!sHasRemoteControlAPIs){
        返回;
    }

    尝试 {
        mActualRemoteControlClient =
                sRemoteControlClientClass.getConstructor(PendingIntent.class,Looper.class)
                        .newInstance(pendingIntent,活套);
    }赶上(例外五){
        Log.e(TAG,错误创建新实例+ sRemoteControlClientClass.getName(),E);
    }
}

/ **
 *用于修改元数据在{@link android.media.RemoteControlClient}对象类。使用
 * {@link android.media.RemoteControlClient#editMetadata(布尔)}创建一个实例
 *编辑器,在其上设置的元数据RemoteControlClient实例。一旦所有的
 *信息设置,使用{@link #apply()},使之成为新的元数据,应该是
 *显示为相关客户端。一旦元数据被应用,你不能重用
 *在MetadataEditor的这个实例。
 * /
公共类MetadataEditorCompat {

    私有方法mPutStringMethod;
    私有方法mPutBitmapMethod;
    私有方法mPutLongMethod;
    私有方法mClearMethod;
    私有方法mApplyMethod;

    私有对象mActualMetadataEditor;

    / **
     *元数据密钥内容​​的插图/专辑封面。
     * /
    公共最后静态INT METADATA_KEY_ARTWORK = 100;

    私人MetadataEditorCompat(对象actualMetadataEditor){
        如果(sHasRemoteControlAPIs&安培;&安培; actualMetadataEditor == NULL){
            抛出新抛出:IllegalArgumentException(遥控器API的存在,+
                    不应该给空MetadataEditor);
        }
        如果(sHasRemoteControlAPIs){
            类metadataEditorClass = actualMetadataEditor.getClass();

            尝试 {
                mPutStringMethod = metadataEditorClass.getMethod(putString
                        int.class,为String.class);
                mPutBitmapMethod = metadataEditorClass.getMethod(putBitmap
                        int.class,Bitmap.class);
                mPutLongMethod = metadataEditorClass.getMethod(putLong
                        int.class,long.class);
                mClearMethod = metadataEditorClass.getMethod(清,新的等级[] {});
                mApplyMethod = metadataEditorClass.getMethod(应用,新的等级[] {});
            }赶上(例外五){
                抛出新的RuntimeException(e.getMessage(),E);
            }
        }
        mActualMetadataEditor = actualMetadataEditor;
    }

    / **
     *添加到要显示的文本信息。
     *请注意,没有经过{@link #apply()}被称为添加的信息,
     *将显示。
     * @参数密钥的所述元数据字段的标识符来设置。有效值
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}。
     *参数值的文本给定键,或{@ code空}以表示没有有效
     *信息领域。
     * @返回返回引用同一个MetadataEditor对象,这样你就可以链认沽
     *调用起来。
     * /
    公共MetadataEditorCompat putString(INT键,字符串值){
        如果(sHasRemoteControlAPIs){
            尝试 {
                mPutStringMethod.invoke(mActualMetadataEditor,键,值);
            }赶上(例外五){
                抛出新的RuntimeException(e.getMessage(),E);
            }
        }
        回到这一点;
    }

    / **
     *设置相册/艺术品图片被遥控器上的显示。
     * @参数关键位图的标识符来设置。唯一有效的值是
     * {@link #METADATA_KEY_ARTWORK}
     *参数位图中的位图作品,或NULL,如果没有任何。
     * @返回返回引用同一个MetadataEditor对象,这样你就可以链认沽
     *调用起来。
     * @throws抛出:IllegalArgumentException
     * @see android.graphics.Bitmap
     * /
    公共MetadataEditorCompat putBitmap(INT键,位图位图){
        如果(sHasRemoteControlAPIs){
            尝试 {
                mPutBitmapMethod.invoke(mActualMetadataEditor,钥匙,位图);
            }赶上(例外五){
                抛出新的RuntimeException(e.getMessage(),E);
            }
        }
        回到这一点;
    }

    / **
     *增加了显示数字信息。
     *请注意,没有经过{@link #apply()}被称为添加的信息,
     *将显示。
     * @参数密钥的所述元数据字段的标识符来设置。有效值
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION}(其值
     * pssed以毫秒为单位EX $ P $)
     * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}。
     *参数值给定键长值
     * @返回返回引用同一个MetadataEditor对象,这样你就可以链认沽
     *调用起来。
     * @throws抛出:IllegalArgumentException
     * /
    公共MetadataEditorCompat putLong(INT键,长值){
        如果(sHasRemoteControlAPIs){
            尝试 {
                mPutLongMethod.invoke(mActualMetadataEditor,键,值);
            }赶上(例外五){
                抛出新的RuntimeException(e.getMessage(),E);
            }
        }
        回到这一点;
    }

    / **
     *清除所有已设置自MetadataEditor实例是元数据
     *与创建{@link android.media.RemoteControlClient#editMetadata(布尔)}。
     * /
    公共无效清除(){
        如果(sHasRemoteControlAPIs){
            尝试 {
                mClearMethod.invoke(mActualMetadataEditor,(对象[])NULL);
            }赶上(例外五){
                抛出新的RuntimeException(e.getMessage(),E);
            }
        }
    }

    / **
     * Associates均已经设置自MetadataEditor实例是元数据
     *用{@link android.media.RemoteControlClient#editMetadata(布尔)},或自创建以来
     * {@link #clear()}是所谓的,与RemoteControlClient。一旦申请,这
     * MetadataEditor不能重复使用编辑RemoteControlClient的元数据。
     * /
    公共无效申请(){
        如果(sHasRemoteControlAPIs){
            尝试 {
                mApplyMethod.invoke(mActualMetadataEditor,(对象[])NULL);
            }赶上(例外五){
                抛出新的RuntimeException(e.getMessage(),E);
            }
        }
    }
}

/ **
 *创建{@link android.media.RemoteControlClient.MetadataEditor}。
 * @参数startEmpty设置为false,如果你想MetadataEditor包含的元数据
 *为previously施加到RemoteControlClient,或真,如果它是要创建空的。
 返回:一个新的MetadataEditor实例。
 * /
公共MetadataEditorCompat editMetadata(布尔startEmpty){
    对象metadataEditor;
    如果(sHasRemoteControlAPIs){
        尝试 {
            metadataEditor = sRCCEditMetadataMethod.invoke(mActualRemoteControlClient,
                    startEmpty);
        }赶上(例外五){
            抛出新的RuntimeException(E);
        }
    } 其他 {
        metadataEditor = NULL;
    }
    返回新MetadataEditorCompat(metadataEditor);
}

/ **
 *设置当前的播放状态。
 *参数状态当前的播放状态,下列值之一:
 * {@link android.media.RemoteControlClient#PLAYSTATE_STOPPED},
 * {@link android.media.RemoteControlClient#PLAYSTATE_PAUSED},
 * {@link android.media.RemoteControlClient#PLAYSTATE_PLAYING},
 * {@link android.media.RemoteControlClient#PLAYSTATE_FAST_FORWARDING},
 * {@link android.media.RemoteControlClient#PLAYSTATE_REWINDING},
 * {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS},
 * {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS},
 * {@link android.media.RemoteControlClient#PLAYSTATE_BUFFERING},
 * {@link android.media.RemoteControlClient#PLAYSTATE_ERROR}。
 * /
公共无效setPlaybackState(INT状态){
    如果(sHasRemoteControlAPIs){
        尝试 {
            sRCCSetPlayStateMethod.invoke(mActualRemoteControlClient,状态);
        }赶上(例外五){
            抛出新的RuntimeException(E);
        }
    }
}

/ **
 *设置标志该客户端支持媒体传输控制按钮。
 * @参数transportControlFlags下列标志的组合:
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_ preVIOUS},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD},
 * {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT}
 * /
公共无效setTransportControlFlags(INT transportControlFlags){
    如果(sHasRemoteControlAPIs){
        尝试 {
            sRCCSetTransportControlFlags.invoke(mActualRemoteControlClient,
                    transportControlFlags);
        }赶上(例外五){
            抛出新的RuntimeException(E);
        }
    }
}

公共终对象getActualRemoteControlClientObject(){
    返回mActualRemoteControlClient;
}
}
 

RemoteControlHelper类:

 公共类RemoteControlHelper {
私有静态最后字符串变量=RemoteControlHelper;

私有静态布尔sHasRemoteControlAPIs = FALSE;

私有静态方法sRegisterRemoteControlClientMethod;
私有静态方法sUnregisterRemoteControlClientMethod;

静态{
    尝试 {
        类加载器的类加载器= RemoteControlHelper.class.getClassLoader();
        类sRemoteControlClientClass =
                RemoteControlClientCompat.getActualRemoteControlClientClass器(classloader);
        sRegisterRemoteControlClientMethod = AudioManager.class.getMethod(
                registerRemoteControlClient,新的等级[] {sRemoteControlClientClass});
        sUnregisterRemoteControlClientMethod = AudioManager.class.getMethod(
                unregisterRemoteControlClient,新的等级[] {sRemoteControlClientClass});
        sHasRemoteControlAPIs = TRUE;
    }赶上(ClassNotFoundException异常E){
        ICS之前的操作系统上运行时,//静默失败。
    }赶上(NoSuchMethodException E){
        ICS之前的操作系统上运行时,//静默失败。
    }赶上(抛出:IllegalArgumentException E){
        ICS之前的操作系统上运行时,//静默失败。
    }赶上(SecurityException异常E){
        ICS之前的操作系统上运行时,//静默失败。
    }
}

公共静态无效registerRemoteControlClient(AudioManager audioManager,
                                               RemoteControlClientCompat remoteControlClient){
    如果(!sHasRemoteControlAPIs){
        返回;
    }

    尝试 {
        sRegisterRemoteControlClientMethod.invoke(audioManager,
                remoteControlClient.getActualRemoteControlClientObject());
    }赶上(例外五){
        Log.e(TAG,e.getMessage(),E);
    }
}


公共静态无效unregisterRemoteControlClient(AudioManager audioManager,
                                                 RemoteControlClientCompat remoteControlClient){
    如果(!sHasRemoteControlAPIs){
        返回;
    }

    尝试 {
        sUnregisterRemoteControlClientMethod.invoke(audioManager,
                remoteControlClient.getActualRemoteControlClientObject());
    }赶上(例外五){
        Log.e(TAG,e.getMessage(),E);
    }
}
}
 
30个简单,节省时间的设计工具

要更改lockPlayer国家dinamicaly:

 私人无效lockontrolsPlay(){
        如果(mRemoteControlClientCompat!= NULL){
            mRemoteControlClientCompat
                    .setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
        }
    }

    私人无效lockontrolsPause(){
        如果(mRemoteControlClientCompat!= NULL){
            mRemoteControlClientCompat
                    .setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
        }
    }
 

接收器:

 公共类MusicIntentReceiver扩展WakefulBroadcastReceiver {
私人诠释headsetSwitch = 1;


@覆盖
公共无效的onReceive(上下文的背景下,意图意图){


    如果(intent.getAction()。等于(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)){


        Toast.makeText(上下文,MyApplication.getContext()getResources()的getString(R.string.aptxt15),Toast.LENGTH_SHORT。).show();
        意图=新的意图(背景下,ReproductorDialog.ServicioCanciones.class);
        intent.putExtra(do_action,pause_cascos);
        context.startService(意向);


    }否则,如果(intent.getAction()。等于(Intent.ACTION_MEDIA_BUTTON)){

        的KeyEvent的keyEvent =(KeyEvent的)intent.getExtras()得到(Intent.EXTRA_KEY_EVENT)。
        如果(keyEvent.getAction()!= KeyEvent.ACTION_DOWN)
            返回;

        开关(keyEvent.getKey code()){
            案例KeyEvent.KEY code_HEADSETHOOK:


            案例KeyEvent.KEY code_MEDIA_PLAY_PAUSE:
                意图=新的意图(背景下,ReproductorDialog.ServicioCanciones.class);
                intent.putExtra(do_action,暂停);
                context.startService(意向);
                // context.startService(新意图(MusicService.ACTION_TOGGLE_PLAYBACK));
                打破;
            案例KeyEvent.KEY code_MEDIA_PLAY:
                // context.startService(新意图(MusicService.ACTION_PLAY));
                意图=新的意图(背景下,ReproductorDialog.ServicioCanciones.class);
                intent.putExtra(do_action,暂停);
                context.startService(意向);
                打破;
            案例KeyEvent.KEY code_MEDIA_PAUSE:
                // context.startService(新意图(MusicService.ACTION_PAUSE));
                意图=新的意图(背景下,ReproductorDialog.ServicioCanciones.class);
                intent.putExtra(do_action,暂停);
                context.startService(意向);
                打破;
            案例KeyEvent.KEY code_MEDIA_STOP:
                // context.startService(新意图(MusicService.ACTION_STOP));
                打破;
            案例KeyEvent.KEY code_MEDIA_NEXT:
                意图=新的意图(背景下,ReproductorDialog.ServicioCanciones.class);
                intent.putExtra(do_action,下一步);
                context.startService(意向);
                打破;
            案例KeyEvent.KEY code_MEDIA_ preVIOUS:
                // TODO:确保在快速连续这样做实际上扮演
                // previous歌曲
                // context.startService(新意图(MusicService.ACTION_REWIND));
                意图=新的意图(背景下,ReproductorDialog.ServicioCanciones.class);
                intent.putExtra(do_action,previous);
                context.startService(意向);
                打破;
        }
    }
}
}
 

mAUdioManager是AudioManager objectand mMediaButtonReceiverComponent是一个组件名,干脆把

  AudioManager mAudioManager;
组件名mMediaButtonReceiverComponent;
 

调用方法lockScreenControls()之前。这些类的API 18

I am developing a music player. I have a widget that works on both the home and lock screen. I do not want to give the user the option to put or remove the widget from the lock screen.

My goal is:

The widget automatically appears on the host lock screen, removing the widget that there are as time-date widget, or putting over its.

Managing MusicService and Widget consistently. (Clear the widget from lock-screen when I leave the music player.     That is exactly how the Google Play Music widget on my Galaxy Nexus (or many other phones). Is this possible? Is it possible that I need something that is not a widget, like custom lock screen?

解决方案

Well, the solution was simple, do not use any widget, simply use the RemoteControlClientCompat class. Here is my lockScreenControls() method code , which I call whenever I want to show this type of control.

private void lockScreenControls() {

        // Use the media button APIs (if available) to register ourselves for media button
        // events

        MediaButtonHelper.registerMediaButtonEventReceiverCompat(mAudioManager, mMediaButtonReceiverComponent);
        // Use the remote control APIs (if available) to set the playback state
        if (mRemoteControlClientCompat == null) {
            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
            intent.setComponent(mMediaButtonReceiverComponent);
            mRemoteControlClientCompat = new RemoteControlClientCompat(PendingIntent.getBroadcast(this /*context*/,0 /*requestCode, ignored*/, intent /*intent*/, 0 /*flags*/));
            RemoteControlHelper.registerRemoteControlClient(mAudioManager,mRemoteControlClientCompat);
        }
        mRemoteControlClientCompat.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
        mRemoteControlClientCompat.setTransportControlFlags(
                RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
                RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS |
                RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
                RemoteControlClient.FLAG_KEY_MEDIA_STOP);

        //update remote controls
        mRemoteControlClientCompat.editMetadata(true)
                .putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, "NombreArtista")
                .putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, "Titulo Album")
                .putString(MediaMetadataRetriever.METADATA_KEY_TITLE, nombreCancion)
                //.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION,playingItem.getDuration())
                        // TODO: fetch real item artwork
                .putBitmap(RemoteControlClientCompat.MetadataEditorCompat.METADATA_KEY_ARTWORK, getAlbumArt())
                .apply();
        }
    }

***********EDIT************

RemoteControlClientCompat class:

@SuppressWarnings({"rawtypes", "unchecked"})
public class RemoteControlClientCompat {

private static final String TAG = "RemoteControlCompat";

private static Class sRemoteControlClientClass;

// RCC short for RemoteControlClient
private static Method sRCCEditMetadataMethod;
private static Method sRCCSetPlayStateMethod;
private static Method sRCCSetTransportControlFlags;

private static boolean sHasRemoteControlAPIs = false;

static {
    try {
        ClassLoader classLoader = RemoteControlClientCompat.class.getClassLoader();
        sRemoteControlClientClass = getActualRemoteControlClientClass(classLoader);
        // dynamically populate the playstate and flag values in case they change
        // in future versions.
        for (Field field : RemoteControlClientCompat.class.getFields()) {
            try {
                Field realField = sRemoteControlClientClass.getField(field.getName());
                Object realValue = realField.get(null);
                field.set(null, realValue);
            } catch (NoSuchFieldException e) {
                Log.w(TAG, "Could not get real field: " + field.getName());
            } catch (IllegalArgumentException e) {
                Log.w(TAG, "Error trying to pull field value for: " + field.getName()
                        + " " + e.getMessage());
            } catch (IllegalAccessException e) {
                Log.w(TAG, "Error trying to pull field value for: " + field.getName()
                        + " " + e.getMessage());
            }
        }

        // get the required public methods on RemoteControlClient
        sRCCEditMetadataMethod = sRemoteControlClientClass.getMethod("editMetadata",
                boolean.class);
        sRCCSetPlayStateMethod = sRemoteControlClientClass.getMethod("setPlaybackState",
                int.class);
        sRCCSetTransportControlFlags = sRemoteControlClientClass.getMethod(
                "setTransportControlFlags", int.class);

        sHasRemoteControlAPIs = true;
    } catch (ClassNotFoundException e) {
        // Silently fail when running on an OS before ICS.
    } catch (NoSuchMethodException e) {
        // Silently fail when running on an OS before ICS.
    } catch (IllegalArgumentException e) {
        // Silently fail when running on an OS before ICS.
    } catch (SecurityException e) {
        // Silently fail when running on an OS before ICS.
    }
}

public static Class getActualRemoteControlClientClass(ClassLoader classLoader)
        throws ClassNotFoundException {
    return classLoader.loadClass("android.media.RemoteControlClient");
}

private Object mActualRemoteControlClient;

public RemoteControlClientCompat(PendingIntent pendingIntent) {
    if (!sHasRemoteControlAPIs) {
        return;
    }
    try {
        mActualRemoteControlClient =
                sRemoteControlClientClass.getConstructor(PendingIntent.class)
                        .newInstance(pendingIntent);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public RemoteControlClientCompat(PendingIntent pendingIntent, Looper looper) {
    if (!sHasRemoteControlAPIs) {
        return;
    }

    try {
        mActualRemoteControlClient =
                sRemoteControlClientClass.getConstructor(PendingIntent.class, Looper.class)
                        .newInstance(pendingIntent, looper);
    } catch (Exception e) {
        Log.e(TAG, "Error creating new instance of " + sRemoteControlClientClass.getName(), e);
    }
}

/**
 * Class used to modify metadata in a {@link android.media.RemoteControlClient} object. Use
 * {@link android.media.RemoteControlClient#editMetadata(boolean)} to create an instance of an
 * editor, on which you set the metadata for the RemoteControlClient instance. Once all the
 * information has been set, use {@link #apply()} to make it the new metadata that should be
 * displayed for the associated client. Once the metadata has been "applied", you cannot reuse
 * this instance of the MetadataEditor.
 */
public class MetadataEditorCompat {

    private Method mPutStringMethod;
    private Method mPutBitmapMethod;
    private Method mPutLongMethod;
    private Method mClearMethod;
    private Method mApplyMethod;

    private Object mActualMetadataEditor;

    /**
     * The metadata key for the content artwork / album art.
     */
    public final static int METADATA_KEY_ARTWORK = 100;

    private MetadataEditorCompat(Object actualMetadataEditor) {
        if (sHasRemoteControlAPIs && actualMetadataEditor == null) {
            throw new IllegalArgumentException("Remote Control API's exist, " +
                    "should not be given a null MetadataEditor");
        }
        if (sHasRemoteControlAPIs) {
            Class metadataEditorClass = actualMetadataEditor.getClass();

            try {
                mPutStringMethod = metadataEditorClass.getMethod("putString",
                        int.class, String.class);
                mPutBitmapMethod = metadataEditorClass.getMethod("putBitmap",
                        int.class, Bitmap.class);
                mPutLongMethod = metadataEditorClass.getMethod("putLong",
                        int.class, long.class);
                mClearMethod = metadataEditorClass.getMethod("clear", new Class[]{});
                mApplyMethod = metadataEditorClass.getMethod("apply", new Class[]{});
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        mActualMetadataEditor = actualMetadataEditor;
    }

    /**
     * Adds textual information to be displayed.
     * Note that none of the information added after {@link #apply()} has been called,
     * will be displayed.
     * @param key The identifier of a the metadata field to set. Valid values are
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
     * @param value The text for the given key, or {@code null} to signify there is no valid
     *      information for the field.
     * @return Returns a reference to the same MetadataEditor object, so you can chain put
     *      calls together.
     */
    public MetadataEditorCompat putString(int key, String value) {
        if (sHasRemoteControlAPIs) {
            try {
                mPutStringMethod.invoke(mActualMetadataEditor, key, value);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        return this;
    }

    /**
     * Sets the album / artwork picture to be displayed on the remote control.
     * @param key the identifier of the bitmap to set. The only valid value is
     *      {@link #METADATA_KEY_ARTWORK}
     * @param bitmap The bitmap for the artwork, or null if there isn't any.
     * @return Returns a reference to the same MetadataEditor object, so you can chain put
     *      calls together.
     * @throws IllegalArgumentException
     * @see android.graphics.Bitmap
     */
    public MetadataEditorCompat putBitmap(int key, Bitmap bitmap) {
        if (sHasRemoteControlAPIs) {
            try {
                mPutBitmapMethod.invoke(mActualMetadataEditor, key, bitmap);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        return this;
    }

    /**
     * Adds numerical information to be displayed.
     * Note that none of the information added after {@link #apply()} has been called,
     * will be displayed.
     * @param key the identifier of a the metadata field to set. Valid values are
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
     *      expressed in milliseconds),
     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
     * @param value The long value for the given key
     * @return Returns a reference to the same MetadataEditor object, so you can chain put
     *      calls together.
     * @throws IllegalArgumentException
     */
    public MetadataEditorCompat putLong(int key, long value) {
        if (sHasRemoteControlAPIs) {
            try {
                mPutLongMethod.invoke(mActualMetadataEditor, key, value);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        return this;
    }

    /**
     * Clears all the metadata that has been set since the MetadataEditor instance was
     * created with {@link android.media.RemoteControlClient#editMetadata(boolean)}.
     */
    public void clear() {
        if (sHasRemoteControlAPIs) {
            try {
                mClearMethod.invoke(mActualMetadataEditor, (Object[]) null);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
    }

    /**
     * Associates all the metadata that has been set since the MetadataEditor instance was
     * created with {@link android.media.RemoteControlClient#editMetadata(boolean)}, or since
     * {@link #clear()} was called, with the RemoteControlClient. Once "applied", this
     * MetadataEditor cannot be reused to edit the RemoteControlClient's metadata.
     */
    public void apply() {
        if (sHasRemoteControlAPIs) {
            try {
                mApplyMethod.invoke(mActualMetadataEditor, (Object[]) null);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
    }
}

/**
 * Creates a {@link android.media.RemoteControlClient.MetadataEditor}.
 * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that
 *     was previously applied to the RemoteControlClient, or true if it is to be created empty.
 * @return a new MetadataEditor instance.
 */
public MetadataEditorCompat editMetadata(boolean startEmpty) {
    Object metadataEditor;
    if (sHasRemoteControlAPIs) {
        try {
            metadataEditor = sRCCEditMetadataMethod.invoke(mActualRemoteControlClient,
                    startEmpty);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    } else {
        metadataEditor = null;
    }
    return new MetadataEditorCompat(metadataEditor);
}

/**
 * Sets the current playback state.
 * @param state The current playback state, one of the following values:
 *       {@link android.media.RemoteControlClient#PLAYSTATE_STOPPED},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_PAUSED},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_PLAYING},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_FAST_FORWARDING},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_REWINDING},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_BUFFERING},
 *       {@link android.media.RemoteControlClient#PLAYSTATE_ERROR}.
 */
public void setPlaybackState(int state) {
    if (sHasRemoteControlAPIs) {
        try {
            sRCCSetPlayStateMethod.invoke(mActualRemoteControlClient, state);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

/**
 * Sets the flags for the media transport control buttons that this client supports.
 * @param transportControlFlags A combination of the following flags:
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD},
 *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT}
 */
public void setTransportControlFlags(int transportControlFlags) {
    if (sHasRemoteControlAPIs) {
        try {
            sRCCSetTransportControlFlags.invoke(mActualRemoteControlClient,
                    transportControlFlags);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

public final Object getActualRemoteControlClientObject() {
    return mActualRemoteControlClient;
}
}

RemoteControlHelper class:

public class RemoteControlHelper {
private static final String TAG = "RemoteControlHelper";

private static boolean sHasRemoteControlAPIs = false;

private static Method sRegisterRemoteControlClientMethod;
private static Method sUnregisterRemoteControlClientMethod;

static {
    try {
        ClassLoader classLoader = RemoteControlHelper.class.getClassLoader();
        Class sRemoteControlClientClass =
                RemoteControlClientCompat.getActualRemoteControlClientClass(classLoader);
        sRegisterRemoteControlClientMethod = AudioManager.class.getMethod(
                "registerRemoteControlClient", new Class[]{sRemoteControlClientClass});
        sUnregisterRemoteControlClientMethod = AudioManager.class.getMethod(
                "unregisterRemoteControlClient", new Class[]{sRemoteControlClientClass});
        sHasRemoteControlAPIs = true;
    } catch (ClassNotFoundException e) {
        // Silently fail when running on an OS before ICS.
    } catch (NoSuchMethodException e) {
        // Silently fail when running on an OS before ICS.
    } catch (IllegalArgumentException e) {
        // Silently fail when running on an OS before ICS.
    } catch (SecurityException e) {
        // Silently fail when running on an OS before ICS.
    }
}

public static void registerRemoteControlClient(AudioManager audioManager,
                                               RemoteControlClientCompat remoteControlClient) {
    if (!sHasRemoteControlAPIs) {
        return;
    }

    try {
        sRegisterRemoteControlClientMethod.invoke(audioManager,
                remoteControlClient.getActualRemoteControlClientObject());
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
    }
}


public static void unregisterRemoteControlClient(AudioManager audioManager,
                                                 RemoteControlClientCompat remoteControlClient) {
    if (!sHasRemoteControlAPIs) {
        return;
    }

    try {
        sUnregisterRemoteControlClientMethod.invoke(audioManager,
                remoteControlClient.getActualRemoteControlClientObject());
    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
    }
}
}

To Change lockPlayer State dinamicaly:

 private void lockontrolsPlay() {
        if (mRemoteControlClientCompat != null) {
            mRemoteControlClientCompat
                    .setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
        }
    }

    private void lockontrolsPause() {
        if (mRemoteControlClientCompat != null) {
            mRemoteControlClientCompat
                    .setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
        }
    }

The receiver:

public class MusicIntentReceiver extends WakefulBroadcastReceiver {
private int headsetSwitch = 1;


@Override
public void onReceive(Context context, Intent intent) {


    if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {


        Toast.makeText(context, MyApplication.getContext().getResources().getString (R.string.aptxt15), Toast.LENGTH_SHORT).show();
        intent = new Intent(context, ReproductorDialog.ServicioCanciones.class);
        intent.putExtra("do_action", "pause_cascos");
        context.startService(intent);


    } else if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {

        KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT);
        if (keyEvent.getAction() != KeyEvent.ACTION_DOWN)
            return;

        switch (keyEvent.getKeyCode()) {
            case KeyEvent.KEYCODE_HEADSETHOOK:


            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                intent = new Intent(context, ReproductorDialog.ServicioCanciones.class);
                intent.putExtra("do_action", "pause");
                context.startService(intent);
                //   context.startService(new Intent(MusicService.ACTION_TOGGLE_PLAYBACK));
                break;
            case KeyEvent.KEYCODE_MEDIA_PLAY:
                //  context.startService(new Intent(MusicService.ACTION_PLAY));
                intent = new Intent(context, ReproductorDialog.ServicioCanciones.class);
                intent.putExtra("do_action", "pause");
                context.startService(intent);
                break;
            case KeyEvent.KEYCODE_MEDIA_PAUSE:
                //  context.startService(new Intent(MusicService.ACTION_PAUSE));
                intent = new Intent(context, ReproductorDialog.ServicioCanciones.class);
                intent.putExtra("do_action", "pause");
                context.startService(intent);
                break;
            case KeyEvent.KEYCODE_MEDIA_STOP:
                //  context.startService(new Intent(MusicService.ACTION_STOP));
                break;
            case KeyEvent.KEYCODE_MEDIA_NEXT:
                intent = new Intent(context, ReproductorDialog.ServicioCanciones.class);
                intent.putExtra("do_action", "next");
                context.startService(intent);
                break;
            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
                // TODO: ensure that doing this in rapid succession actually plays the
                // previous song
                //   context.startService(new Intent(MusicService.ACTION_REWIND));
                intent = new Intent(context, ReproductorDialog.ServicioCanciones.class);
                intent.putExtra("do_action", "previous");
                context.startService(intent);
                break;
        }
    }
}
}

mAUdioManager is an AudioManager objectand mMediaButtonReceiverComponent is a ComponentName, simply put

AudioManager mAudioManager; 
ComponentName mMediaButtonReceiverComponent;

before call method lockScreenControls(). These Classes are on API 18