From a6672148c6bf7a386b724cfcc1352afd190a4e2f Mon Sep 17 00:00:00 2001
From: MUQING <1966944300@qq.com>
Date: Wed, 27 Dec 2023 12:13:53 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAndroid=2013=E7=9A=84?=
=?UTF-8?q?=E9=97=AA=E9=80=80=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 6 +-
.../main/java/com/muqingbfq/MediaPlayer.java | 2 +
app/src/main/java/com/muqingbfq/bfqkz.java | 41 +++++++--
.../java/com/muqingbfq/fragment/wode.java | 8 +-
app/src/main/java/com/muqingbfq/home.java | 88 +++++++++++++++++--
.../mq/NotificationManagerCompat.java | 33 ++++---
6 files changed, 142 insertions(+), 36 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cf7f148..a6e5cc9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -66,7 +66,11 @@
+ android:exported="false">
+
+
+
+
() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model,
diff --git a/app/src/main/java/com/muqingbfq/bfqkz.java b/app/src/main/java/com/muqingbfq/bfqkz.java
index 94f0b16..08fb333 100644
--- a/app/src/main/java/com/muqingbfq/bfqkz.java
+++ b/app/src/main/java/com/muqingbfq/bfqkz.java
@@ -1,17 +1,22 @@
package com.muqingbfq;
import android.annotation.SuppressLint;
-import android.app.Service;
+import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.TextUtils;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.media.MediaBrowserServiceCompat;
import com.muqingbfq.api.url;
import com.muqingbfq.mq.BluetoothMusicController;
@@ -22,7 +27,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-public class bfqkz extends Service {
+public class bfqkz extends MediaBrowserServiceCompat {
public static MediaPlayer mt = new MediaPlayer();
public static List list = new ArrayList<>();
public static List lishi_list = new ArrayList<>();
@@ -32,6 +37,7 @@ public class bfqkz extends Service {
public static boolean like_bool;
@SuppressLint("StaticFieldLeak")
public static com.muqingbfq.mq.NotificationManagerCompat notify;
+
public static int getmti(int s) {
int i = bfqkz.list.indexOf(xm);
if (s == 1) {
@@ -77,10 +83,12 @@ public class bfqkz extends Service {
public static class mp3 extends Thread {
String id;
+
public mp3(String id) {
this.id = id;
start();
}
+
@Override
public void run() {
super.run();
@@ -90,7 +98,6 @@ public class bfqkz extends Service {
public static MediaSessionCompat mSession;
- public static MediaMetadataCompat build;
public static PlaybackStateCompat playback;
@Override
@@ -98,15 +105,24 @@ public class bfqkz extends Service {
super.onCreate();
com.muqingbfq.api.playlist.hq_hc(bfqkz.lishi_list);
new BluetoothMusicController(this);
- mSession = new MediaSessionCompat(this, "MusicService");
playback = new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_NONE, 0, 1.0f)
.build();
+
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setComponent(new ComponentName(this, home.class));//用ComponentName得到class对象
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);// 关键的一步,设置启动模式,两种情况
+ PendingIntent pendingIntent = com.muqingbfq.mq.NotificationManagerCompat.getActivity(this, intent);
+ mSession = new MediaSessionCompat(this, "MusicService",
+ home.componentName, pendingIntent);
mSession.setCallback(new callback());
mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mSession.setPlaybackState(playback);
- mSession.setMetadata(build);
- mSession.setActive(true);
+// mSession.setActive(true);
+ setSessionToken(mSession.getSessionToken());
+
notify = new com.muqingbfq.mq.NotificationManagerCompat(this);
}
@@ -172,6 +188,17 @@ public class bfqkz extends Service {
public IBinder onBind(Intent intent) {
return null;
}
+
+ @Nullable
+ @Override
+ public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) {
+ return null;
+ }
+
+ @Override
+ public void onLoadChildren(@NonNull String parentId, @NonNull Result> result) {
+
+ }
/*
public class MyBinder extends Binder {
@@ -184,7 +211,7 @@ public class bfqkz extends Service {
public static void updateNotification() {
try {
// 更新通知栏的播放状态
- if (notify.notificationBuilder != null) {
+ if (bfqkz.notify != null && notify.notificationBuilder != null) {
notify.tzl();
}
} catch (Exception e) {
diff --git a/app/src/main/java/com/muqingbfq/fragment/wode.java b/app/src/main/java/com/muqingbfq/fragment/wode.java
index 9c3635f..388d04d 100644
--- a/app/src/main/java/com/muqingbfq/fragment/wode.java
+++ b/app/src/main/java/com/muqingbfq/fragment/wode.java
@@ -61,7 +61,12 @@ public class wode extends Fragment {
new user_message();
// int k = (int) (main.k / getResources().getDisplayMetrics().density + 0.5f);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4);
+ GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4){
+ @Override
+ public boolean canScrollVertically() {
+ return false;//禁止滑动
+ }
+ };
binding.recyclerview1.setLayoutManager(gridLayoutManager);
final Object[][] lista = {
{R.drawable.bf, "最近播放", "mp3_hc.json"},
@@ -73,6 +78,7 @@ public class wode extends Fragment {
{R.drawable.paihangbang, "排行榜", "排行榜"},
{R.drawable.icon, "开发中", ""}
};
+ binding.recyclerview1.setFocusable(false);
binding.recyclerview1.setAdapter(new RecyclerView.Adapter() {
@NonNull
@Override
diff --git a/app/src/main/java/com/muqingbfq/home.java b/app/src/main/java/com/muqingbfq/home.java
index 80fb3ee..835e6cc 100644
--- a/app/src/main/java/com/muqingbfq/home.java
+++ b/app/src/main/java/com/muqingbfq/home.java
@@ -1,10 +1,12 @@
package com.muqingbfq;
import android.annotation.SuppressLint;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
+import android.support.v4.media.MediaBrowserCompat;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
@@ -31,6 +33,8 @@ public class home extends AppCompatActivity {
@SuppressLint("StaticFieldLeak")
public static AppCompatActivity appCompatActivity;
ActivityHomeBinding binding;
+
+ public MediaBrowserCompat mBrowser;
@Override
protected void onCreate(Bundle savedInstanceState) {
appCompatActivity = this;
@@ -54,12 +58,16 @@ public class home extends AppCompatActivity {
com.muqingbfq.fragment.sz.switch_sz(home.this, item.getItemId());
return false;
});
+
//初始化播放器组件
// 启动Service
- if (serviceIntent == null) {
- serviceIntent = new Intent(this, bfqkz.class);
- startService(serviceIntent);
- }
+ componentName = new ComponentName(this, bfqkz.class);
+ mBrowser = new MediaBrowserCompat(
+ this,componentName
+ ,//绑定服务端
+ browserConnectionCallback,//设置连接回调
+ null
+ );
//检测更新
new gj.jianchagengxin(this);
binding.editView.setOnClickListener(view ->
@@ -70,14 +78,28 @@ public class home extends AppCompatActivity {
}
}
- List list = new ArrayList<>();
+ public static ComponentName componentName;
+ @Override
+ protected void onStart() {
+ super.onStart();
+ //Browser发送连接请求
+ mBrowser.connect();
+ }
+
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mBrowser.disconnect();
+ }
+
+ private final List list = new ArrayList<>();
private class adaper extends FragmentStateAdapter {
public adaper(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
list.add(new gd_adapter());
list.add(new wode());
}
-
@NonNull
@Override
public Fragment createFragment(int position) {
@@ -91,7 +113,6 @@ public class home extends AppCompatActivity {
public void UI() {
binding.viewPager.setAdapter(new adaper(this));
-
// 将 ViewPager2 绑定到 TabLayout
binding.tablayout.setOnItemSelectedListener(item -> {
int itemId = item.getItemId();
@@ -129,8 +150,6 @@ public class home extends AppCompatActivity {
}
});
}
-
- private static Intent serviceIntent;
@Override
protected void onPause() {
super.onPause();
@@ -182,4 +201,55 @@ public class home extends AppCompatActivity {
}
return super.onOptionsItemSelected(item);
}
+
+
+
+ /**
+ * 连接状态的回调接口,连接成功时会调用onConnected()方法
+ */
+ private MediaBrowserCompat.ConnectionCallback browserConnectionCallback=
+ new MediaBrowserCompat.ConnectionCallback(){
+ @Override
+ public void onConnected() {
+ //必须在确保连接成功的前提下执行订阅的操作
+ if (mBrowser.isConnected()) {
+ //mediaId即为MediaBrowserService.onGetRoot的返回值
+ //若Service允许客户端连接,则返回结果不为null,其值为数据内容层次结构的根ID
+ //若拒绝连接,则返回null
+ String mediaId = mBrowser.getRoot();
+
+ //Browser通过订阅的方式向Service请求数据,发起订阅请求需要两个参数,其一为mediaId
+ //而如果该mediaId已经被其他Browser实例订阅,则需要在订阅之前取消mediaId的订阅者
+ //虽然订阅一个 已被订阅的mediaId 时会取代原Browser的订阅回调,但却无法触发onChildrenLoaded回调
+
+ //ps:虽然基本的概念是这样的,但是Google在官方demo中有这么一段注释...
+ // This is temporary: A bug is being fixed that will make subscribe
+ // consistently call onChildrenLoaded initially, no matter if it is replacing an existing
+ // subscriber or not. Currently this only happens if the mediaID has no previous
+ // subscriber or if the media content changes on the service side, so we need to
+ // unsubscribe first.
+ //大概的意思就是现在这里还有BUG,即只要发送订阅请求就会触发onChildrenLoaded回调
+ //所以无论怎样我们发起订阅请求之前都需要先取消订阅
+ mBrowser.unsubscribe(mediaId);
+ //之前说到订阅的方法还需要一个参数,即设置订阅回调SubscriptionCallback
+ //当Service获取数据后会将数据发送回来,此时会触发SubscriptionCallback.onChildrenLoaded回调
+ mBrowser.subscribe(mediaId, browserSubscriptionCallback);
+ }
+ }
+
+ @Override
+ public void onConnectionFailed() {
+ gj.sc("连接失败!");
+ }
+ };
+ /**
+ * 向媒体服务器(MediaBrowserService)发起数据订阅请求的回调接口
+ */
+ private final MediaBrowserCompat.SubscriptionCallback browserSubscriptionCallback =
+ new MediaBrowserCompat.SubscriptionCallback(){
+ @Override
+ public void onChildrenLoaded(@NonNull String parentId,
+ @NonNull List children) {
+ }
+ };
}
\ No newline at end of file
diff --git a/app/src/main/java/com/muqingbfq/mq/NotificationManagerCompat.java b/app/src/main/java/com/muqingbfq/mq/NotificationManagerCompat.java
index 628252e..1580560 100644
--- a/app/src/main/java/com/muqingbfq/mq/NotificationManagerCompat.java
+++ b/app/src/main/java/com/muqingbfq/mq/NotificationManagerCompat.java
@@ -62,15 +62,9 @@ public class NotificationManagerCompat {
setAction("syq"));
pendingIntent_xyq = getBroadcast(context, my.
setAction("xyq"));
- // 取消操作的PendingIntent
-// 取消操作的PendingIntent
-/* PendingIntent cancelIntent = MediaButtonReceiver.buildMediaButtonPendingIntent(context,
- PlaybackStateCompat.ACTION_STOP);*/
style = new androidx.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0, 1, 2)
.setMediaSession(bfqkz.mSession.getSessionToken());
-// .setShowCancelButton(true)
-// .setCancelButtonIntent(cancelIntent);
notificationManager = androidx.core.app.NotificationManagerCompat.from(context);
notificationBuilder = getNotificationBuilder(context)
.setSmallIcon(R.drawable.icon)
@@ -96,11 +90,6 @@ public class NotificationManagerCompat {
name = bfqkz.xm.name;
zz = bfqkz.xm.zz;
}
- bfqkz.build = new MediaMetadataCompat.Builder()
- .putString(MediaMetadataCompat.METADATA_KEY_TITLE, name)
- .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, zz)
- .build();
- bfqkz.mSession.setMetadata(bfqkz.build);
notificationBuilder.mActions.clear();
notificationBuilder.addAction(android.R.drawable.ic_media_previous, "syq", pendingIntent_syq) // #0
.addAction(bfqkz.mt.isPlaying() ? android.R.drawable.ic_media_pause : android.R.drawable.ic_media_play
@@ -111,6 +100,7 @@ public class NotificationManagerCompat {
.setOngoing(bfqkz.mt.isPlaying());
notificationManager_notify();
}
+
private PendingIntent pendingIntent_kg,
pendingIntent_syq,
pendingIntent_xyq;
@@ -123,17 +113,22 @@ public class NotificationManagerCompat {
notificationManager.notify(1, notificationBuilder.build());
}
- @SuppressLint({"MissingPermission", "RestrictedApi", "NotifyDataSetChanged"})
public void setBitmap() {
- if (bfq.bitmap == null) {
- bfq.bitmap = BitmapFactory.decodeResource(context.getResources(),
- R.drawable.icon);
- }
+ Media.setImageBitmap();
if (notificationManager != null) {
+ if (ActivityCompat.checkSelfPermission(home.appCompatActivity, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ return;
+ }
notificationBuilder.setLargeIcon(bfq.bitmap);
notificationManager.notify(1, notificationBuilder.build());
}
- Media.setImageBitmap();
}
private NotificationCompat.Builder getNotificationBuilder(Context context) {
@@ -152,7 +147,9 @@ public class NotificationManagerCompat {
return PendingIntent.getBroadcast(context, 0, intent, flag);
}
- private PendingIntent getActivity(Context context, Intent intent) {
+
+
+ public static PendingIntent getActivity(Context context, Intent intent) {
int flag;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
flag = PendingIntent.FLAG_IMMUTABLE;