diff --git a/app/build.gradle b/app/build.gradle index 8831b0f..f4a6d05 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,7 +10,7 @@ android { minSdk 28 targetSdk 35 versionCode 116155 - versionName "1.16.15d" + versionName "1.16.1" multiDexEnabled false proguardFiles += 'proguard-rules.pro' buildConfigField 'String', 'HOOK_TARGET_VERSION', '"141910383"' diff --git a/app/src/main/java/io/github/hiro/lime/hooks/RingTone.java b/app/src/main/java/io/github/hiro/lime/hooks/RingTone.java index 51deecf..3bf96a3 100644 --- a/app/src/main/java/io/github/hiro/lime/hooks/RingTone.java +++ b/app/src/main/java/io/github/hiro/lime/hooks/RingTone.java @@ -6,6 +6,7 @@ import android.content.Context; import android.media.MediaPlayer; import android.net.Uri; import android.os.Environment; +import android.util.Log; import java.io.File; import java.io.FileOutputStream; @@ -21,9 +22,9 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import io.github.hiro.lime.LimeOptions; public class RingTone implements IHook { - private MediaPlayer mediaPlayer = null; + private android.media.Ringtone ringtone = null; private boolean isPlaying = false; - + MediaPlayer mediaPlayer = null; @Override public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (!limeOptions.callTone.checked) return; @@ -66,22 +67,37 @@ public class RingTone implements IHook { out.write(buffer, 0, length); } } catch (IOException e) { - // エラーが発生しても何もしない + e.printStackTrace(); } } - if (paramValue.contains("type:NOTIFIED_RECEIVED_CALL,") && !isPlaying) { + if (paramValue.contains("type:NOTIFIED_RECEIVED_CALL,")) { if (context != null) { - prepareAndPlayMedia(context, destFile); - } - } + // MediaPlayerが初期化されているか確認 + if (mediaPlayer != null) { + // MediaPlayerが再生中の場合は停止 + if (mediaPlayer.isPlaying()) { + Log.d("Xposed", "MediaPlayer is already playing. Stopping playback."); + mediaPlayer.stop(); // 再生中の場合は停止 + } + mediaPlayer.release(); // MediaPlayerを解放 + mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定 + } - if (paramValue.contains("RESULT=REJECTED,")) { - stopMediaPlayer(); + Uri ringtoneUri = Uri.fromFile(destFile); // コピーしたファイルのURIを取得 + mediaPlayer = MediaPlayer.create(context, ringtoneUri); + mediaPlayer.setLooping(true); // 繰り返し再生を設定 + + if (mediaPlayer != null) { + mediaPlayer.start(); + isPlaying = true; + } + } } } }); + Class targetClass = loadPackageParam.classLoader.loadClass("com.linecorp.andromeda.audio.AudioManager"); Method[] methods = targetClass.getDeclaredMethods(); @@ -90,104 +106,113 @@ public class RingTone implements IHook { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { - if (method.getName().equals("setServerConfig") || method.getName().equals("stop")) { - stopMediaPlayer(); + + if (method.getName().equals("setServerConfig")) { + if (mediaPlayer != null && mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + mediaPlayer.release(); // MediaPlayerを解放 + mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定 + } + } + + if (method.getName().equals("stop")) { + if (mediaPlayer != null && mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + mediaPlayer.release(); // MediaPlayerを解放 + mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定 + } } if (method.getName().equals("processToneEvent")) { Object arg0 = param.args[0]; if (limeOptions.DialTone.checked) { + Log.d("Xposed", "MuteTone is enabled. Suppressing tone event."); param.setResult(null); return; } if (arg0.toString().contains("START")) { if (appContext != null) { - if (mediaPlayer == null || !mediaPlayer.isPlaying()) { - playDialTone(appContext); + // MediaPlayerが初期化されている場合 + if (mediaPlayer != null) { + // MediaPlayerが再生中の場合は停止 + if (mediaPlayer.isPlaying()) { + Log.d("Xposed", "MediaPlayer is already playing. Stopping playback."); + mediaPlayer.stop(); // 再生中の場合は停止 + } + mediaPlayer.release(); // MediaPlayerを解放 + mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定 } + + Context moduleContext = AndroidAppHelper.currentApplication().createPackageContext( + "io.github.hiro.lime", Context.CONTEXT_IGNORE_SECURITY); + + String resourceNameA = "dial_tone"; + int resourceId = moduleContext.getResources().getIdentifier(resourceNameA, "raw", "io.github.hiro.lime"); + + File ringtoneDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup"); + if (!ringtoneDir.exists()) { + ringtoneDir.mkdirs(); // ディレクトリが存在しない場合は作成 + } + File destFile = new File(ringtoneDir, resourceNameA + ".wav"); + + // リソースをストリームとして読み込み、ファイルに書き込む + if (!destFile.exists()) { + try (InputStream in = moduleContext.getResources().openRawResource(resourceId); + OutputStream out = new FileOutputStream(destFile)) { + byte[] buffer = new byte[1024]; + int length; + while ((length = in.read(buffer)) > 0) { + out.write(buffer, 0, length); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + Uri ringtoneUri = Uri.fromFile(destFile); // コピーしたファイルのURIを取得 + mediaPlayer = MediaPlayer.create(appContext, ringtoneUri); + mediaPlayer.setLooping(true); // 繰り返し再生を設定 + + if (mediaPlayer != null) { + Log.d("Xposed", "Playing media."); + mediaPlayer.start(); + } else { + Log.d("Xposed", "MediaPlayer is null. Cannot play media."); + return; + } + } else { + Log.d("Xposed", "appContext is null. Cannot play media."); + return; } + } else { + Log.d("Xposed", "Argument is not 'START'. Actual value: " + arg0); + } } - if (limeOptions.MuteTone.checked && method.getName().equals("setTonePlayer")) { - param.setResult(null); + if (limeOptions.MuteTone.checked) { + if (method.getName().equals("setTonePlayer")) { + param.setResult(null); + } } if (method.getName().equals("ACTIVATED") && param.args != null && param.args.length > 0) { Object arg0 = param.args[0]; if ("ACTIVATED".equals(arg0)) { - stopMediaPlayer(); + if (mediaPlayer != null && mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + mediaPlayer.release(); // MediaPlayerを解放 + mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定 + } } } } }); + + } } }); } - - private void prepareAndPlayMedia(Context context, File destFile) { - if (mediaPlayer != null) { - stopMediaPlayer(); - } - - Uri ringtoneUri = Uri.fromFile(destFile); - mediaPlayer = MediaPlayer.create(context, ringtoneUri); - mediaPlayer.setLooping(true); - - if (mediaPlayer != null) { - mediaPlayer.start(); - isPlaying = true; - - mediaPlayer.setOnCompletionListener(mp -> { - mp.seekTo(0); - mp.start(); - }); - } - } - - private void stopMediaPlayer() { - if (mediaPlayer != null) { - try { - if (mediaPlayer.isPlaying()) { - mediaPlayer.stop(); - } - } catch (IllegalStateException ignored) { - } - try { - mediaPlayer.release(); - } catch (IllegalStateException ignored) { - } finally { - mediaPlayer = null; - isPlaying = false; - } - } - } - - private void playDialTone(Context appContext) { - String resourceNameA = "dial_tone"; - int resourceIdA = appContext.getResources().getIdentifier(resourceNameA, "raw", "io.github.hiro.lime"); - - File ringtoneDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup"); - if (!ringtoneDir.exists()) { - ringtoneDir.mkdirs(); - } - File destFile = new File(ringtoneDir, resourceNameA + ".wav"); - - if (!destFile.exists()) { - try (InputStream in = appContext.getResources().openRawResource(resourceIdA); - OutputStream out = new FileOutputStream(destFile)) { - byte[] buffer = new byte[1024]; - int length; - while ((length = in.read(buffer)) > 0) { - out.write(buffer, 0, length); - } - } catch (IOException e) { - - } - } - - prepareAndPlayMedia(appContext, destFile); - } } \ No newline at end of file