mirror of
https://github.com/areteruhiro/LIME-beta-hiro.git
synced 2025-02-06 05:21:37 +09:00
Notif_invalid機能の追加
This commit is contained in:
parent
1a4b377a1f
commit
e7d18f2782
@ -4,13 +4,13 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace 'io.github.hiro.lime'
|
||||
compileSdk 34
|
||||
compileSdk 35
|
||||
|
||||
defaultConfig {
|
||||
minSdk 28
|
||||
targetSdk 34
|
||||
targetSdk 35
|
||||
versionCode 15
|
||||
versionName "1.12.5e"
|
||||
versionName "1.12.5fd"
|
||||
multiDexEnabled false
|
||||
proguardFiles += 'proguard-rules.pro'
|
||||
buildConfigField 'String', 'HOOK_TARGET_VERSION', '"141700420"'
|
||||
@ -67,6 +67,7 @@ dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation 'org.mozilla:rhino:1.7.15'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0' // バージョンはプロジェクトに合わせて調整
|
||||
implementation "androidx.work:work-runtime:2.10.0"
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
|
@ -41,7 +41,8 @@ public class LimeOptions {
|
||||
public Option ReadChecker = new Option("ReadChecker", R.string.ReadChecker, false);
|
||||
public Option RemoveNotification = new Option("RemoveNotification", R.string.removeNotification, false);
|
||||
public Option NaviColor = new Option("NaviColor", R.string.NaviColor, false);
|
||||
|
||||
public Option NoMuteMessage = new Option("NoMuteMessage", R.string.NoMuteMessage, false);
|
||||
public Option Notif_invalid = new Option("Notif_invalid", R.string.Notif_invalid, false);
|
||||
public Option[] options = {
|
||||
removeVoom,
|
||||
removeWallet,
|
||||
@ -70,6 +71,7 @@ public class LimeOptions {
|
||||
outputCommunication,
|
||||
calltone,
|
||||
NaviColor,
|
||||
Notif_invalid
|
||||
|
||||
|
||||
};
|
||||
|
@ -23,6 +23,8 @@ import io.github.hiro.lime.hooks.KeepUnread;
|
||||
import io.github.hiro.lime.hooks.KeepUnreadLSpatch;
|
||||
import io.github.hiro.lime.hooks.ModifyRequest;
|
||||
import io.github.hiro.lime.hooks.ModifyResponse;
|
||||
import io.github.hiro.lime.hooks.Notif_invalid;
|
||||
import io.github.hiro.lime.hooks.Notificaton_Picture;
|
||||
import io.github.hiro.lime.hooks.OutputRequest;
|
||||
import io.github.hiro.lime.hooks.OutputResponse;
|
||||
import io.github.hiro.lime.hooks.PreventMarkAsRead;
|
||||
@ -36,6 +38,7 @@ import io.github.hiro.lime.hooks.RemoveNotification;
|
||||
import io.github.hiro.lime.hooks.RemoveReplyMute;
|
||||
import io.github.hiro.lime.hooks.Ringtone;
|
||||
import io.github.hiro.lime.hooks.SendMuteMessage;
|
||||
import io.github.hiro.lime.hooks.NoMuteMessage;
|
||||
import io.github.hiro.lime.hooks.SpoofAndroidId;
|
||||
import io.github.hiro.lime.hooks.SpoofUserAgent;
|
||||
import io.github.hiro.lime.hooks.UnsentRec;
|
||||
@ -44,7 +47,6 @@ import io.github.hiro.lime.hooks.ReadChecker;
|
||||
import io.github.hiro.lime.hooks.NaviColor;
|
||||
|
||||
|
||||
|
||||
public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResources, IXposedHookZygoteInit {
|
||||
public static String modulePath;
|
||||
|
||||
@ -82,7 +84,7 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
||||
new KeepUnreadLSpatch(),
|
||||
new AutomaticBackup(),
|
||||
new RemoveNotification(),
|
||||
|
||||
new Notif_invalid(),
|
||||
};
|
||||
|
||||
public void handleLoadPackage(@NonNull XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
|
@ -22,7 +22,7 @@ import io.github.hiro.lime.Utils;
|
||||
|
||||
public class AddRegistrationOptions implements IHook {
|
||||
|
||||
private Switch switchAndroidSecondary;
|
||||
private Switch switchAndroidSecondary;
|
||||
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
@ -85,6 +85,7 @@ public class AddRegistrationOptions implements IHook {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void showSpoofVersionIdDialog(Activity activity, SharedPreferences prefs) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.options_title);
|
||||
@ -96,22 +97,22 @@ public class AddRegistrationOptions implements IHook {
|
||||
TextView textView = new TextView(activity);
|
||||
textView.setText(R.string.spoof_version_id_risk);
|
||||
layout.addView(textView);
|
||||
|
||||
|
||||
EditText editTextDeviceName = new EditText(activity);
|
||||
editTextDeviceName.setHint(R.string.spoof_device_name);
|
||||
editTextDeviceName.setText(prefs.getString("device_name", "ANDROID"));
|
||||
layout.addView(editTextDeviceName); // ここでlayoutに追加
|
||||
|
||||
layout.addView(editTextDeviceName);
|
||||
|
||||
EditText editTextOsName = new EditText(activity);
|
||||
editTextOsName.setHint(R.string.spoof_os_name);
|
||||
editTextOsName.setText(prefs.getString("os_name", "Android OS"));
|
||||
layout.addView(editTextOsName);
|
||||
|
||||
|
||||
EditText editTextOsVersion = new EditText(activity);
|
||||
editTextOsVersion.setHint(R.string.spoof_os_version);
|
||||
editTextOsVersion.setText(prefs.getString("os_version", "14"));
|
||||
layout.addView(editTextOsVersion);
|
||||
|
||||
|
||||
EditText editTextAndroidVersion = new EditText(activity);
|
||||
editTextAndroidVersion.setHint(R.string.spoof_android_version);
|
||||
editTextAndroidVersion.setText(prefs.getString("android_version", "14.16.0"));
|
||||
@ -138,7 +139,6 @@ public class AddRegistrationOptions implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void showSpoofAndroidIdDialog(Activity activity, SharedPreferences prefs) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.options_title);
|
||||
|
@ -7,6 +7,7 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
@ -54,7 +55,8 @@ public class Archived implements IHook {
|
||||
}
|
||||
});
|
||||
}
|
||||
private void hookMessageDeletion(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db,Context moduleContext) {
|
||||
|
||||
private void hookMessageDeletion(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db, Context moduleContext) {
|
||||
if (!limeOptions.Archived.checked) return;
|
||||
try {
|
||||
|
||||
@ -70,7 +72,7 @@ public class Archived implements IHook {
|
||||
String talkId = extractTalkId(paramValue);
|
||||
if (talkId != null) {
|
||||
saveTalkIdToFile(talkId, context);
|
||||
updateArchivedChatsFromFile(db, context,moduleContext);
|
||||
updateArchivedChatsFromFile(db, context, moduleContext);
|
||||
}
|
||||
}
|
||||
if (paramValue.contains("hidden:false")) {
|
||||
@ -78,7 +80,7 @@ public class Archived implements IHook {
|
||||
if (talkId != null) {
|
||||
|
||||
deleteTalkIdFromFile(talkId, context);
|
||||
updateArchivedChatsFromFile(db, context,moduleContext);
|
||||
updateArchivedChatsFromFile(db, context, moduleContext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,7 +160,6 @@ public class Archived implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<String> readChatIdsFromFile(Context context, Context moduleContext) {
|
||||
List<String> chatIds = new ArrayList<>();
|
||||
File dir = moduleContext.getFilesDir();
|
||||
@ -215,8 +216,7 @@ public class Archived implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void updateArchivedChatsFromFile(SQLiteDatabase db, Context context,Context moduleContext) {
|
||||
private void updateArchivedChatsFromFile(SQLiteDatabase db, Context context, Context moduleContext) {
|
||||
File dir = moduleContext.getFilesDir(); // moduleContextを使用
|
||||
File file = new File(dir, "hidelist.txt");
|
||||
|
||||
|
@ -1,29 +1,23 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
import static android.content.ContentValues.TAG;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
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;
|
||||
import io.github.hiro.lime.hooks.IHook;
|
||||
|
||||
public class AutomaticBackup implements IHook {
|
||||
@Override
|
||||
@ -39,6 +33,7 @@ public class AutomaticBackup implements IHook {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent, Object activity) {
|
||||
if (intent != null) {
|
||||
String text = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
@ -56,7 +51,6 @@ public class AutomaticBackup implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void backupChatHistory(Context appContext) {
|
||||
File originalDbFile = appContext.getDatabasePath("naver_line");
|
||||
File backupDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||
@ -75,6 +69,7 @@ public class AutomaticBackup implements IHook {
|
||||
showToast(appContext, "自動バックアップ中にエラーが発生しました: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void backupChatsFolder(Context context) {
|
||||
File originalChatsDir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/files/chats");
|
||||
File backupDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||
@ -130,8 +125,8 @@ public class AutomaticBackup implements IHook {
|
||||
}
|
||||
|
||||
private void showToast(final Context context, final String message) {
|
||||
new android.os.Handler(context.getMainLooper()).post(() ->
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||
);
|
||||
}
|
||||
new android.os.Handler(context.getMainLooper()).post(() ->
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,6 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import io.github.hiro.lime.LimeOptions;
|
||||
|
||||
|
||||
import static io.github.hiro.lime.Main.limeOptions;
|
||||
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.media.AudioManager;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
@ -42,8 +20,8 @@ public class CallVolume implements IHook {
|
||||
int focusGain = (int) param.args[1];
|
||||
int mode = (int) param.args[2];
|
||||
|
||||
XposedBridge.log("Blocking transient audio focus request.");
|
||||
param.setResult(AudioManager.AUDIOFOCUS_REQUEST_FAILED);
|
||||
XposedBridge.log("Blocking transient audio focus request.");
|
||||
param.setResult(AudioManager.AUDIOFOCUS_REQUEST_FAILED);
|
||||
|
||||
}
|
||||
});
|
||||
@ -58,6 +36,5 @@ public class CallVolume implements IHook {
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ public class CheckHookTargetVersion implements IHook {
|
||||
Context context = (Context) param.thisObject;
|
||||
PackageManager pm = context.getPackageManager();
|
||||
long versionCode = pm.getPackageInfo(loadPackageParam.packageName, 0).getLongVersionCode();
|
||||
String versionCodeStr = String.valueOf(versionCode);
|
||||
String versionCodeStr = String.valueOf(versionCode);
|
||||
|
||||
if (!BuildConfig.HOOK_TARGET_VERSION.equals(versionCodeStr)) {
|
||||
Utils.addModuleAssetPath(context);
|
||||
|
@ -1,11 +1,6 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
public class Communication {
|
||||
public enum Type {
|
||||
REQUEST,
|
||||
RESPONSE;
|
||||
}
|
||||
|
||||
public Type type;
|
||||
public String name;
|
||||
public Object value;
|
||||
@ -20,4 +15,9 @@ public class Communication {
|
||||
public String toString() {
|
||||
return type.toString() + ": " + name + ", " + value.toString();
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
REQUEST,
|
||||
RESPONSE
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,19 @@ package io.github.hiro.lime.hooks;
|
||||
public class Constants {
|
||||
public static final String PACKAGE_NAME = "jp.naver.line.android";
|
||||
public static final String MODULE_NAME = "io.github.hiro.lime";
|
||||
//TRADITIONAL_CHINESE
|
||||
static final HookTarget USER_AGENT_HOOK = new HookTarget("n91.c", "h");
|
||||
//HANDLED_AND_RETURN_TRUE
|
||||
static final HookTarget WEBVIEW_CLIENT_HOOK = new HookTarget("VH0.m", "onPageFinished");
|
||||
//NOTIFICATION_DISABLED
|
||||
static final HookTarget MUTE_MESSAGE_HOOK = new HookTarget("f81.b", "H");
|
||||
//PROCESSING
|
||||
static final HookTarget MARK_AS_READ_HOOK = new HookTarget("dM.d$d", "run");
|
||||
static final HookTarget Archive = new HookTarget("eB.Q", "invokeSuspend");
|
||||
//READNOTIFICATION
|
||||
static final HookTarget NOTIFICATION_READ_HOOK = new HookTarget("H91.c", "invokeSuspend");
|
||||
static final HookTarget REQUEST_HOOK = new HookTarget("org.apache.thrift.l", "b");
|
||||
static final HookTarget RESPONSE_HOOK = new HookTarget("org.apache.thrift.l", "a");
|
||||
|
||||
public static class HookTarget {
|
||||
public String className;
|
||||
@ -13,20 +26,5 @@ public class Constants {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
}
|
||||
//TRADITIONAL_CHINESE
|
||||
static final HookTarget USER_AGENT_HOOK = new HookTarget("n91.c", "h");
|
||||
//HANDLED_AND_RETURN_TRUE
|
||||
static final HookTarget WEBVIEW_CLIENT_HOOK = new HookTarget("VH0.m", "onPageFinished");
|
||||
//NOTIFICATION_DISABLED
|
||||
static final HookTarget MUTE_MESSAGE_HOOK = new HookTarget("f81.b", "H");
|
||||
//PROCESSING
|
||||
static final HookTarget MARK_AS_READ_HOOK = new HookTarget("dM.d$d", "run");
|
||||
static final HookTarget Archive = new HookTarget("eB.Q", "invokeSuspend");
|
||||
|
||||
//READNOTIFICATION
|
||||
static final HookTarget NOTIFICATION_READ_HOOK = new HookTarget("H91.c", "invokeSuspend");
|
||||
|
||||
static final HookTarget REQUEST_HOOK = new HookTarget("org.apache.thrift.l", "b");
|
||||
static final HookTarget RESPONSE_HOOK = new HookTarget("org.apache.thrift.l", "a");
|
||||
}
|
||||
|
||||
|
@ -23,20 +23,21 @@ import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.text.SimpleDateFormat;
|
||||
@ -217,6 +218,7 @@ public class EmbedOptions implements IHook {
|
||||
backupChatsFolder(context);
|
||||
}
|
||||
});
|
||||
|
||||
layout.addView(backupfolderButton);
|
||||
|
||||
Button restorefolderButton = new Button(context);
|
||||
@ -228,9 +230,19 @@ public class EmbedOptions implements IHook {
|
||||
restoreChatsFolder(context);
|
||||
}
|
||||
});
|
||||
|
||||
layout.addView(restorefolderButton);
|
||||
|
||||
|
||||
Button MuteGroups_Button = new Button(context);
|
||||
MuteGroups_Button.setLayoutParams(buttonParams);
|
||||
MuteGroups_Button.setText("通知を無効にしているグループ");
|
||||
MuteGroups_Button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MuteGroups_Button(context);
|
||||
}
|
||||
});
|
||||
layout.addView(MuteGroups_Button);
|
||||
|
||||
builder.setPositiveButton(R.string.positive_button, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
@ -468,6 +480,69 @@ public class EmbedOptions implements IHook {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private void MuteGroups_Button(Context context) {
|
||||
// ファイルパスを指定
|
||||
File dir = context.getFilesDir(); // 例えば内部ストレージのファイルディレクトリ
|
||||
File file = new File(dir, "Notification.txt");
|
||||
|
||||
// ファイルが存在する場合、内容を読み込む
|
||||
StringBuilder fileContent = new StringBuilder();
|
||||
if (file.exists()) {
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
fileContent.append(line).append("\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
XposedBridge.log("Error reading the file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 新しい内容を編集できるようにEditTextを表示する
|
||||
final EditText editText = new EditText(context);
|
||||
editText.setText(fileContent.toString());
|
||||
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
|
||||
editText.setMinLines(10); // 適切な行数を設定
|
||||
editText.setGravity(Gravity.TOP); // 上から入力されるように設定
|
||||
|
||||
// ボタン用のレイアウトパラメータを設定
|
||||
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
buttonParams.setMargins(16, 16, 16, 16); // 任意のマージン設定
|
||||
|
||||
// 保存ボタンを作成
|
||||
Button saveButton = new Button(context);
|
||||
saveButton.setText("Save");
|
||||
saveButton.setLayoutParams(buttonParams); // レイアウトパラメータを設定
|
||||
saveButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// 編集した内容をファイルに保存
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
|
||||
writer.write(editText.getText().toString());
|
||||
XposedBridge.log("File saved successfully.");
|
||||
} catch (IOException e) {
|
||||
XposedBridge.log("Error saving the file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 編集画面を表示するためのLayoutに追加
|
||||
LinearLayout layout = new LinearLayout(context);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
layout.addView(editText);
|
||||
layout.addView(saveButton);
|
||||
|
||||
// ダイアログを表示して編集画面を表示する
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("通知を無効にしているグループ");
|
||||
builder.setView(layout);
|
||||
builder.setNegativeButton("キャンセル", null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
|
||||
private void backupChatHistory(Context appContext) {
|
||||
File originalDbFile = appContext.getDatabasePath("naver_line");
|
||||
|
||||
@ -504,13 +579,6 @@ public class EmbedOptions implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void restoreChatHistory(Context context) {
|
||||
File backupDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||
File backupDbFile = new File(backupDir, "naver_line_backup.db");
|
||||
@ -607,7 +675,6 @@ public class EmbedOptions implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void restoreChat(Context context) {
|
||||
File backupDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||
File backupDbFile = new File(backupDir, "naver_line_backup.db");
|
||||
@ -709,6 +776,7 @@ public class EmbedOptions implements IHook {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void backupChatsFolder(Context context) {
|
||||
File originalChatsDir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/files/chats");
|
||||
File backupDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||
|
@ -2,9 +2,7 @@ package io.github.hiro.lime.hooks;
|
||||
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
@ -17,6 +15,7 @@ import android.widget.RelativeLayout;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
@ -39,7 +38,7 @@ public class KeepUnread implements IHook {
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
View rootView = (View) param.getResult();
|
||||
Context appContext = rootView.getContext();
|
||||
|
||||
|
||||
Context moduleContext = AndroidAppHelper.currentApplication().createPackageContext(
|
||||
"io.github.hiro.lime", Context.CONTEXT_IGNORE_SECURITY);
|
||||
|
||||
@ -57,13 +56,13 @@ public class KeepUnread implements IHook {
|
||||
imageParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE); // 垂直中央に配置
|
||||
imageParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); // 水平中央に配置
|
||||
imageParams.setMargins(50, 0, 0, 0); // 水平に50ピクセル右に移動(必要に応じて調整)
|
||||
|
||||
|
||||
imageView.setOnClickListener(v -> {
|
||||
keepUnread = !keepUnread;
|
||||
updateSwitchImage(imageView, keepUnread, moduleContext);
|
||||
saveStateToFile(appContext, keepUnread);
|
||||
});
|
||||
|
||||
|
||||
layout.addView(imageView, imageParams);
|
||||
|
||||
if (rootView instanceof ViewGroup) {
|
||||
@ -78,17 +77,17 @@ public class KeepUnread implements IHook {
|
||||
}
|
||||
|
||||
private void updateSwitchImage(ImageView imageView, boolean isOn, Context moduleContext) {
|
||||
|
||||
String imageName = isOn ? "switch_on" : "switch_off";
|
||||
int imageResource = moduleContext.getResources().getIdentifier(imageName, "drawable", "io.github.hiro.lime");
|
||||
|
||||
if (imageResource != 0) {
|
||||
Drawable drawable = moduleContext.getResources().getDrawable(imageResource, null);
|
||||
if (drawable != null) {
|
||||
drawable = scaleDrawable(drawable, 86, 86);
|
||||
imageView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
String imageName = isOn ? "switch_on" : "switch_off";
|
||||
int imageResource = moduleContext.getResources().getIdentifier(imageName, "drawable", "io.github.hiro.lime");
|
||||
|
||||
if (imageResource != 0) {
|
||||
Drawable drawable = moduleContext.getResources().getDrawable(imageResource, null);
|
||||
if (drawable != null) {
|
||||
drawable = scaleDrawable(drawable, 86, 86);
|
||||
imageView.setImageDrawable(drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable scaleDrawable(Drawable drawable, int width, int height) {
|
||||
@ -96,6 +95,7 @@ public class KeepUnread implements IHook {
|
||||
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
|
||||
return new BitmapDrawable(scaledBitmap);
|
||||
}
|
||||
|
||||
private void saveStateToFile(Context context, boolean state) {
|
||||
String filename = "keep_unread_state.txt";
|
||||
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
|
||||
@ -104,6 +104,7 @@ public class KeepUnread implements IHook {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean readStateFromFile(Context context) {
|
||||
String filename = "keep_unread_state.txt";
|
||||
try (FileInputStream fis = context.openFileInput(filename)) {
|
||||
@ -128,7 +129,7 @@ public class KeepUnread implements IHook {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
if (keepUnread) {
|
||||
param.setResult(null);
|
||||
param.setResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import io.github.hiro.lime.LimeOptions;
|
||||
public class KeepUnreadLSpatch implements IHook {
|
||||
|
||||
static boolean keepUnread = false;
|
||||
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
if (!limeOptions.KeepUnreadLSpatch.checked) return;
|
||||
|
@ -1,26 +1,15 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XResources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookInitPackageResources;
|
||||
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_InitPackageResources.InitPackageResourcesParam;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import io.github.hiro.lime.LimeOptions;
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class OutputRequest implements IHook {
|
||||
new XC_MethodHook() {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
XposedBridge.log(new Communication(Communication.Type.REQUEST, param.args[0].toString(), param.args[1]).toString());
|
||||
XposedBridge.log(new Communication(Communication.Type.REQUEST, param.args[0].toString(), param.args[1]).toString());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ public class PreventMarkAsRead implements IHook {
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
|
||||
param.setResult(null);
|
||||
param.setResult(null);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -37,18 +37,21 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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;
|
||||
import io.github.hiro.lime.R;
|
||||
|
||||
public class ReadChecker implements IHook {
|
||||
private SQLiteDatabase limeDatabase;
|
||||
private SQLiteDatabase db3 = null;
|
||||
private SQLiteDatabase db4 = null;
|
||||
private boolean shouldHookOnCreate = false;
|
||||
private String currentGroupId = null;
|
||||
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
if (!limeOptions.ReadChecker.checked) return;
|
||||
@ -94,7 +97,7 @@ public class ReadChecker implements IHook {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
String chatId = (String) param.getResult();
|
||||
XposedBridge.log(chatId);
|
||||
XposedBridge.log(chatId);
|
||||
if (isGroupExists(chatId)) {
|
||||
shouldHookOnCreate = true;
|
||||
currentGroupId = chatId;
|
||||
@ -259,7 +262,7 @@ public class ReadChecker implements IHook {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle("確認")
|
||||
.setMessage("本当に削除しますか?")
|
||||
.setPositiveButton("はい", (confirmDialog, confirmWhich) -> deleteGroupData(groupId,activity))
|
||||
.setPositiveButton("はい", (confirmDialog, confirmWhich) -> deleteGroupData(groupId, activity))
|
||||
.setNegativeButton("いいえ", null)
|
||||
.show();
|
||||
});
|
||||
@ -270,7 +273,7 @@ public class ReadChecker implements IHook {
|
||||
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));
|
||||
}
|
||||
|
||||
private void deleteGroupData(String groupId,Activity activity) {
|
||||
private void deleteGroupData(String groupId, Activity activity) {
|
||||
if (limeDatabase == null) {
|
||||
return;
|
||||
}
|
||||
@ -301,20 +304,6 @@ public class ReadChecker implements IHook {
|
||||
return user_names;
|
||||
}
|
||||
|
||||
private static class DataItem {
|
||||
String serverId;
|
||||
String content;
|
||||
String createdTime;
|
||||
Set<String> user_names;
|
||||
|
||||
DataItem(String serverId, String content, String createdTime) {
|
||||
this.serverId = serverId;
|
||||
this.content = content;
|
||||
this.createdTime = createdTime;
|
||||
this.user_names = new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
private void catchNotification(XC_LoadPackage.LoadPackageParam loadPackageParam, SQLiteDatabase db3, SQLiteDatabase db4, Context appContext) {
|
||||
try {
|
||||
XposedBridge.hookAllMethods(
|
||||
@ -326,7 +315,7 @@ public class ReadChecker implements IHook {
|
||||
String paramValue = param.args[0].toString();
|
||||
XposedBridge.log(paramValue);
|
||||
if (appContext == null) {
|
||||
XposedBridge.log("appContext is null!");
|
||||
XposedBridge.log("appContext is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -537,6 +526,7 @@ public class ReadChecker implements IHook {
|
||||
limeDatabase.execSQL(createGroupTable);
|
||||
// XposedBridge.log("Database initialized and group_messages table created.");
|
||||
}
|
||||
|
||||
private void saveData(String groupId, String serverId, String checkedUser, String groupName, String content, String user_name, String createdTime, Context context) {
|
||||
File dbFile = new File(context.getFilesDir(), "operation_log.txt");
|
||||
|
||||
@ -617,10 +607,24 @@ public class ReadChecker implements IHook {
|
||||
limeDatabase.execSQL(insertQuery, new Object[]{groupId, serverId, checkedUser, groupName, content, user_name, createdTime});
|
||||
|
||||
XposedBridge.log("Saved to DB: Group_Id: " + groupId + ", Server_id: " + serverId + ", Checked_user: " + checkedUser +
|
||||
", Group_Name: " + groupName + ", Content: " + content + ", user_name: " + user_name + ", Created_Time: " + createdTime);
|
||||
", Group_Name: " + groupName + ", Content: " + content + ", user_name: " + user_name + ", Created_Time: " + createdTime);
|
||||
} catch (Exception e) {
|
||||
Log.e("insertNewRecord", "Error saving data to database:", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataItem {
|
||||
String serverId;
|
||||
String content;
|
||||
String createdTime;
|
||||
Set<String> user_names;
|
||||
|
||||
DataItem(String serverId, String content, String createdTime) {
|
||||
this.serverId = serverId;
|
||||
this.content = content;
|
||||
this.createdTime = createdTime;
|
||||
this.user_names = new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,6 @@ package io.github.hiro.lime.hooks;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebView;
|
||||
@ -42,7 +41,7 @@ public class RedirectWebView implements IHook {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
webView.setVisibility(View.GONE);
|
||||
webView.stopLoading();
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class RemoveAds implements IHook {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
XposedHelpers.findAndHookMethod(
|
||||
ViewGroup.class,
|
||||
"addView",
|
||||
@ -73,8 +73,8 @@ public class RemoveAds implements IHook {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
View view = (View) param.args[0];
|
||||
String className = view.getClass().getName();
|
||||
if (className.contains("Ad") ) {
|
||||
String className = view.getClass().getName();
|
||||
if (className.contains("Ad")) {
|
||||
if (!adClassNames.contains(className)) {
|
||||
adClassNames.add(className);
|
||||
}
|
||||
@ -83,7 +83,7 @@ public class RemoveAds implements IHook {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
for (String adClassName : adClassNames) {
|
||||
XposedBridge.hookAllConstructors(
|
||||
loadPackageParam.classLoader.loadClass(adClassName),
|
||||
|
@ -46,7 +46,6 @@ public class RemoveFlexibleContents implements IHook {
|
||||
View view;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
view = (View) param.thisObject;
|
||||
@ -60,9 +59,7 @@ public class RemoveFlexibleContents implements IHook {
|
||||
|| viewId == serviceTitleBackgroundResId
|
||||
|| viewId == serviceTitleResId
|
||||
|| viewId == serviceSeeMoreResId
|
||||
|| viewId == serviceSeeMoreBadgeResId))
|
||||
|
||||
{
|
||||
|| viewId == serviceSeeMoreBadgeResId)) {
|
||||
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
|
||||
layoutParams.height = 0;
|
||||
view.setLayoutParams(layoutParams);
|
||||
|
@ -53,7 +53,7 @@ public class RemoveIcons implements IHook {
|
||||
|
||||
if (limeOptions.extendClickableArea.checked) {
|
||||
int mainTabContainerResId = activity.getResources().getIdentifier("main_tab_container", "id", activity.getPackageName());
|
||||
ViewGroup mainTabContainer = (ViewGroup) activity.findViewById(mainTabContainerResId);
|
||||
ViewGroup mainTabContainer = activity.findViewById(mainTabContainerResId);
|
||||
for (int i = 2; i < mainTabContainer.getChildCount(); i += 2) {
|
||||
ViewGroup icon = (ViewGroup) mainTabContainer.getChildAt(i);
|
||||
ViewGroup.LayoutParams layoutParams = icon.getLayoutParams();
|
||||
|
@ -2,6 +2,7 @@ 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;
|
||||
@ -43,7 +44,8 @@ public class RemoveNotification implements IHook {
|
||||
typeField.set(operation, type.getClass().getMethod("valueOf", String.class).invoke(type, "DUMMY"));
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException e) {
|
||||
} catch (NoSuchFieldException | IllegalAccessException |
|
||||
IllegalArgumentException e) {
|
||||
XposedBridge.log("RemoveNotification: Error accessing fields - " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
XposedBridge.log("RemoveNotification: Unexpected error - " + e.getMessage());
|
||||
|
@ -14,6 +14,7 @@ import io.github.hiro.lime.LimeOptions;
|
||||
public class Ringtone implements IHook {
|
||||
private android.media.Ringtone ringtone = null;
|
||||
private boolean isPlaying = false;
|
||||
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
|
||||
|
@ -11,7 +11,7 @@ import io.github.hiro.lime.LimeOptions;
|
||||
import io.github.hiro.lime.Main;
|
||||
|
||||
public class SpoofUserAgent implements IHook {
|
||||
private boolean hasLoggedSpoofedUserAgent = false;
|
||||
private boolean hasLoggedSpoofedUserAgent = false;
|
||||
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
@ -36,7 +36,7 @@ public class SpoofUserAgent implements IHook {
|
||||
|
||||
if (!hasLoggedSpoofedUserAgent) {
|
||||
XposedBridge.log("Spoofed User-Agent: " + spoofedUserAgent);
|
||||
hasLoggedSpoofedUserAgent = true;
|
||||
hasLoggedSpoofedUserAgent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,6 @@ public class UnsentRec implements IHook {
|
||||
container.setLayoutParams(containerParams);
|
||||
|
||||
|
||||
|
||||
Button openFileButton = new Button(appContext);
|
||||
openFileButton.setText(moduleContext.getResources().getString(R.string.confirm_messages));
|
||||
|
||||
@ -177,7 +176,6 @@ public class UnsentRec implements IHook {
|
||||
);
|
||||
|
||||
|
||||
|
||||
XposedHelpers.findAndHookMethod(
|
||||
|
||||
|
||||
@ -200,7 +198,7 @@ public class UnsentRec implements IHook {
|
||||
originalFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, moduleContext.getResources().getString(R.string.file_creation_failed), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(context, moduleContext.getResources().getString(R.string.file_creation_failed), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -254,7 +252,6 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// カスタムViewを作成
|
||||
HorizontalScrollView horizontalScrollView = new HorizontalScrollView(context); // 横スクロール用のScrollView
|
||||
ScrollView verticalScrollView = new ScrollView(context); // 縦スクロール用のScrollView
|
||||
@ -273,7 +270,7 @@ public class UnsentRec implements IHook {
|
||||
|
||||
// AlertDialogを作成
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle( moduleContext.getResources().getString(R.string.deleted_messages))
|
||||
builder.setTitle(moduleContext.getResources().getString(R.string.deleted_messages))
|
||||
.setView(verticalScrollView) // カスタムビューをセット
|
||||
.setPositiveButton("ok", (dialog, which) -> {
|
||||
try {
|
||||
@ -287,7 +284,7 @@ public class UnsentRec implements IHook {
|
||||
clearWriter.close();
|
||||
|
||||
Toast.makeText(context,
|
||||
moduleContext.getResources().getString(R.string.content_moved_to_backup),Toast.LENGTH_SHORT).show();
|
||||
moduleContext.getResources().getString(R.string.content_moved_to_backup), Toast.LENGTH_SHORT).show();
|
||||
|
||||
// フラグをリセット
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
@ -296,7 +293,7 @@ public class UnsentRec implements IHook {
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, moduleContext.getResources().getString(R.string.file_move_failed), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(context, moduleContext.getResources().getString(R.string.file_move_failed), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
// ボタンの親からボタンを削除
|
||||
@ -310,7 +307,7 @@ public class UnsentRec implements IHook {
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, moduleContext.getResources().getString(R.string.read_BackUpFile_failed), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(context, moduleContext.getResources().getString(R.string.read_BackUpFile_failed), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
@ -330,7 +327,6 @@ public class UnsentRec implements IHook {
|
||||
);
|
||||
|
||||
|
||||
|
||||
XposedBridge.hookAllMethods(Application.class, "onCreate", new XC_MethodHook() {
|
||||
|
||||
@Override
|
||||
@ -371,8 +367,8 @@ public class UnsentRec implements IHook {
|
||||
SQLiteDatabase db2 = SQLiteDatabase.openDatabase(dbFile2, dbParams2);
|
||||
|
||||
|
||||
hookMessageDeletion(loadPackageParam, appContext,db1, db2);
|
||||
resolveUnresolvedIds(loadPackageParam, appContext,db1, db2,moduleContext);
|
||||
hookMessageDeletion(loadPackageParam, appContext, db1, db2);
|
||||
resolveUnresolvedIds(loadPackageParam, appContext, db1, db2, moduleContext);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -407,10 +403,11 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private void hookMessageDeletion(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db1, SQLiteDatabase db2) {
|
||||
try {
|
||||
XposedBridge.hookAllMethods(
|
||||
loadPackageParam.classLoader.loadClass(Constants.RESPONSE_HOOK.className),
|
||||
loadPackageParam.classLoader.loadClass(Constants.RESPONSE_HOOK.className),
|
||||
Constants.RESPONSE_HOOK.methodName,
|
||||
|
||||
new XC_MethodHook() {
|
||||
@ -425,8 +422,7 @@ public class UnsentRec implements IHook {
|
||||
"io.github.hiro.lime", Context.CONTEXT_IGNORE_SECURITY);
|
||||
|
||||
|
||||
|
||||
processMessage(paramValue, moduleContext, db1, db2,context);
|
||||
processMessage(paramValue, moduleContext, db1, db2, context);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -548,6 +544,7 @@ public class UnsentRec implements IHook {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void saveUnresolvedIds(String serverId, String talkId, String filePath) {
|
||||
String newEntry = "serverId:" + serverId + ",talkId:" + talkId;
|
||||
|
||||
@ -574,8 +571,7 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void resolveUnresolvedIds(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db1, SQLiteDatabase db2,Context moduleContext) {
|
||||
private void resolveUnresolvedIds(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db1, SQLiteDatabase db2, Context moduleContext) {
|
||||
String unresolvedFilePath = context.getFilesDir() + "/UnresolvedIds.txt";
|
||||
|
||||
File unresolvedFile = new File(unresolvedFilePath);
|
||||
@ -647,7 +643,6 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
try (BufferedWriter clearWriter = new BufferedWriter(new FileWriter(unresolvedFile))) {
|
||||
clearWriter.write("");
|
||||
}
|
||||
@ -658,8 +653,6 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private String formatMessageTime(String timeEpochStr) {
|
||||
if (timeEpochStr == null) return null;
|
||||
long timeEpoch = Long.parseLong(timeEpochStr);
|
||||
@ -668,5 +661,4 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,40 +7,41 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.ConstraintSet;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
import dalvik.system.DexFile;
|
||||
import io.github.hiro.lime.LimeOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import dalvik.system.DexFile;
|
||||
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 test implements IHook {
|
||||
private boolean isButtonAdded = false; // ボタンが追加されたかどうかを追跡するフラグ
|
||||
private final boolean isButtonAdded = false; // ボタンが追加されたかどうかを追跡するフラグ
|
||||
|
||||
@Override
|
||||
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
String packageName = loadPackageParam.packageName;
|
||||
|
||||
XposedBridge.log("Hooking package: " + packageName);
|
||||
hookOnViewAdded(loadPackageParam.classLoader);
|
||||
// hookOnViewAdded(loadPackageParam.classLoader);
|
||||
hookAllClassesInPackage(loadPackageParam.classLoader, loadPackageParam);
|
||||
hookFragmentOnCreateView(loadPackageParam.classLoader);
|
||||
// hookFragmentOnCreateView(loadPackageParam.classLoader);
|
||||
//hookChatHistoryActivity(loadPackageParam.classLoader); // ChatHistoryActivityのフック
|
||||
//hookLongClickListeners(loadPackageParam.classLoader); // 長押しリスナーのフック
|
||||
|
||||
|
||||
// `e.b`クラスの`f(OutputStream param1OutputStream)`メソッドをフック
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void hookAllClassesInPackage(ClassLoader classLoader, XC_LoadPackage.LoadPackageParam loadPackageParam) {
|
||||
|
||||
|
||||
try {
|
||||
String apkPath = loadPackageParam.appInfo.sourceDir;
|
||||
if (apkPath == null) {
|
||||
@ -153,14 +154,14 @@ public class test implements IHook {
|
||||
Method onViewAddedMethod = constraintLayoutClass.getDeclaredMethod("onViewAdded", View.class);
|
||||
|
||||
XposedBridge.hookMethod(onViewAddedMethod, new XC_MethodHook() {
|
||||
private final boolean isButtonAdded = false; // ボタンが追加されたかどうかを追跡するフラグ
|
||||
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||
View addedView = (View) param.args[0];
|
||||
XposedBridge.log(addedView.toString());
|
||||
}
|
||||
|
||||
private boolean isButtonAdded = false; // ボタンが追加されたかどうかを追跡するフラグ
|
||||
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
View addedView = (View) param.args[0];
|
||||
@ -250,7 +251,6 @@ public class test implements IHook {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int getIdByName(Context context, String resourceName) {
|
||||
return context.getResources().getIdentifier(resourceName, "id", context.getPackageName());
|
||||
}
|
||||
@ -287,7 +287,22 @@ public class test implements IHook {
|
||||
!"setCompoundDrawables".equals(method.getName()) &&
|
||||
!"getActivity".equals(method.getName()) && // PendingIntent method
|
||||
!"onViewAdded".equals(method.getName()) && // PendingIntent method
|
||||
!"setState".equals(method.getName())) { // PendingIntent method
|
||||
!"run".equals(method.getName()) && // PendingIntent method
|
||||
!"setState".equals(method.getName()) &&
|
||||
!"setMode".equals(method.getName()) && // AudioManagerのsetModeメソッドを除外
|
||||
!"requestAudioFocus".equals(method.getName()) && // AudioManagerのrequestAudioFocusメソッドを除外
|
||||
|
||||
|
||||
!"write".equals(method.getName()) && // AudioManagerのabandonAudioFocusRequestメソッドを除外
|
||||
|
||||
!"read".equals(method.getName()) && // AudioManagerのabandonAudioFocusRequestメソッドを除外
|
||||
!"onNewIntent".equals(method.getName()) && // AudioManagerのabandonAudioFocusRequestメソッドを除外
|
||||
!"adjustStreamVolume".equals(method.getName())) { // AudioManagerのadjustStreamVolumeメソッドを除外
|
||||
|
||||
|
||||
// メソッド処理のコード
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -326,9 +341,9 @@ public class test implements IHook {
|
||||
} else if ("setPadding".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling setPadding in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("setLayoutParams".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling setLayoutParams in class: " + clazz.getName() + " with args: " + argsString);
|
||||
// XposedBridge.log("Before calling setLayoutParams in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("requestLayout".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling requestLayout in class: " + clazz.getName() + " with args: " + argsString);
|
||||
// XposedBridge.log("Before calling requestLayout in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("invalidate".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling invalidate in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("setText".equals(method.getName())) {
|
||||
@ -345,10 +360,17 @@ public class test implements IHook {
|
||||
XposedBridge.log("Before calling onStart in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("getActivity".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling getActivity in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("onViewAdded".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling onViewAdded in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("getService".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling getService in class: " + clazz.getName() + " with args: " + argsString);
|
||||
|
||||
} else if ("write".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling write in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("read".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling read in class: " + clazz.getName() + " with args: " + argsString);
|
||||
|
||||
|
||||
} else if ("onReceive".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling onReceive in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("onNewIntent".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling onNewIntent in class: " + clazz.getName() + " with args: " + argsString);
|
||||
} else if ("setState".equals(method.getName())) {
|
||||
XposedBridge.log("Before setState invoke in class: " + clazz.getName() + " with args: " + argsString);
|
||||
}
|
||||
@ -356,9 +378,13 @@ public class test implements IHook {
|
||||
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
|
||||
|
||||
Object result = param.getResult();
|
||||
|
||||
|
||||
if ("invokeSuspend".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling invokeSuspend in class: " + clazz.getName() + (result != null ? result.toString() : "null"));
|
||||
XposedBridge.log("After calling invokeSuspend in class: " + clazz.getName() + (result != null ? result.toString() : "null"));
|
||||
} else if ("setVisibility".equals(method.getName())) {
|
||||
XposedBridge.log("After calling setVisibility in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("setAlpha".equals(method.getName())) {
|
||||
@ -374,9 +400,9 @@ public class test implements IHook {
|
||||
} else if ("setPadding".equals(method.getName())) {
|
||||
XposedBridge.log("After calling setPadding in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("setLayoutParams".equals(method.getName())) {
|
||||
XposedBridge.log("After calling setLayoutParams in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
// XposedBridge.log("After calling setLayoutParams in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("requestLayout".equals(method.getName())) {
|
||||
XposedBridge.log("After calling requestLayout in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
// XposedBridge.log("After calling requestLayout in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("invalidate".equals(method.getName())) {
|
||||
XposedBridge.log("After calling invalidate in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("setText".equals(method.getName())) {
|
||||
@ -390,16 +416,34 @@ public class test implements IHook {
|
||||
} else if ("setCompoundDrawables".equals(method.getName())) {
|
||||
XposedBridge.log("After calling setCompoundDrawables in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("onStart".equals(method.getName())) {
|
||||
XposedBridge.log("Before calling onStart in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
XposedBridge.log("After calling onStart in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("getActivity".equals(method.getName())) {
|
||||
XposedBridge.log("After calling getActivity in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("onViewAdded".equals(method.getName())) {
|
||||
XposedBridge.log("After calling onViewAdded in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("run".equals(method.getName())) {
|
||||
XposedBridge.log("After calling RUN in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("getService".equals(method.getName())) {
|
||||
XposedBridge.log("After calling getService in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("setState".equals(method.getName())) {
|
||||
XposedBridge.log("setState " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
XposedBridge.log("After calling setState in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
} else if ("setMode".equals(method.getName())) {
|
||||
XposedBridge.log("After calling setMode in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
|
||||
} else if ("onNewIntent".equals(method.getName())) {
|
||||
XposedBridge.log("After calling onNewIntent in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
|
||||
|
||||
} else if ("write".equals(method.getName())) {
|
||||
XposedBridge.log("After calling write in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
|
||||
} else if ("read".equals(method.getName())) {
|
||||
XposedBridge.log("After calling read in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
|
||||
} else if ("adjustStreamVolume".equals(method.getName())) {
|
||||
XposedBridge.log("After calling adjustStreamVolume in class: " + clazz.getName() + " with result: " + (result != null ? result.toString() : "null"));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
@ -96,5 +96,7 @@
|
||||
<string name="switch_KeepUnreadLSpatch">LsPatch用「未読のまま閲覧」スイッチを表示</string>
|
||||
<string name="SleepCall">連続で通話がかかってこないとかからないように</string>
|
||||
<string name="CrashGuard">随時キャッシュを削除してクラッシュを予防</string>
|
||||
<string name="NoMuteMessage">ミュートメッセージの無効化</string>
|
||||
<string name="Notif_invalid">登録しているグループ名の通知をオフにする</string>
|
||||
|
||||
</resources>
|
||||
|
@ -44,4 +44,6 @@
|
||||
|
||||
<!-- Menu -->
|
||||
<string name="switch_keep_unread">保持未讀</string>
|
||||
<string name="NoMuteMessage">ミュートメッセージの無効化</string>
|
||||
<string name="Notif_invalid">登録しているグループ名の通知をオフにする</string>
|
||||
</resources>
|
||||
|
@ -97,4 +97,6 @@
|
||||
<string name="AutomaticBackup">定期的にバックアップ\n</string>
|
||||
<string name="SleepCall">連続で通話がかかってこないとかからないように</string>
|
||||
<string name="CrashGuard">随時キャッシュを削除してクラッシュを予防</string>
|
||||
<string name="NoMuteMessage">ミュートメッセージの無効化</string>
|
||||
<string name="Notif_invalid">登録しているグループ名の通知をオフにする</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user