diff --git a/.safedk/app_sdks.lst b/.safedk/app_sdks.lst
new file mode 100644
index 0000000..4c6ef96
--- /dev/null
+++ b/.safedk/app_sdks.lst
@@ -0,0 +1,28 @@
+a787e8e868e0962815f613634aaa7623
+106f9be0e66f52f36eaaaff4dd231971
+75939c4ce23c53ad9534d43be176b3e9
+217e8f437c9fc4244d6e74653ac8a8c7
+66b774de6608db14a84e972fba1ec954
+e1c9ddef73e5621f62c717badf1be3f2
+daaea35726ab7cd457ab61d4538fb822
+b9b88d70c3d018bfbda46cd93ba3ddca
+946dbe0d5ed7fee91c8ece64d035e70b
+213ac5b6803852323d73a1292440d7be
+d41ed920405e4bd14f3a42cd93c43d89
+7eac188d3286b05ccbba774f63a2c049
+4df96d3bc9afd17b812e65e6c6add1ef
+9f5a74f6ccfb81b48969231b39bf937f
+eb3214f29c0a52815b41977d6cc9a46e
+becf75b2cc99e82716da2e6697879509
+7eec7b9476b99b3ce94533da4f2eb987
+974322f19d813702ea048d95288d2b8c
+95ff573e4cdf46a05f6c5ac703940db3
+f281c2ca1b0ba69b5805badd314ef646
+29015bbfcc182d80e7f75bd2c38e4521
+ff22dbf67af979b8b3169a242d10f166
+c4d1f1775f251f03dce94fdf267a7b89
+dd2971b0681141d57b221687791ad1bd
+86a0d598cde251321e21a0da4ab94065
+74616804a7dc29147dfb0afe122a9fd2
+35695de726f6044576c830bf197f36f7
+
diff --git a/.safedk/dex/SafeDKAndroid-6.6.2.dex b/.safedk/dex/SafeDKAndroid-6.6.2.dex
new file mode 100644
index 0000000..007bf30
Binary files /dev/null and b/.safedk/dex/SafeDKAndroid-6.6.2.dex differ
diff --git a/.safedk/hashes.safedk b/.safedk/hashes.safedk
new file mode 100644
index 0000000..5852668
--- /dev/null
+++ b/.safedk/hashes.safedk
@@ -0,0 +1,2 @@
+#Fri Nov 22 12:07:09 CST 2024
+json=-514815800
diff --git a/.safedk/plugin.properties b/.safedk/plugin.properties
new file mode 100644
index 0000000..daebed3
--- /dev/null
+++ b/.safedk/plugin.properties
@@ -0,0 +1,5 @@
+#
+#Fri Nov 22 13:46:35 CST 2024
+4CFHxOfvQvy95EqDxa_eNPe4pmq_KfoZPJeVscTMt2uT3VL2fO3iyZyBFMTOOTRbKw6WelbaDEhNzxOxVrlQTE=tAh5Z8CtFiG05NfRWh9UuOHCp3h3SaFvlh6Phw5ucaxFMCRs2d97F7lywfBKOEKSipdaGq8vZOaDLZkrL1fDDc
+sdk_analysis_plugin_version=5.6.2
+set_multidex=true
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f282fca..dd3aea5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,13 +5,16 @@
-
+
+
+
+
+ android:exported="false"
+ android:screenOrientation="portrait" />
+ android:exported="false"
+ android:screenOrientation="portrait" />
+ android:exported="false"
+ android:screenOrientation="portrait" />
+ android:exported="false"
+ android:screenOrientation="portrait" />
+ android:exported="false"
+ android:screenOrientation="portrait" />
+ android:exported="false"
+ android:screenOrientation="portrait">
+ android:exported="true"
+ android:screenOrientation="portrait">
diff --git a/app/src/main/java/com/offline/music/playermp3/service/MusicPlayerForegroundService.java b/app/src/main/java/com/offline/music/playermp3/service/MusicPlayerForegroundService.java
index 40aa0f4..56f1f82 100644
--- a/app/src/main/java/com/offline/music/playermp3/service/MusicPlayerForegroundService.java
+++ b/app/src/main/java/com/offline/music/playermp3/service/MusicPlayerForegroundService.java
@@ -1,5 +1,6 @@
package com.offline.music.playermp3.service;
+import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -7,6 +8,7 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.net.Uri;
@@ -20,7 +22,9 @@ import android.util.Log;
import android.widget.Toast;
import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -88,35 +92,70 @@ public class MusicPlayerForegroundService extends Service {
}
startForeground(1, createNotification()); // 启动前台服务并显示通知
+ showNotification();
acquireWakeLock(); // 获取WakeLock
return START_NOT_STICKY; // 服务不会在被杀死后自动重启
}
- // 创建通知
- private Notification createNotification() {
- createNotificationChannel(); // 创建通知渠道
- Intent notificationIntent = new Intent(this, A_PlayActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_IMMUTABLE : 0); // 适配Android 12
+ public void showNotification() {
+ // 获取 Notification 对象
+ Notification notification = createNotification();
- return new NotificationCompat.Builder(this, CHANNEL_ID)
- .setContentTitle("Playing audio") // 通知标题
- .setContentText("Your audio is playing") // 通知内容
- .setSmallIcon(R.drawable.music_player_launch) // 小图标
- .setContentIntent(pendingIntent) // 点击通知的Intent
- .setPriority(NotificationCompat.PRIORITY_LOW) // 低优先级
- .build();
+ // 使用 NotificationManagerCompat 来显示通知
+ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
+
+ // 为每个通知提供唯一的 ID,以便以后可以更新或移除通知
+ int notificationId = 1; // 可以是任何唯一的 ID
+ if (ActivityCompat.checkSelfPermission(this, 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.
+ Log.d("----------", "Have no authority");
+ return;
+ }
+ notificationManager.notify(notificationId, notification);
+ }
+
+ private Notification createNotification() {
+ createNotificationChannel();
+
+ // 创建一个Intent,点击通知后跳转到 A_PlayActivity
+ Intent notificationIntent = new Intent(this, A_PlayActivity.class);
+ notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+ // 创建通知构建器
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
+ .setContentTitle("Offline Music Player") // 通知标题
+ .setContentText("Your audio is playing") // 通知内容
+ .setSmallIcon(R.drawable.home_select) // 小图标
+ .setPriority(NotificationCompat.PRIORITY_HIGH); // 优先级设置为高
+
+ // 设置展开样式(可选,根据需要)
+ builder.setStyle(new NotificationCompat.BigTextStyle()
+ .bigText("Your audio is playing in the background. Tap to go to the player activity."));
+
+ return builder.build();
}
- // 创建通知渠道
private void createNotificationChannel() {
+ // 仅在 Android 8.0(API 级别 26)及以上版本创建通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ // 创建通知渠道,设置重要性
NotificationChannel serviceChannel = new NotificationChannel(
- CHANNEL_ID, "Music player channel", NotificationManager.IMPORTANCE_LOW);
- NotificationManager manager = getSystemService(NotificationManager.class);
- if (manager != null) {
- manager.createNotificationChannel(serviceChannel); // 创建渠道
+ CHANNEL_ID, "Offline Music Player", NotificationManager.IMPORTANCE_HIGH); // 设置为高优先级
+
+ // 配置通知渠道的详细信息(如描述)
+ serviceChannel.setDescription("This is the channel for the music player notifications");
+
+ // 注册通知渠道
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ if (notificationManager != null) {
+ notificationManager.createNotificationChannel(serviceChannel);
}
}
}
@@ -134,7 +173,7 @@ public class MusicPlayerForegroundService extends Service {
// 初始化播放器
private void initializePlayer(String path) {
try {
- Log.d("MusicPlayerService", "正在初始化播放器,音频路径: " + path);
+ Log.d("MusicPlayerService", "Initializing the player, audio path: " + path);
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer(); // 创建新的MediaPlayer实例
}
@@ -168,7 +207,7 @@ public class MusicPlayerForegroundService extends Service {
// });
} catch (IOException | IllegalArgumentException | IllegalStateException e) {
- Log.e("MusicPlayerService", "初始化播放器失败,路径: " + path, e);
+ Log.e("MusicPlayerService", "Failed to initialize the player, path: " + path, e);
isPlaying.postValue(false); // 更新状态
stopSelf(); // 停止服务
}
@@ -193,8 +232,8 @@ public class MusicPlayerForegroundService extends Service {
throw new IOException("Unable to open the content URI: " + path);
}
} catch (SecurityException e) {
- Log.e("MusicPlayerService", "权限被拒绝,无法访问内容URI: " + path, e);
- throw new IOException("权限被拒绝", e); // 处理权限异常
+ Log.e("MusicPlayerService", "Permission denied, unable to access content URI: " + path, e);
+ throw new IOException("Permission denied", e); // 处理权限异常
}
}
@@ -224,7 +263,7 @@ public class MusicPlayerForegroundService extends Service {
// 如果找到了点,返回不带扩展名的文件名
return (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName;
} catch (Exception e) {
- Log.e("MusicPlayerService", "获取文件名失败", e);
+ Log.e("MusicPlayerService", "Failed to get file name", e);
return "Unknown file"; // 默认文件名
}
}
@@ -347,14 +386,14 @@ public class MusicPlayerForegroundService extends Service {
@Override
public void run() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
- Log.d("nowtotal","run222");
+ Log.d("nowtotal", "run222");
currentPosition.postValue(mediaPlayer.getCurrentPosition());
handler.postDelayed(this, 1000); // 每隔1秒更新一次
}
}
};
handler.post(runnable); // 启动更新
- Log.d("nowtotal","service");
+ Log.d("nowtotal", "service");
}
// 跳转到指定播放位置
diff --git a/app/src/main/java/com/offline/music/playermp3/ui/activity/A_HomeActivity.java b/app/src/main/java/com/offline/music/playermp3/ui/activity/A_HomeActivity.java
index 22fb294..c47dec6 100644
--- a/app/src/main/java/com/offline/music/playermp3/ui/activity/A_HomeActivity.java
+++ b/app/src/main/java/com/offline/music/playermp3/ui/activity/A_HomeActivity.java
@@ -1,13 +1,19 @@
package com.offline.music.playermp3.ui.activity;
+import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.Toast;
+
+import androidx.core.app.ActivityCompat;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
@@ -21,6 +27,7 @@ import com.offline.music.playermp3.service.MusicPlayerForegroundService;
import java.util.Locale;
public class A_HomeActivity extends BaseActivity {
+ private static final int PERMISSION_REQUEST_CODE = 1001;
public static MusicPlayerForegroundService musicService; // 音乐播放服务
private boolean isBound = false; // 服务是否绑定
@@ -54,10 +61,16 @@ public class A_HomeActivity extends BaseActivity {
@Override
protected void onCreateInit() {
- Intent serviceIntent = new Intent(this, MusicPlayerForegroundService.class);
- bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); // 绑定服务
- startService(serviceIntent);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, PERMISSION_REQUEST_CODE);
+ }
+ }
+
+ Intent serviceIntent = new Intent(this, MusicPlayerForegroundService.class);
+ startService(serviceIntent); // 启动音乐播放服务
+ bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); // 绑定服务
// 初始化界面
vb.homeContainer.setVisibility(View.GONE);
vb.pause.setOnClickListener(v -> togglePlayPause()); // 设置暂停/播放按钮点击事件
@@ -80,6 +93,22 @@ public class A_HomeActivity extends BaseActivity {
// 处理其他点击事件
}
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ if (requestCode == PERMISSION_REQUEST_CODE) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ Intent serviceIntent = new Intent(this, MusicPlayerForegroundService.class);
+ startService(serviceIntent); // 启动音乐播放服务
+ bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); // 绑定服务
+ } else {
+ Toast.makeText(this, "Notification permission is required to show notifications", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
@Override
public boolean isFullScreen() {
return true;