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;