mirror of
https://github.com/areteruhiro/LIME-beta-hiro.git
synced 2025-02-06 05:21:37 +09:00
ファイル作成を色々な場所で試すように
This commit is contained in:
parent
d06e4251ce
commit
037e67e4f8
@ -10,7 +10,7 @@ android {
|
|||||||
minSdk 28
|
minSdk 28
|
||||||
targetSdk 35
|
targetSdk 35
|
||||||
versionCode 11501
|
versionCode 11501
|
||||||
versionName "1.16.04beta"
|
versionName "1.16.10beta"
|
||||||
multiDexEnabled false
|
multiDexEnabled false
|
||||||
proguardFiles += 'proguard-rules.pro'
|
proguardFiles += 'proguard-rules.pro'
|
||||||
buildConfigField 'String', 'HOOK_TARGET_VERSION', '"141910383"'
|
buildConfigField 'String', 'HOOK_TARGET_VERSION', '"141910383"'
|
||||||
|
@ -24,7 +24,7 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
public static XSharedPreferences xPrefs;
|
public static XSharedPreferences xPrefs;
|
||||||
public static LimeOptions limeOptions = new LimeOptions();
|
public static LimeOptions limeOptions = new LimeOptions();
|
||||||
|
|
||||||
static final IHook[] hooks = new IHook[]{
|
static final IHook[] hooks = {
|
||||||
new OutputResponse(),
|
new OutputResponse(),
|
||||||
new ModifyRequest(),
|
new ModifyRequest(),
|
||||||
new CheckHookTargetVersion(),
|
new CheckHookTargetVersion(),
|
||||||
@ -61,9 +61,22 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
@Override
|
@Override
|
||||||
public void initZygote(@NonNull StartupParam startupParam) throws Throwable {
|
public void initZygote(@NonNull StartupParam startupParam) throws Throwable {
|
||||||
modulePath = startupParam.modulePath;
|
modulePath = startupParam.modulePath;
|
||||||
customPreferences = new CustomPreferences(); // CustomPreferences を初期化
|
customPreferences = new CustomPreferences();
|
||||||
|
|
||||||
|
// 初期設定ファイルを作成
|
||||||
|
createDefaultSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createDefaultSettings() {
|
||||||
|
for (LimeOptions.Option option : limeOptions.options) {
|
||||||
|
String currentValue = customPreferences.getSetting(option.name, null);
|
||||||
|
if (currentValue == null) {
|
||||||
|
customPreferences.saveSetting(option.name, String.valueOf(option.checked));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void handleLoadPackage(@NonNull XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
public void handleLoadPackage(@NonNull XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||||
if (!loadPackageParam.packageName.equals(Constants.PACKAGE_NAME)) return;
|
if (!loadPackageParam.packageName.equals(Constants.PACKAGE_NAME)) return;
|
||||||
Constants.initializeHooks(loadPackageParam);
|
Constants.initializeHooks(loadPackageParam);
|
||||||
@ -71,11 +84,9 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
xModulePrefs = new XSharedPreferences(Constants.MODULE_NAME, "options");
|
xModulePrefs = new XSharedPreferences(Constants.MODULE_NAME, "options");
|
||||||
xPackagePrefs = new XSharedPreferences(Constants.PACKAGE_NAME, Constants.MODULE_NAME + "-options");
|
xPackagePrefs = new XSharedPreferences(Constants.PACKAGE_NAME, Constants.MODULE_NAME + "-options");
|
||||||
|
|
||||||
// 設定ファイルを再読み込み
|
|
||||||
xModulePrefs.reload();
|
xModulePrefs.reload();
|
||||||
xPackagePrefs.reload();
|
xPackagePrefs.reload();
|
||||||
|
|
||||||
// unembed_optionsの値をログに出力
|
|
||||||
boolean unembedOptions = xModulePrefs.getBoolean("unembed_options", false);
|
boolean unembedOptions = xModulePrefs.getBoolean("unembed_options", false);
|
||||||
XposedBridge.log("unembed_options: " + unembedOptions);
|
XposedBridge.log("unembed_options: " + unembedOptions);
|
||||||
|
|
||||||
@ -83,7 +94,6 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
xPrefs = xModulePrefs;
|
xPrefs = xModulePrefs;
|
||||||
XposedBridge.log("Using module preferences");
|
XposedBridge.log("Using module preferences");
|
||||||
|
|
||||||
// xModulePrefsから設定を読み込む
|
|
||||||
for (LimeOptions.Option option : limeOptions.options) {
|
for (LimeOptions.Option option : limeOptions.options) {
|
||||||
option.checked = xModulePrefs.getBoolean(option.name, option.checked);
|
option.checked = xModulePrefs.getBoolean(option.name, option.checked);
|
||||||
}
|
}
|
||||||
@ -91,13 +101,11 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
xPrefs = xPackagePrefs;
|
xPrefs = xPackagePrefs;
|
||||||
XposedBridge.log("Using package preferences");
|
XposedBridge.log("Using package preferences");
|
||||||
|
|
||||||
// customPreferencesから設定を読み込む
|
|
||||||
for (LimeOptions.Option option : limeOptions.options) {
|
for (LimeOptions.Option option : limeOptions.options) {
|
||||||
option.checked = Boolean.parseBoolean(customPreferences.getSetting(option.name, String.valueOf(option.checked)));
|
option.checked = Boolean.parseBoolean(customPreferences.getSetting(option.name, String.valueOf(option.checked)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 各フックを適用
|
|
||||||
for (IHook hook : hooks) {
|
for (IHook hook : hooks) {
|
||||||
hook.hook(limeOptions, loadPackageParam);
|
hook.hook(limeOptions, loadPackageParam);
|
||||||
}
|
}
|
||||||
@ -105,12 +113,10 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleInitPackageResources(@NonNull XC_InitPackageResources.InitPackageResourcesParam resparam) throws Throwable {
|
public void handleInitPackageResources(@NonNull XC_InitPackageResources.InitPackageResourcesParam resparam) throws Throwable {
|
||||||
if (!resparam.packageName.equals(Constants.PACKAGE_NAME))
|
if (!resparam.packageName.equals(Constants.PACKAGE_NAME)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
XModuleResources xModuleResources = XModuleResources.createInstance(modulePath, resparam.res);
|
XModuleResources xModuleResources = XModuleResources.createInstance(modulePath, resparam.res);
|
||||||
|
|
||||||
// 既存のリソースフック
|
|
||||||
if (limeOptions.removeIconLabels.checked) {
|
if (limeOptions.removeIconLabels.checked) {
|
||||||
resparam.res.setReplacement(Constants.PACKAGE_NAME, "dimen", "main_bnb_button_height", xModuleResources.fwd(R.dimen.main_bnb_button_height));
|
resparam.res.setReplacement(Constants.PACKAGE_NAME, "dimen", "main_bnb_button_height", xModuleResources.fwd(R.dimen.main_bnb_button_height));
|
||||||
resparam.res.setReplacement(Constants.PACKAGE_NAME, "dimen", "main_bnb_button_width", xModuleResources.fwd(R.dimen.main_bnb_button_width));
|
resparam.res.setReplacement(Constants.PACKAGE_NAME, "dimen", "main_bnb_button_width", xModuleResources.fwd(R.dimen.main_bnb_button_width));
|
||||||
@ -126,6 +132,4 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
resparam.res.setReplacement(Constants.PACKAGE_NAME, "dimen", "home_tab_v3_service_icon_size", xModuleResources.fwd(R.dimen.home_tab_v3_service_icon_size));
|
resparam.res.setReplacement(Constants.PACKAGE_NAME, "dimen", "home_tab_v3_service_icon_size", xModuleResources.fwd(R.dimen.home_tab_v3_service_icon_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
SharedPreferences prefs;
|
SharedPreferences prefs;
|
||||||
try {
|
try {
|
||||||
prefs = getSharedPreferences("options", MODE_WORLD_READABLE);
|
prefs = getSharedPreferences("options", MODE_PRIVATE);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
showModuleNotEnabledAlert();
|
showModuleNotEnabledAlert();
|
||||||
return;
|
return;
|
||||||
@ -353,4 +353,4 @@ public class MainActivity extends Activity {
|
|||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package io.github.hiro.lime.hooks;
|
package io.github.hiro.lime.hooks;
|
||||||
|
|
||||||
|
import android.app.AndroidAppHelper;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -14,10 +17,17 @@ public class CustomPreferences {
|
|||||||
|
|
||||||
private final File settingsFile;
|
private final File settingsFile;
|
||||||
|
|
||||||
public CustomPreferences() {
|
public CustomPreferences() throws PackageManager.NameNotFoundException {
|
||||||
|
Context moduleContext = AndroidAppHelper.currentApplication().createPackageContext(
|
||||||
|
"io.github.hiro.lime", Context.CONTEXT_IGNORE_SECURITY);
|
||||||
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), SETTINGS_DIR);
|
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), SETTINGS_DIR);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
dir.mkdirs();
|
// 最初のディレクトリの作成に失敗した場合
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
|
// 次のディレクトリの作成に失敗した場合
|
||||||
|
dir = moduleContext.getFilesDir(); // アプリの内部ストレージを使用
|
||||||
|
}
|
||||||
}
|
}
|
||||||
settingsFile = new File(dir, SETTINGS_FILE);
|
settingsFile = new File(dir, SETTINGS_FILE);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,12 @@ public class EmbedOptions implements IHook {
|
|||||||
String code = editText.getText().toString();
|
String code = editText.getText().toString();
|
||||||
if (!code.equals(script)) {
|
if (!code.equals(script)) {
|
||||||
// CustomPreferencesのインスタンスを作成
|
// CustomPreferencesのインスタンスを作成
|
||||||
CustomPreferences customPreferences = new CustomPreferences();
|
CustomPreferences customPreferences = null;
|
||||||
|
try {
|
||||||
|
customPreferences = new CustomPreferences();
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
// Base64エンコードして設定を保存
|
// Base64エンコードして設定を保存
|
||||||
String encodedCode = Base64.encodeToString(code.getBytes(), Base64.NO_WRAP);
|
String encodedCode = Base64.encodeToString(code.getBytes(), Base64.NO_WRAP);
|
||||||
customPreferences.saveSetting("encoded_js_modify_request", encodedCode);
|
customPreferences.saveSetting("encoded_js_modify_request", encodedCode);
|
||||||
@ -515,10 +520,21 @@ public class EmbedOptions implements IHook {
|
|||||||
|
|
||||||
|
|
||||||
private void Cancel_Message_Button(Context context, Context moduleContext) {
|
private void Cancel_Message_Button(Context context, Context moduleContext) {
|
||||||
// フォルダのパスを設定
|
// フォルダのパスを設定
|
||||||
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup/Setting");
|
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup/Setting");
|
||||||
|
|
||||||
|
// 最初のディレクトリを確認
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
if (!dir.mkdirs()) {
|
// 次のディレクトリを確認
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/LimeBackup/Setting");
|
||||||
|
|
||||||
|
if (!dir.exists()) {
|
||||||
|
// 内部ストレージを確認
|
||||||
|
dir = new File(context.getFilesDir(), "LimeBackup/Setting");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最終的にディレクトリを作成
|
||||||
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
Toast.makeText(context, "Failed to create directory", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "Failed to create directory", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -601,10 +617,17 @@ public class EmbedOptions implements IHook {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
private void KeepUnread_Button(Context context, Context moduleContext) {
|
private void KeepUnread_Button(Context context, Context moduleContext) {
|
||||||
// ファイルパスを取得
|
// 最初のディレクトリパスを取得
|
||||||
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||||
|
|
||||||
|
// ディレクトリの作成を試みる
|
||||||
if (!dir.exists() && !dir.mkdirs()) {
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
return;
|
// 最初のディレクトリの作成に失敗した場合
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
|
// 次のディレクトリの作成に失敗した場合
|
||||||
|
dir = moduleContext.getFilesDir(); // アプリの内部ストレージを使用
|
||||||
|
}
|
||||||
}
|
}
|
||||||
File file = new File(dir, "margin_settings.txt");
|
File file = new File(dir, "margin_settings.txt");
|
||||||
|
|
||||||
|
@ -138,24 +138,37 @@ public class KeepUnread implements IHook {
|
|||||||
File file = new File(dir, fileName);
|
File file = new File(dir, fileName);
|
||||||
Map<String, String> settings = new HashMap<>();
|
Map<String, String> settings = new HashMap<>();
|
||||||
|
|
||||||
|
// ファイルが存在しない場合、他のディレクトリを確認
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
|
// 次のディレクトリを確認
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
|
file = new File(dir, fileName);
|
||||||
|
|
||||||
}
|
// それでも存在しない場合、内部ストレージを確認
|
||||||
|
if (!file.exists()) {
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
file = new File(context.getFilesDir(), fileName);
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
String[] parts = line.split("=", 2);
|
|
||||||
if (parts.length == 2) {
|
|
||||||
settings.put(parts[0].trim(), parts[1].trim());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("FileError", "Error reading file: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ファイルが存在する場合、内容を読み込む
|
||||||
|
if (file.exists()) {
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
String[] parts = line.split("=", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
settings.put(parts[0].trim(), parts[1].trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("FileError", "Error reading file: " + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("FileError", "File not found: " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getkeep_unread_horizontalMarginFactor(Context context) {
|
private float getkeep_unread_horizontalMarginFactor(Context context) {
|
||||||
Map<String, String> settings = readSettingsFromExternalFile(context);
|
Map<String, String> settings = readSettingsFromExternalFile(context);
|
||||||
try {
|
try {
|
||||||
|
@ -125,19 +125,31 @@ public class PreventMarkAsRead implements IHook {
|
|||||||
File file = new File(dir, fileName);
|
File file = new File(dir, fileName);
|
||||||
Map<String, String> settings = new HashMap<>();
|
Map<String, String> settings = new HashMap<>();
|
||||||
|
|
||||||
|
// ファイルが存在しない場合、他のディレクトリを確認
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
|
// 次のディレクトリを確認
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
|
file = new File(dir, fileName);
|
||||||
|
|
||||||
|
// それでも存在しない場合、内部ストレージを確認
|
||||||
|
if (!file.exists()) {
|
||||||
|
file = new File(context.getFilesDir(), fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
// ファイルが存在する場合、内容を読み込む
|
||||||
String line;
|
if (file.exists()) {
|
||||||
while ((line = reader.readLine()) != null) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
String[] parts = line.split("=", 2);
|
String line;
|
||||||
if (parts.length == 2) {
|
while ((line = reader.readLine()) != null) {
|
||||||
settings.put(parts[0].trim(), parts[1].trim());
|
String[] parts = line.split("=", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
settings.put(parts[0].trim(), parts[1].trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
@ -151,6 +163,17 @@ public class PreventMarkAsRead implements IHook {
|
|||||||
float chatUnreadSizeDp = 30; // デフォルト値
|
float chatUnreadSizeDp = 30; // デフォルト値
|
||||||
|
|
||||||
// ファイルの内容を読み込む
|
// ファイルの内容を読み込む
|
||||||
|
if (!file.exists()) {
|
||||||
|
// 次のディレクトリを確認
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
|
file = new File(dir, "margin_settings.txt");
|
||||||
|
|
||||||
|
// それでも存在しない場合、内部ストレージを確認
|
||||||
|
if (!file.exists()) {
|
||||||
|
file = new File(moduleContext.getFilesDir(), "margin_settings.txt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
String line;
|
String line;
|
||||||
@ -175,16 +198,23 @@ public class PreventMarkAsRead implements IHook {
|
|||||||
|
|
||||||
// 画像ファイルが存在しない場合、リソースからコピーして保存
|
// 画像ファイルが存在しない場合、リソースからコピーして保存
|
||||||
if (!imageFile.exists()) {
|
if (!imageFile.exists()) {
|
||||||
try (InputStream in = moduleContext.getResources().openRawResource(
|
// 最初のディレクトリにコピーを試みる
|
||||||
moduleContext.getResources().getIdentifier(imageName.replace(".png", ""), "drawable", "io.github.hiro.lime"));
|
if (!copyImageFile(moduleContext, imageName, imageFile)) {
|
||||||
OutputStream out = new FileOutputStream(imageFile)) {
|
// 次のディレクトリにコピーを試みる
|
||||||
byte[] buffer = new byte[1024];
|
File fallbackDir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
int length;
|
if (!fallbackDir.exists()) {
|
||||||
while ((length = in.read(buffer)) > 0) {
|
fallbackDir.mkdirs();
|
||||||
out.write(buffer, 0, length);
|
}
|
||||||
|
imageFile = new File(fallbackDir, imageName);
|
||||||
|
if (!copyImageFile(moduleContext, imageName, imageFile)) {
|
||||||
|
// 内部ストレージにコピーを試みる
|
||||||
|
File internalDir = new File(moduleContext.getFilesDir(), "backup");
|
||||||
|
if (!internalDir.exists()) {
|
||||||
|
internalDir.mkdirs();
|
||||||
|
}
|
||||||
|
imageFile = new File(internalDir, imageName);
|
||||||
|
copyImageFile(moduleContext, imageName, imageFile);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +231,22 @@ public class PreventMarkAsRead implements IHook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean copyImageFile(Context moduleContext, String imageName, File destinationFile) {
|
||||||
|
try (InputStream in = moduleContext.getResources().openRawResource(
|
||||||
|
moduleContext.getResources().getIdentifier(imageName.replace(".png", ""), "drawable", "io.github.hiro.lime"));
|
||||||
|
OutputStream out = new FileOutputStream(destinationFile)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = in.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
return true; // コピー成功
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false; // コピー失敗
|
||||||
|
}
|
||||||
|
}
|
||||||
// DP値をピクセル値に変換するメソッド
|
// DP値をピクセル値に変換するメソッド
|
||||||
private int dpToPx(@NonNull Context context, float dp) {
|
private int dpToPx(@NonNull Context context, float dp) {
|
||||||
float density = context.getResources().getDisplayMetrics().density;
|
float density = context.getResources().getDisplayMetrics().density;
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package io.github.hiro.lime.hooks;
|
package io.github.hiro.lime.hooks;
|
||||||
|
|
||||||
|
|
||||||
import static android.content.ContentValues.TAG;
|
|
||||||
import static io.github.hiro.lime.Main.limeOptions;
|
import static io.github.hiro.lime.Main.limeOptions;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AndroidAppHelper;
|
import android.app.AndroidAppHelper;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
@ -20,13 +18,8 @@ import android.graphics.Bitmap;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@ -198,38 +191,40 @@ public class ReadChecker implements IHook {
|
|||||||
cursor.close();
|
cursor.close();
|
||||||
return noGroup;
|
return noGroup;
|
||||||
}
|
}
|
||||||
|
private void addButton(Activity activity, Context moduleContext) {
|
||||||
private static final String TAG = "FileHandler";
|
// ファイルパスを取得
|
||||||
public void addButton(Activity activity, Context moduleContext) {
|
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||||
// ファイル取得処理(フォールバック対応)
|
File file = new File(dir, "margin_settings.txt");
|
||||||
File file = getFile(activity);
|
|
||||||
if (file == null) {
|
|
||||||
Log.e(TAG, "Failed to get a valid file.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// デフォルト値
|
// デフォルト値
|
||||||
float readCheckerHorizontalMarginFactor = 0.5f;
|
float readCheckerHorizontalMarginFactor = 0.5f; // デフォルト値
|
||||||
int readCheckerVerticalMarginDp = 100;
|
int readCheckerVerticalMarginDp = 100; // デフォルト値
|
||||||
float readCheckerSizeDp = 60;
|
float readCheckerSizeDp = 60; // デフォルト値
|
||||||
|
|
||||||
// ファイルの内容を読み込む
|
// ファイルの内容を読み込む
|
||||||
|
if (!file.exists()) {
|
||||||
|
// 次のディレクトリを確認
|
||||||
|
dir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
|
file = new File(dir, "margin_settings.txt");
|
||||||
|
|
||||||
|
// それでも存在しない場合、内部ストレージを確認
|
||||||
|
if (!file.exists()) {
|
||||||
|
file = new File(moduleContext.getFilesDir(), "margin_settings.txt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
String[] parts = line.split("=", 2);
|
String[] parts = line.split("=", 2);
|
||||||
if (parts.length == 2) {
|
if (parts.length == 2) {
|
||||||
switch (parts[0].trim()) {
|
if (parts[0].trim().equals("Read_checker_horizontalMarginFactor")) {
|
||||||
case "Read_checker_horizontalMarginFactor":
|
readCheckerHorizontalMarginFactor = Float.parseFloat(parts[1].trim());
|
||||||
readCheckerHorizontalMarginFactor = Float.parseFloat(parts[1].trim());
|
} else if (parts[0].trim().equals("Read_checker_verticalMarginDp")) {
|
||||||
break;
|
readCheckerVerticalMarginDp = Integer.parseInt(parts[1].trim());
|
||||||
case "Read_checker_verticalMarginDp":
|
} else if (parts[0].trim().equals("chat_read_check_size")) {
|
||||||
readCheckerVerticalMarginDp = Integer.parseInt(parts[1].trim());
|
readCheckerSizeDp = Float.parseFloat(parts[1].trim());
|
||||||
break;
|
|
||||||
case "chat_read_check_size":
|
|
||||||
readCheckerSizeDp = Float.parseFloat(parts[1].trim());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,34 +232,42 @@ public class ReadChecker implements IHook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 画像ボタンの設定
|
|
||||||
ImageView imageButton = new ImageView(activity);
|
ImageView imageButton = new ImageView(activity);
|
||||||
String imageName = "read_checker.png";
|
String imageName = "read_checker.png";
|
||||||
File imageFile = new File(file.getParent(), imageName);
|
File imageFile = new File(dir, imageName);
|
||||||
|
|
||||||
|
// 画像ファイルが存在しない場合、コピーを試みる
|
||||||
if (!imageFile.exists()) {
|
if (!imageFile.exists()) {
|
||||||
try (InputStream in = moduleContext.getResources().openRawResource(
|
// 最初のディレクトリにコピーを試みる
|
||||||
moduleContext.getResources().getIdentifier(imageName.replace(".png", ""), "drawable", "io.github.hiro.lime"));
|
if (!copyImageFile(moduleContext, imageName, imageFile)) {
|
||||||
OutputStream out = new FileOutputStream(imageFile)) {
|
// 次のディレクトリにコピーを試みる
|
||||||
byte[] buffer = new byte[1024];
|
File fallbackDir = new File(Environment.getExternalStorageDirectory(), "Android/data/jp.naver.line.android/");
|
||||||
int length;
|
if (!fallbackDir.exists()) {
|
||||||
while ((length = in.read(buffer)) > 0) {
|
fallbackDir.mkdirs();
|
||||||
out.write(buffer, 0, length);
|
}
|
||||||
|
imageFile = new File(fallbackDir, imageName);
|
||||||
|
if (!copyImageFile(moduleContext, imageName, imageFile)) {
|
||||||
|
// 内部ストレージにコピーを試みる
|
||||||
|
File internalDir = new File(moduleContext.getFilesDir(), "backup");
|
||||||
|
if (!internalDir.exists()) {
|
||||||
|
internalDir.mkdirs();
|
||||||
|
}
|
||||||
|
imageFile = new File(internalDir, imageName);
|
||||||
|
copyImageFile(moduleContext, imageName, imageFile);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 画像ファイルが存在する場合、Drawableを設定
|
||||||
if (imageFile.exists()) {
|
if (imageFile.exists()) {
|
||||||
Drawable drawable = Drawable.createFromPath(imageFile.getAbsolutePath());
|
Drawable drawable = Drawable.createFromPath(imageFile.getAbsolutePath());
|
||||||
if (drawable != null) {
|
if (drawable != null) {
|
||||||
int sizeInPx = dpToPx(moduleContext, readCheckerSizeDp);
|
int sizeInPx = dpToPx(moduleContext, readCheckerSizeDp);
|
||||||
|
drawable = scaleDrawable(drawable, sizeInPx, sizeInPx);
|
||||||
imageButton.setImageDrawable(drawable);
|
imageButton.setImageDrawable(drawable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 画像ボタンのレイアウト
|
|
||||||
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
|
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||||
@ -275,9 +278,13 @@ public class ReadChecker implements IHook {
|
|||||||
frameParams.setMargins(horizontalMarginPx, verticalMarginPx, 0, 0);
|
frameParams.setMargins(horizontalMarginPx, verticalMarginPx, 0, 0);
|
||||||
|
|
||||||
imageButton.setLayoutParams(frameParams);
|
imageButton.setLayoutParams(frameParams);
|
||||||
imageButton.setOnClickListener(v -> {
|
|
||||||
if (currentGroupId != null) {
|
imageButton.setOnClickListener(new View.OnClickListener() {
|
||||||
showDataForGroupId(activity, currentGroupId, moduleContext);
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (currentGroupId != null) {
|
||||||
|
showDataForGroupId(activity, currentGroupId, moduleContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -285,25 +292,29 @@ public class ReadChecker implements IHook {
|
|||||||
if (limeOptions.ReadCheckerChatdataDelete.checked) {
|
if (limeOptions.ReadCheckerChatdataDelete.checked) {
|
||||||
Button deleteButton = new Button(activity);
|
Button deleteButton = new Button(activity);
|
||||||
deleteButton.setText(moduleContext.getResources().getString(R.string.Delete));
|
deleteButton.setText(moduleContext.getResources().getString(R.string.Delete));
|
||||||
deleteButton.setBackgroundColor(Color.RED);
|
deleteButton.setBackgroundColor(Color.RED); // ボタンの背景色を赤に設定
|
||||||
deleteButton.setTextColor(Color.WHITE);
|
deleteButton.setTextColor(Color.WHITE); // ボタンのテキスト色を白に設定
|
||||||
|
|
||||||
FrameLayout.LayoutParams deleteButtonParams = new FrameLayout.LayoutParams(
|
FrameLayout.LayoutParams deleteButtonParams = new FrameLayout.LayoutParams(
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Delete ボタンの位置を画像ボタンの右側に設定
|
||||||
deleteButtonParams.setMargins(horizontalMarginPx + dpToPx(moduleContext, readCheckerSizeDp) + 20, verticalMarginPx, 0, 0);
|
deleteButtonParams.setMargins(horizontalMarginPx + dpToPx(moduleContext, readCheckerSizeDp) + 20, verticalMarginPx, 0, 0);
|
||||||
deleteButton.setLayoutParams(deleteButtonParams);
|
deleteButton.setLayoutParams(deleteButtonParams);
|
||||||
|
|
||||||
deleteButton.setOnClickListener(v -> {
|
deleteButton.setOnClickListener(new View.OnClickListener() {
|
||||||
if (currentGroupId != null) {
|
@Override
|
||||||
new AlertDialog.Builder(activity)
|
public void onClick(View v) {
|
||||||
.setTitle(moduleContext.getResources().getString(R.string.check))
|
if (currentGroupId != null) {
|
||||||
.setMessage(moduleContext.getResources().getString(R.string.really_delete))
|
new AlertDialog.Builder(activity)
|
||||||
.setPositiveButton(moduleContext.getResources().getString(R.string.yes), (dialog, which) -> deleteGroupData(currentGroupId, activity, moduleContext))
|
.setTitle(moduleContext.getResources().getString(R.string.check))
|
||||||
.setNegativeButton(moduleContext.getResources().getString(R.string.no), null)
|
.setMessage(moduleContext.getResources().getString(R.string.really_delete))
|
||||||
.show();
|
.setPositiveButton(moduleContext.getResources().getString(R.string.yes), (confirmDialog, confirmWhich) -> deleteGroupData(currentGroupId, activity, moduleContext))
|
||||||
|
.setNegativeButton(moduleContext.getResources().getString(R.string.no), null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -315,50 +326,21 @@ public class ReadChecker implements IHook {
|
|||||||
layout.addView(imageButton);
|
layout.addView(imageButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getFile(Activity activity) {
|
private boolean copyImageFile(Context moduleContext, String imageName, File destinationFile) {
|
||||||
File dir;
|
try (InputStream in = moduleContext.getResources().openRawResource(
|
||||||
File file;
|
moduleContext.getResources().getIdentifier(imageName.replace(".png", ""), "drawable", "io.github.hiro.lime"));
|
||||||
|
OutputStream out = new FileOutputStream(destinationFile)) {
|
||||||
try {
|
byte[] buffer = new byte[1024];
|
||||||
dir = new File(activity.getExternalFilesDir(null), "LimeBackup");
|
int length;
|
||||||
if (!dir.exists() && !dir.mkdirs()) {
|
while ((length = in.read(buffer)) > 0) {
|
||||||
throw new IOException("Failed to create directory");
|
out.write(buffer, 0, length);
|
||||||
}
|
}
|
||||||
file = new File(dir, "margin_settings.txt");
|
return true; // コピー成功
|
||||||
|
} catch (IOException e) {
|
||||||
if (!file.exists() && !file.createNewFile()) {
|
e.printStackTrace();
|
||||||
throw new IOException("Failed to create file");
|
return false; // コピー失敗
|
||||||
}
|
|
||||||
return file;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "getExternalFilesDir failed, falling back to MediaStore.", e);
|
|
||||||
return getFileFromMediaStore(activity, "LimeBackup/margin_settings.txt");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getFileFromMediaStore(Context context, String relativePath) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
||||||
ContentResolver resolver = context.getContentResolver();
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
values.put(MediaStore.Downloads.DISPLAY_NAME, "margin_settings.txt");
|
|
||||||
values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + "/LimeBackup");
|
|
||||||
values.put(MediaStore.Downloads.MIME_TYPE, "text/plain");
|
|
||||||
|
|
||||||
Uri fileUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
|
|
||||||
if (fileUri != null) {
|
|
||||||
try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(fileUri, "rw")) {
|
|
||||||
if (pfd != null) {
|
|
||||||
return new File(context.getFilesDir(), "margin_settings.txt");
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private int dpToPx(@NonNull Context context, float dp) {
|
private int dpToPx(@NonNull Context context, float dp) {
|
||||||
float density = context.getResources().getDisplayMetrics().density;
|
float density = context.getResources().getDisplayMetrics().density;
|
||||||
return Math.round(dp * density);
|
return Math.round(dp * density);
|
||||||
@ -397,7 +379,7 @@ public class ReadChecker implements IHook {
|
|||||||
while (sameGroupIdCursor.moveToNext()) {
|
while (sameGroupIdCursor.moveToNext()) {
|
||||||
String otherServerId = sameGroupIdCursor.getString(0);
|
String otherServerId = sameGroupIdCursor.getString(0);
|
||||||
String otherUserName = sameGroupIdCursor.getString(1);
|
String otherUserName = sameGroupIdCursor.getString(1);
|
||||||
|
|
||||||
if (!userName.equals(otherUserName)) {
|
if (!userName.equals(otherUserName)) {
|
||||||
// 新しいレコードを作成
|
// 新しいレコードを作成
|
||||||
limeDatabase.execSQL(
|
limeDatabase.execSQL(
|
||||||
|
Loading…
Reference in New Issue
Block a user