mirror of
https://github.com/areteruhiro/LIME-beta-hiro.git
synced 2025-02-05 21:11:39 +09:00
音声バグの修正と、プロフィール画像の取得
This commit is contained in:
parent
5882253f70
commit
3fa559c792
@ -10,7 +10,7 @@ android {
|
||||
minSdk 28
|
||||
targetSdk 35
|
||||
versionCode 116160
|
||||
versionName "1.17.0β"
|
||||
versionName "1.16.17.1"
|
||||
multiDexEnabled false
|
||||
proguardFiles += 'proguard-rules.pro'
|
||||
buildConfigField 'String', 'HOOK_TARGET_VERSION', '"141910383"'
|
||||
|
@ -58,7 +58,7 @@ public class LimeOptions {
|
||||
|
||||
public Option AgeCheckSkip = new Option("AgeCheckSkip", R.string.AgeCheckSkip, false);
|
||||
public Option hide_canceled_message = new Option("hide_canceled_message", R.string.hide_canceled_message, false);
|
||||
public Option RemoveNotification = new Option("RemoveNotification", R.string.removeNotification, false);
|
||||
public Option RemoveNotification = new Option("RemoveProfileNotification", R.string.removeNotification, false);
|
||||
public Option DarkColor = new Option("DarkColor", R.string.DarkColor, false);
|
||||
public Option NoMuteMessage = new Option("NoMuteMessage", R.string.NoMuteMessage, false);
|
||||
public Option MuteGroup = new Option("Disabled_Group_notification", R.string.MuteGroup, false);
|
||||
|
@ -2,7 +2,6 @@ package io.github.hiro.lime;
|
||||
|
||||
import android.content.res.XModuleResources;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -16,8 +15,6 @@ import de.robv.android.xposed.callbacks.XC_LayoutInflated;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import io.github.hiro.lime.hooks.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResources, IXposedHookZygoteInit {
|
||||
|
||||
public static String modulePath;
|
||||
@ -54,7 +51,7 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
||||
new DarkColor(),
|
||||
new KeepUnreadLSpatch(),
|
||||
new AutomaticBackup(),
|
||||
new RemoveNotification(),
|
||||
new RemoveProfileNotification(),
|
||||
new Disabled_Group_notification(),
|
||||
new PhotoAddNotification(),
|
||||
new RemoveVoiceRecord(),
|
||||
|
@ -46,8 +46,6 @@ public class AgeCheckSkip implements IHook {
|
||||
builder1.addOpenFlags(SQLiteDatabase.OPEN_READWRITE);
|
||||
SQLiteDatabase.OpenParams dbParams1 = builder1.build();
|
||||
SQLiteDatabase db3 = SQLiteDatabase.openDatabase(dbFile3, dbParams1);
|
||||
|
||||
// 既に "AGE_VERIFICATION_RESULT" が存在するか確認
|
||||
String query = "SELECT * FROM key_value_text WHERE key = ?";
|
||||
Cursor cursor = db3.rawQuery(query, new String[]{"AGE_VERIFICATION_RESULT"});
|
||||
|
||||
@ -67,9 +65,8 @@ public class AgeCheckSkip implements IHook {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.close(); // カーソルを閉じる
|
||||
db3.close(); // データベースを閉じる
|
||||
cursor.close();
|
||||
db3.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -72,8 +72,7 @@ public class AutomaticBackup implements IHook {
|
||||
try (FileChannel destinationWithTimestamp = new FileOutputStream(backupFileWithTimestamp).getChannel()) {
|
||||
destinationWithTimestamp.transferFrom(source, 0, source.size());
|
||||
}
|
||||
showToast(appContext,moduleContext.getResources().getString(R.string.Talk_Auto_Back_up_Success)); // トーストをUIスレッドで表示
|
||||
|
||||
showToast(appContext,moduleContext.getResources().getString(R.string.Talk_Auto_Back_up_Success));
|
||||
} catch (IOException ignored) {
|
||||
showToast(appContext, moduleContext.getResources().getString(R.string.Talk_Auto_Back_up_Error));
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ public class BlockTracking implements IHook {
|
||||
"me1.hd", "me1.jd", "me1.Lb", "me1.Nb"
|
||||
};
|
||||
String[] methodsToHook = {"read", "write"};
|
||||
// Hook 'read' and 'write' methods for each specified class
|
||||
for (String className : classesToHook) {
|
||||
for (String methodName : methodsToHook) {
|
||||
XposedBridge.hookAllMethods(
|
||||
@ -59,8 +58,7 @@ public class BlockTracking implements IHook {
|
||||
}
|
||||
);
|
||||
}
|
||||
// Hook specific method in 'jp.naver.line.android.thrift.client.impl.LegacyTalkServiceClientImpl'
|
||||
XposedBridge.hookAllMethods(
|
||||
XposedBridge.hookAllMethods(
|
||||
loadPackageParam.classLoader.loadClass("jp.naver.line.android.thrift.client.impl.LegacyTalkServiceClientImpl"),
|
||||
"F2",
|
||||
new XC_MethodHook() {
|
||||
|
@ -21,7 +21,6 @@ public class CustomPreferences {
|
||||
|
||||
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), SETTINGS_DIR);
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
// 最初のディレクトリの作成に失敗した場合
|
||||
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||
}
|
||||
settingsFile = new File(dir, SETTINGS_FILE);
|
||||
@ -29,20 +28,28 @@ public class CustomPreferences {
|
||||
|
||||
public void saveSetting(String key, String value) {
|
||||
Properties properties = new Properties();
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(settingsFile)) {
|
||||
properties.load(fis);
|
||||
} catch (IOException e) {
|
||||
// ファイルが存在しない場合、新規作成する
|
||||
|
||||
}
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(settingsFile)) {
|
||||
properties.setProperty(key, value);
|
||||
properties.store(fos, null);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
if (settingsFile.exists()) {
|
||||
settingsFile.delete();
|
||||
}
|
||||
try {
|
||||
properties.setProperty(key, value);
|
||||
properties.store(new FileOutputStream(settingsFile), null);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getSetting(String key, String defaultValue) {
|
||||
Properties properties = new Properties();
|
||||
try (FileInputStream fis = new FileInputStream(settingsFile)) {
|
||||
|
@ -900,17 +900,13 @@ public class EmbedOptions implements IHook {
|
||||
layout.addView(readCheckerVerticalInput);
|
||||
layout.addView(saveButton);
|
||||
layout.addView(resetButton);
|
||||
// ScrollView を作成
|
||||
ScrollView scrollView = new ScrollView(context);
|
||||
scrollView.addView(layout);
|
||||
|
||||
// ダイアログを作成
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(moduleContext.getResources().getString(R.string.edit_margin_settings));
|
||||
builder.setView(scrollView); // ScrollView をダイアログのビューとして設定
|
||||
builder.setNegativeButton(moduleContext.getResources().getString(R.string.cancel), null);
|
||||
|
||||
// アクティビティがまだ有効であるか確認
|
||||
if (context instanceof Activity && !((Activity) context).isFinishing()) {
|
||||
builder.show();
|
||||
}
|
||||
|
@ -140,10 +140,10 @@ public class PhotoAddNotification implements IHook {
|
||||
if (notification.extras != null) {
|
||||
Bundle extras = notification.extras;
|
||||
//XposedBridge.log("Notification Extras:");
|
||||
for (String key : extras.keySet()) {
|
||||
Object value = extras.get(key);
|
||||
//XposedBridge.log(" " + key + ": " + (value != null ? value.toString() : "null"));
|
||||
}
|
||||
// for (String key : extras.keySet()) {
|
||||
// Object value = extras.get(key);
|
||||
// //XposedBridge.log(" " + key + ": " + (value != null ? value.toString() : "null"));
|
||||
// }
|
||||
if (extras.containsKey("line.sticker.url")) {
|
||||
String stickerUrl = extras.getString("line.sticker.url");
|
||||
if (stickerUrl != null) {
|
||||
|
@ -1,58 +0,0 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import io.github.hiro.lime.LimeOptions;
|
||||
|
||||
public class RemoveNotification implements IHook {
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
if (!limeOptions.RemoveNotification.checked) return;
|
||||
XposedBridge.hookAllMethods(
|
||||
loadPackageParam.classLoader.loadClass(Constants.RESPONSE_HOOK.className),
|
||||
Constants.RESPONSE_HOOK.methodName,
|
||||
new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
if (!"sync".equals(param.args[0].toString())) return;
|
||||
|
||||
try {
|
||||
Object wrapper = param.args[1].getClass().getDeclaredField("a").get(param.args[1]);
|
||||
if (wrapper == null) return;
|
||||
|
||||
Field operationResponseField = wrapper.getClass().getSuperclass().getDeclaredField("value_");
|
||||
operationResponseField.setAccessible(true);
|
||||
Object operationResponse = operationResponseField.get(wrapper);
|
||||
if (operationResponse == null) return;
|
||||
|
||||
ArrayList<?> operations = (ArrayList<?>) operationResponse.getClass().getDeclaredField("a").get(operationResponse);
|
||||
if (operations == null) return;
|
||||
|
||||
|
||||
for (int i = operations.size() - 1; i >= 0; i--) {
|
||||
Object operation = operations.get(i);
|
||||
Field typeField = operation.getClass().getDeclaredField("c");
|
||||
typeField.setAccessible(true);
|
||||
Object type = typeField.get(operation);
|
||||
|
||||
|
||||
if ("NOTIFIED_UPDATE_PROFILE".equals(type.toString())) {
|
||||
typeField.set(operation, type.getClass().getMethod("valueOf", String.class).invoke(type, "DUMMY"));
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException |
|
||||
IllegalArgumentException e) {
|
||||
// XposedBridge.log("RemoveNotification: Error accessing fields - " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
// XposedBridge.log("RemoveNotification: Unexpected error - " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import io.github.hiro.lime.LimeOptions;
|
||||
|
||||
public class RemoveProfileNotification implements IHook {
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
if (!limeOptions.RemoveNotification.checked) return;
|
||||
|
||||
XposedBridge.hookAllMethods(Application.class, "onCreate", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
Application appContext = (Application) param.thisObject;
|
||||
if (appContext == null) {
|
||||
return;
|
||||
}
|
||||
Context moduleContext;
|
||||
try {
|
||||
moduleContext = appContext.createPackageContext(
|
||||
"io.github.hiro.lime", Context.CONTEXT_IGNORE_SECURITY);
|
||||
} catch (PackageManager.NameNotFoundException ignored) {
|
||||
return;
|
||||
}
|
||||
File dbFile1 = appContext.getDatabasePath("naver_line");
|
||||
File dbFile2 = appContext.getDatabasePath("contact");
|
||||
if (dbFile1.exists() && dbFile2.exists()) {
|
||||
|
||||
SQLiteDatabase.OpenParams.Builder builder1 = new SQLiteDatabase.OpenParams.Builder();
|
||||
builder1.addOpenFlags(SQLiteDatabase.OPEN_READWRITE);
|
||||
SQLiteDatabase.OpenParams dbParams1 = builder1.build();
|
||||
|
||||
SQLiteDatabase.OpenParams.Builder builder2 = new SQLiteDatabase.OpenParams.Builder();
|
||||
builder2.addOpenFlags(SQLiteDatabase.OPEN_READWRITE);
|
||||
SQLiteDatabase.OpenParams dbParams2 = builder2.build();
|
||||
|
||||
SQLiteDatabase db1 = SQLiteDatabase.openDatabase(dbFile1, dbParams1);
|
||||
SQLiteDatabase db2 = SQLiteDatabase.openDatabase(dbFile2, dbParams2);
|
||||
|
||||
RemoveProfileNotifications(loadPackageParam, appContext, db1, db2, moduleContext);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
private void RemoveProfileNotifications(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db1, SQLiteDatabase db2, Context moduleContext) throws ClassNotFoundException {
|
||||
XposedBridge.hookAllMethods(
|
||||
loadPackageParam.classLoader.loadClass(Constants.RESPONSE_HOOK.className),
|
||||
Constants.RESPONSE_HOOK.methodName,
|
||||
new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
if (!"sync".equals(param.args[0].toString())) return;
|
||||
|
||||
try {
|
||||
String paramValue = param.args[1].toString();
|
||||
String[] operations = paramValue.split("Operation\\(");
|
||||
for (String operation : operations) {
|
||||
if (operation.trim().isEmpty()) continue;
|
||||
|
||||
String type = null;
|
||||
String param1 = null;
|
||||
String[] parts = operation.split(",");
|
||||
for (String part : parts) {
|
||||
part = part.trim();
|
||||
if (part.startsWith("type:")) {
|
||||
type = part.substring("type:".length()).trim();
|
||||
} else if (part.startsWith("param1:")) {
|
||||
param1 = part.substring("param1:".length()).trim();
|
||||
}
|
||||
}
|
||||
if ("NOTIFIED_UPDATE_PROFILE".equals(type)) {
|
||||
XposedBridge.log("取得したparam1: " + param1);
|
||||
Cursor cursor = db2.rawQuery("SELECT mid, contact_type, profile_updated_time_millis, profile_name FROM contacts WHERE mid=?", new String[]{param1});
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
String mid = cursor.getString(cursor.getColumnIndex("mid"));
|
||||
int rowsDeleted = db2.delete("contacts", "mid=?", new String[]{mid});
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
Object operationObject = param.args[1].getClass().getDeclaredField("a").get(param.args[1]);
|
||||
if (operationObject != null) {
|
||||
Field operationResponseField = operationObject.getClass().getSuperclass().getDeclaredField("value_");
|
||||
operationResponseField.setAccessible(true);
|
||||
Object operationResponse = operationResponseField.get(operationObject);
|
||||
if (operationResponse != null) {
|
||||
ArrayList<?> operationList = (ArrayList<?>) operationResponse.getClass().getDeclaredField("a").get(operationResponse);
|
||||
for (Object op : operationList) {
|
||||
Field typeField = op.getClass().getDeclaredField("c");
|
||||
typeField.setAccessible(true);
|
||||
Object typeFieldValue = typeField.get(op);
|
||||
if ("NOTIFIED_UPDATE_PROFILE".equals(typeFieldValue.toString())) {
|
||||
typeField.set(op, typeFieldValue.getClass().getMethod("valueOf", String.class).invoke(typeFieldValue, "DUMMY"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
XposedBridge.log("RemoveProfileNotification: 予期しないエラー - " + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,32 @@ public class RingTone implements IHook {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Context moduleContext = AndroidAppHelper.currentApplication().createPackageContext(
|
||||
"io.github.hiro.lime", Context.CONTEXT_IGNORE_SECURITY);
|
||||
|
||||
String resourceNameA = "dial_tone";
|
||||
int resourceIdA = 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 destFileA = new File(ringtoneDir, resourceNameA + ".wav");
|
||||
|
||||
if (!destFileA.exists()) {
|
||||
try (InputStream in = moduleContext.getResources().openRawResource(resourceIdA);
|
||||
OutputStream out = new FileOutputStream(destFileA)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
XposedBridge.hookAllMethods(
|
||||
loadPackageParam.classLoader.loadClass(Constants.RESPONSE_HOOK.className),
|
||||
Constants.RESPONSE_HOOK.methodName,
|
||||
@ -72,21 +98,19 @@ public class RingTone implements IHook {
|
||||
}
|
||||
|
||||
if (paramValue.contains("type:NOTIFIED_RECEIVED_CALL,")) {
|
||||
XposedBridge.log(paramValue);
|
||||
if (context != null) {
|
||||
// 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 (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
Log.d("Xposed", "MediaPlayer is already playing. Not starting new playback.");
|
||||
return; // すでに再生中の場合は新しい再生を開始しない
|
||||
}
|
||||
|
||||
Uri ringtoneUri = Uri.fromFile(destFile); // コピーしたファイルのURIを取得
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
return;
|
||||
}
|
||||
Uri ringtoneUri = Uri.fromFile(destFile);
|
||||
mediaPlayer = MediaPlayer.create(context, ringtoneUri);
|
||||
mediaPlayer.setLooping(true); // 繰り返し再生を設定
|
||||
mediaPlayer.setLooping(true);
|
||||
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.start();
|
||||
@ -97,7 +121,6 @@ public class RingTone implements IHook {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Class<?> targetClass = loadPackageParam.classLoader.loadClass("com.linecorp.andromeda.audio.AudioManager");
|
||||
Method[] methods = targetClass.getDeclaredMethods();
|
||||
|
||||
@ -106,108 +129,116 @@ public class RingTone implements IHook {
|
||||
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
String methodName = method.getName();
|
||||
Context context = AndroidAppHelper.currentApplication().getApplicationContext();
|
||||
|
||||
if (methodName.equals("getVoiceComplexityLevel")) {
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
return;
|
||||
|
||||
}
|
||||
XposedBridge.log("getVoiceComplexityLevel");
|
||||
|
||||
File destFile = new File(ringtoneDir, "ringtone" + ".wav");
|
||||
Uri ringtoneUri = Uri.fromFile(destFile);
|
||||
mediaPlayer = MediaPlayer.create(context, ringtoneUri);
|
||||
mediaPlayer.setLooping(true);
|
||||
mediaPlayer.start();
|
||||
isPlaying = true;
|
||||
return;
|
||||
}
|
||||
if (method.getName().equals("setServerConfig")) {
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
mediaPlayer.stop();
|
||||
mediaPlayer.release(); // MediaPlayerを解放
|
||||
mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.getName().equals("stop")) {
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
mediaPlayer.stop();
|
||||
mediaPlayer.release(); // MediaPlayerを解放
|
||||
mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.getName().equals("processToneEvent")) {
|
||||
if( param.args != null && param.args.length > 0) {
|
||||
Object arg0 = param.args[0];
|
||||
if (method.getName().equals("ACTIVATED") )
|
||||
if ("ACTIVATED".equals(arg0)) {
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
mediaPlayer.stop();
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (method.getName().equals("processToneEvent")) {
|
||||
|
||||
if (limeOptions.DialTone.checked) {
|
||||
Log.d("Xposed", "MuteTone is enabled. Suppressing tone event.");
|
||||
param.setResult(null);
|
||||
return;
|
||||
}
|
||||
if (limeOptions.MuteTone.checked) {
|
||||
if (method.getName().equals("setTonePlayer")) {
|
||||
param.setResult(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg0.toString().contains("START")) {
|
||||
if (appContext != null) {
|
||||
// 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);
|
||||
// 音楽が再生中の場合、MediaPlayerの再生を抑制
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
Log.d("Xposed", "音楽が再生中のため、MediaPlayerの再生を抑制します。");
|
||||
return; // ここで何もしないことで再生を抑制
|
||||
}
|
||||
|
||||
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);
|
||||
if( param.args != null && param.args.length > 0) {
|
||||
Object arg0 = param.args[0];
|
||||
if (arg0.toString().contains("START")) {
|
||||
if (appContext != null) {
|
||||
if (mediaPlayer != null) {
|
||||
if (mediaPlayer.isPlaying()) {
|
||||
Log.d("Xposed", "MediaPlayer is already playing. Stopping playback.");
|
||||
mediaPlayer.stop();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
Uri ringtoneUri = Uri.fromFile(destFile); // コピーしたファイルのURIを取得
|
||||
mediaPlayer = MediaPlayer.create(appContext, ringtoneUri);
|
||||
mediaPlayer.setLooping(true); // 繰り返し再生を設定
|
||||
Uri ringtoneUriA = Uri.fromFile(destFileA);
|
||||
mediaPlayer = MediaPlayer.create(appContext, ringtoneUriA);
|
||||
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) {
|
||||
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)) {
|
||||
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
|
||||
mediaPlayer.stop();
|
||||
mediaPlayer.release(); // MediaPlayerを解放
|
||||
mediaPlayer = null; // MediaPlayerのインスタンスをnullに設定
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// // 引数の値を取得してログに出力
|
||||
// StringBuilder argsLog = new StringBuilder("Method: " + methodName + ", Arguments: ");
|
||||
// for (Object arg : param.args) {
|
||||
// argsLog.append(arg).append(", ");
|
||||
// }
|
||||
//
|
||||
// // 最後のカンマとスペースを削除
|
||||
// if (argsLog.length() > 0) {
|
||||
// argsLog.setLength(argsLog.length() - 2);
|
||||
// }
|
||||
//
|
||||
// // XposedBridge.logを使用してログ出力
|
||||
// XposedBridge.log(argsLog.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user