SimpleMobileTools / Simple-Music-Player

A clean music player with a customizable widget, stylish interface and no ads.
https://www.simplemobiletools.com
GNU General Public License v3.0
1.28k stars 407 forks source link

QUESTION: Fake Media Player #236

Closed ricardojlrufino closed 4 years ago

ricardojlrufino commented 4 years ago

I need interact with bluetooth media buttons (miband4), but not for audio playing, but for another purpose. It is possible ? Sorry for unrelated question.

My test: The media Metadata is showing in external bluetoth (miband). But then i clink in play or pause, this not catching events.

My log shows:

2020-01-30 22:40:35.180 2021-2968/? D/MediaSessionService: Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=66885018, downTime=66885018, deviceId=-1, source=0x0 } to the last known PendingIntent PendingIntent{a867d3e: PendingIntentRecord{160679f com.google.android.youtube broadcastIntent}}
ricardojlrufino commented 4 years ago

Code

package io.opendevice.miband;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.os.IBinder;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.view.KeyEvent;

public class FakePlayerService extends Service {

    private MediaSessionCompat mediaSession;

    @Override
    public void onCreate() {
        super.onCreate();
        ComponentName receiver = new ComponentName(getPackageName(), RemoteReceiver.class.getName());
        mediaSession = new MediaSessionCompat(this, "PlayerService", receiver, null);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
                MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
                .setState(PlaybackStateCompat.STATE_PLAYING, 5000, 1)
                .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE)
                .build());
        mediaSession.setMetadata(new MediaMetadataCompat.Builder()
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Test Artist")
                .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "Test Album")
                .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Test Track Name")
                .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 10000)
                .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART,
                        BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                .build());

        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {
                // Ignore
                System.out.println("request audio focussssssssssss");
            }
        }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
        mediaSession.setActive(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mediaSession.getController().getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING) {
            mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
                    .setState(PlaybackStateCompat.STATE_PAUSED, 0, 0.0f)
                    .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
        } else {
            mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
                    .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
                    .setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE).build());
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mediaSession.release();
    }

    public static class RemoteReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
                final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

                if (event != null && event.getAction() == KeyEvent.ACTION_DOWN) {
                    switch (event.getKeyCode()) {
                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                            context.startService(new Intent(context, FakePlayerService.class));
                            break;
                    }
                }
            }
        }
    }
}

Manifest

<service
            android:name=".FakePlayerService"
            android:exported="false">
            <intent-filter>
                <action android:name="android.media.browse.MediaBrowserService" />
                <action android:name="com.simplemobiletools.musicplayer.action.INIT"/>
                <action android:name="com.simplemobiletools.musicplayer.action.INIT_PATH"/>
                <action android:name="com.simplemobiletools.musicplayer.action.SETUP"/>
                <action android:name="com.simplemobiletools.musicplayer.action.FINISH"/>
                <action android:name="com.simplemobiletools.musicplayer.action.PREVIOUS"/>
                <action android:name="com.simplemobiletools.musicplayer.action.PAUSE"/>
                <action android:name="com.simplemobiletools.musicplayer.action.PLAYPAUSE"/>
                <action android:name="com.simplemobiletools.musicplayer.action.NEXT"/>
                <action android:name="com.simplemobiletools.musicplayer.action.RESET"/>
                <action android:name="com.simplemobiletools.musicplayer.action.EDIT"/>
                <action android:name="com.simplemobiletools.musicplayer.action.PLAYPOS"/>
                <action android:name="com.simplemobiletools.musicplayer.action.REFRESH_LIST"/>
                <action android:name="com.simplemobiletools.musicplayer.action.SET_PROGRESS"/>
                <action android:name="com.simplemobiletools.musicplayer.action.SKIP_BACKWARD"/>
                <action android:name="com.simplemobiletools.musicplayer.action.SKIP_FORWARD"/>
                <action android:name="com.simplemobiletools.musicplayer.action.REMOVE_CURRENT_SONG"/>
                <action android:name="com.simplemobiletools.musicplayer.action.REMOVE_SONG_IDS"/>
            </intent-filter>
        </service>
ricardojlrufino commented 4 years ago

After making a simple play song, now events are send to my app

mPlayer = MediaPlayer.create(this, R.raw.beep_02); mPlayer.start();

2020-01-31 01:03:31.350 3230-3230/? V/Avrcp_ext: recordKeyDispatched: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=74663823, downTime=74663823, deviceId=-1, source=0x0 } dispatched to io.opendevice.miband

But it is no getting this event: On main activity i tried: onKeyDown(int keyCode, KeyEvent event) and public boolean onKeyUp(int keyCode, KeyEvent event)

tibbi commented 4 years ago

Im not giving developer support, you can see the source code of the app