Android操作系统Music源码修改:把包名,各种命名都修改成自己的

修改Android操作系统Music源码,把后台播放核心服务对外暴漏:
<!-- 核心服务 --> <!-- 定义对外暴露的配置 android:exported="true" android:process=":remote" android:enabled="true" --> <service android:name="liudeli.music2.service.MediaPlaybackService" android:exported="true" android:process=":remote" android:enabled="true"> <intent-filter> <!-- 定义对外暴露的 唯一标示 --> <action android:name="liudeli.custom.system.music.backplay.service" /> </intent-filter> </service>
阅读Android操作系统Music源码的AIDL:

// IMediaPlaybackService.aidl package liudeli.music2.service; // Declare any non-default types here with import statements import android.graphics.Bitmap; interface IMediaPlaybackService { void openFile(String path); void open(in long [] list, int position); int getQueuePosition(); boolean isPlaying(); void stop(); void pause(); void play(); void prev(); void next(); long duration(); long position(); long seek(long pos); String getTrackName(); String getAlbumName(); long getAlbumId(); String getArtistName(); long getArtistId(); void enqueue(in long [] list, int action); long [] getQueue(); void moveQueueItem(int from, int to); void setQueuePosition(int index); String getPath(); long getAudioId(); void setShuffleMode(int shufflemode); int getShuffleMode(); int removeTracks(int first, int last); int removeTrack(long id); void setRepeatMode(int repeatmode); int getRepeatMode(); int getMediaMountedCount(); int getAudioSessionId(); String getLyricPath(); String getArtistPath(); }
阅读Android操作系统核心后台播放服务:

经过阅读Android操作系统Music源码发现,系统Music播放音乐采用来MediaPlaybackService服务来处理复杂的音乐播放逻辑,还用来AIDL来接口控制播放
既然如此,我就修改AndroidManifest.xml--->MediaPlaybackService服务,对外暴露,⚠️注意:暴露的时候,action:name="必须唯一"
-------------------- 以下代码是创建一个Android工程,来访问操作系统Music播放服务来播放音乐🎵
新创建的工程和操作系统Music工程的AIDL保存一致(包名 所以 都要一模一样):

绑定操心系统服务,并播放音乐🎵:
package liudeli.service1; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; import liudeli.music2.service.IMediaPlaybackService; public class PlaySystemMusicActivity extends Activity { private final String TAG = PlaySystemMusicActivity.class.getSimpleName(); private TextView tvMusicStatue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_play_system_music); // 绑定操作系统Music的服务 Intent intent = new Intent(); intent.setAction("liudeli.custom.system.music.backplay.service"); intent.setPackage("liudeli.music2"); bindService(intent, conn, BIND_AUTO_CREATE); alterShow("操作系统Music的服务绑定成功"); tvMusicStatue = findViewById(R.id.tv_music_statue); } private IMediaPlaybackService iMediaPlaybackService; /** * 操作系统Music的服务接口 */ private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 代理对象转换 iMediaPlaybackService = IMediaPlaybackService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; public void playMusic(View view) { if (null != iMediaPlaybackService) { try { String path = iMediaPlaybackService.getPath(); iMediaPlaybackService.openFile(path); iMediaPlaybackService.play(); Log.d(TAG, " path:" + path); /*iMediaPlaybackService.openFile(path); iMediaPlaybackService.play();*/ updateMusicStatus(); } catch (RemoteException e) { e.printStackTrace(); } } } public void pauseMusic(View view) { if (null != iMediaPlaybackService) { try{ if (!iMediaPlaybackService.isPlaying()) { alterShow("操作系统的Music还没有播放呢,还不能暂停哦"); return; } iMediaPlaybackService.pause(); }catch (Exception e) { e.printStackTrace(); } } } public void continueMusic(View view) { if (null != iMediaPlaybackService) { try{ if (iMediaPlaybackService.isPlaying()) { alterShow("操作系统的Music播放中,不能继续播放"); return; } iMediaPlaybackService.play(); }catch (Exception e) { e.printStackTrace(); } } } public void stopMusic(View view) { if (null != iMediaPlaybackService) { try{ if (!iMediaPlaybackService.isPlaying()) { alterShow("操作系统的Music还没有播放呢,还不能停止哦"); return; } iMediaPlaybackService.stop(); }catch (Exception e){ e.printStackTrace(); } } } public void prevMusic(View view) { if (null != iMediaPlaybackService) { try { iMediaPlaybackService.prev(); } catch (RemoteException e) { e.printStackTrace(); } } } public void nextMusic(View view) { if (null != iMediaPlaybackService) { try { iMediaPlaybackService.next(); } catch (RemoteException e) { e.printStackTrace(); } } } public void test(View view) { if (null != iMediaPlaybackService) { try { long duration = iMediaPlaybackService.duration(); long position = iMediaPlaybackService.position(); /*iMediaPlaybackService.seek(position +=10); long[] queues = iMediaPlaybackService.getQueue(); for (long queue : queues) { Log.d(TAG, "queue:" + queue); } Random random = new Random(queues.length); iMediaPlaybackService.setQueuePosition(random.nextInt());*/ String trackName = iMediaPlaybackService.getTrackName(); String albumName = iMediaPlaybackService.getAlbumName(); Log.d(TAG, "duration:" + duration + " position:" + position + " trackName:" + trackName + " albumName:" + albumName); } catch (RemoteException e) { e.printStackTrace(); } } } @Override protected void onDestroy() { super.onDestroy(); unbindService(conn); alterShow("操作系统Music的服务解绑成功"); } private void alterShow(String text) { Toast.makeText(PlaySystemMusicActivity.this, text, Toast.LENGTH_LONG).show(); } private synchronized void updateMusicStatus() throws RemoteException{ long duration = iMediaPlaybackService.duration(); long position = iMediaPlaybackService.position(); String trackName = iMediaPlaybackService.getTrackName(); String albumName = iMediaPlaybackService.getAlbumName(); String aristName = iMediaPlaybackService.getArtistName(); tvMusicStatue.setText("歌曲时长:" + timeParse(duration) + " ,目前播放:" + timeParse(position) + " ,歌曲:" + trackName + " ,专辑:" + albumName + " ,歌手:" + aristName); new Handler().postDelayed(new Runnable() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { try { updateMusicStatus(); } catch (RemoteException e) { e.printStackTrace(); } } }); } },1000); } /** * Android 音乐播放器应用里,读出的音乐时长为 long 类型以毫秒数为单位, * 例如:将 234736 转化为分钟和秒应为 03:55 (包含四舍五入) * @param duration 音乐时长 * @return */ public String timeParse(long duration) { String time = "" ; long minute = duration / 60000 ; long seconds = duration % 60000 ; long second = Math.round((float)seconds/1000) ; if( minute < 10 ){ time += "0" ; } time += minute+":" ; if( second < 10 ){ time += "0" ; } time += second ; return time ; } }
Layout相关:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放操作系统Music中的音乐" android:onClick="playMusic" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="暂停操作系统Music中的音乐" android:onClick="pauseMusic" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="继续播放操作系统Music中的音乐" android:onClick="continueMusic" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止操作系统Music中的音乐" android:onClick="stopMusic" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="prevMusic" android:text="上一曲" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="nextMusic" android:text="下一曲" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="test" android:text="test" android:visibility="gone" /> </LinearLayout> <TextView android:id="@+id/tv_music_statue" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="还没有播放歌曲"/> </LinearLayout>
完成✅去 bind 操作系统Music来播放音乐:

请看,我播放原生Android操作系统Music的图标:

请看,我调用Android操作系统Music后显示的图标:

Android操作系统Music暂停后 图标消失
我的应用暂停后,图标也会消失,我完全是在使用Android操作系统Music里面的播放处理逻辑
浙公网安备 33010602011771号