Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f6f2504158 |
@ -7,7 +7,6 @@
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="Android Studio default JDK" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="temurin-11" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -28,6 +28,5 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
compileOnly files('libs/XposedBridgeAPI-89.jar')
|
||||
}
|
@ -1,11 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="run.evan.hotspotip">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true">
|
||||
android:supportsRtl="true"
|
||||
tools:ignore="MissingApplicationIcon"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity
|
||||
android:name="run.evan.hotspotip.SettingsActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<meta-data
|
||||
android:name="xposedmodule"
|
||||
android:value="true" />
|
||||
@ -15,7 +28,6 @@
|
||||
<meta-data
|
||||
android:name="xposedminversion"
|
||||
android:value="53" />
|
||||
|
||||
<meta-data
|
||||
android:name="xposedscope"
|
||||
android:resource="@array/scope" />
|
||||
|
@ -1,55 +1,83 @@
|
||||
package run.evan.hotspotip;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XC_MethodReplacement;
|
||||
import de.robv.android.xposed.XSharedPreferences;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||
|
||||
public class MainHook implements IXposedHookLoadPackage {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||
if (loadPackageParam.packageName.equals("com.android.networkstack.tethering.inprocess")) {
|
||||
XposedBridge.log("Hotspot IP init process="+loadPackageParam.packageName);
|
||||
XposedHelpers.findAndHookMethod("com.android.networkstack.tethering.PrivateAddressCoordinator", loadPackageParam.classLoader, "requestDownstreamAddress", "android.net.ip.IpServer", boolean.class, new XC_MethodReplacement() {
|
||||
@Override
|
||||
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
|
||||
return buildPrivateAddressResponse(methodHookParam, loadPackageParam);
|
||||
}
|
||||
});
|
||||
}
|
||||
XSharedPreferences prefs = new XSharedPreferences("run.evan.hotspotip", "conf");
|
||||
XposedBridge.log("Hotspot Ip init");
|
||||
XposedHelpers.findAndHookMethod("com.android.networkstack.tethering.PrivateAddressCoordinator", loadPackageParam.classLoader, "requestDownstreamAddress", "android.net.ip.IpServer", boolean.class, new XC_MethodHook() {
|
||||
|
||||
if (loadPackageParam.packageName.equals("com.android.networkstack.tethering")) {
|
||||
XposedBridge.log("Hotspot IP init process="+loadPackageParam.packageName);
|
||||
XposedHelpers.findAndHookMethod("com.android.networkstack.tethering.PrivateAddressCoordinator", loadPackageParam.classLoader, "requestDownstreamAddress", "android.net.ip.IpServer",int.class, boolean.class, new XC_MethodReplacement() {
|
||||
@Override
|
||||
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
|
||||
return buildPrivateAddressResponse(methodHookParam, loadPackageParam);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static Object buildPrivateAddressResponse(XC_MethodHook.MethodHookParam methodHookParam, XC_LoadPackage.LoadPackageParam loadPackageParam) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
prefs.reload();
|
||||
Class linkAddressClass = XposedHelpers.findClass("android.net.LinkAddress", loadPackageParam.classLoader);
|
||||
Constructor linkAddressConstructor = linkAddressClass.getConstructor(String.class);
|
||||
Class ipServerClass = XposedHelpers.findClass("android.net.ip.IpServer", loadPackageParam.classLoader);
|
||||
Method interfaceTypeMethod = ipServerClass.getDeclaredMethod("interfaceType");
|
||||
int iFaceType = (int) interfaceTypeMethod.invoke(methodHookParam.args[0]);
|
||||
switch (iFaceType) {
|
||||
case 3:
|
||||
return linkAddressConstructor.newInstance("192.168.49.1/24");
|
||||
case 0:
|
||||
return linkAddressConstructor.newInstance("192.168.6.1/24");
|
||||
case 1:
|
||||
return linkAddressConstructor.newInstance("192.168.7.1/24");
|
||||
default:
|
||||
return linkAddressConstructor.newInstance("192.168.8.1/24");
|
||||
int iFaceType = (int) interfaceTypeMethod.invoke(param.args[0]);
|
||||
XposedBridge.log("Hotspot Ip process ifaceType=" + iFaceType);
|
||||
XposedBridge.log(prefs.getString("usb_ip", "192.168.7.2/24"));
|
||||
if (prefs.getBoolean("wlan_persistent_enable", true)) {
|
||||
XposedBridge.log("Hotspot Ip fixed wlanA");
|
||||
param.setResult(linkAddressConstructor.newInstance("192.168.6.1/24"));
|
||||
}else {
|
||||
XposedBridge.log("Hotspot Ip fixed wlan not enable");
|
||||
}
|
||||
// switch (iFaceType) {
|
||||
// case 0:
|
||||
// if (prefs.getBoolean("wlan_persistent_enable", true)) {
|
||||
// XposedBridge.log("Hotspot Ip fixed wlan");
|
||||
// param.setResult(linkAddressConstructor.newInstance("192.168.6.1/24"));
|
||||
// }else {
|
||||
// XposedBridge.log("Hotspot Ip fixed wlan not enable");
|
||||
// }
|
||||
// case 1:
|
||||
// if (prefs.getBoolean("usb_persistent_enable", true)) {
|
||||
// param.setResult(linkAddressConstructor.newInstance(prefs.getString("usb_ip", "192.168.7.1/24")));
|
||||
// }
|
||||
// case 2:
|
||||
// if (prefs.getBoolean("bluetooth_persistent_enable", true)) {
|
||||
// param.setResult(linkAddressConstructor.newInstance(prefs.getString("usb_ip", "192.168.8.1/24")));
|
||||
// }
|
||||
// default:
|
||||
// //super.afterHookedMethod(param);
|
||||
//
|
||||
// }
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
|
||||
// Class linkAddressClass = XposedHelpers.findClass("android.net.LinkAddress", loadPackageParam.classLoader);
|
||||
// Constructor linkAddressConstructor = linkAddressClass.getConstructor(String.class);
|
||||
// Class ipServerClass = XposedHelpers.findClass("android.net.ip.IpServer", loadPackageParam.classLoader);
|
||||
// Method interfaceTypeMethod = ipServerClass.getDeclaredMethod("interfaceType");
|
||||
// int iFaceType = (int) interfaceTypeMethod.invoke(methodHookParam.args[0]);
|
||||
// switch (iFaceType) {
|
||||
// case 3:
|
||||
// return linkAddressConstructor.newInstance("192.168.49.1/24");
|
||||
// case 0:
|
||||
// return linkAddressConstructor.newInstance("192.168.6.1/24");
|
||||
// case 1:
|
||||
// return linkAddressConstructor.newInstance("192.168.7.1/24");
|
||||
// default:
|
||||
// return linkAddressConstructor.newInstance("192.168.8.1/24");
|
||||
// }
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
73
app/src/main/java/run/evan/hotspotip/SettingsActivity.java
Normal file
73
app/src/main/java/run/evan/hotspotip/SettingsActivity.java
Normal file
@ -0,0 +1,73 @@
|
||||
package run.evan.hotspotip;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.view.View;
|
||||
|
||||
public class SettingsActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.settings_activity);
|
||||
checkEdXposed();
|
||||
if (savedInstanceState == null) {
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(R.id.fragment_container, new SettingsFragment()).commit();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("WorldReadableFiles")
|
||||
private void checkEdXposed() {
|
||||
try {
|
||||
// getSharedPreferences will hooked by LSPosed and change xml file path to /data/misc/edxp**
|
||||
// will not throw SecurityException
|
||||
//noinspection deprecation
|
||||
getSharedPreferences("conf", Context.MODE_WORLD_READABLE);
|
||||
} catch (SecurityException exception) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage("AA")
|
||||
.setPositiveButton(android.R.string.ok, (dialog12, which) -> finish())
|
||||
.setNegativeButton("BB", null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getPreferenceManager().setSharedPreferencesName("conf");
|
||||
addPreferencesFromResource(R.xml.root_preferences);
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
View list = view.findViewById(android.R.id.list);
|
||||
list.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||
list.setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getStableInsetBottom());
|
||||
return insets.consumeSystemWindowInsets();
|
||||
});
|
||||
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
}
|
5
app/src/main/res/layout/settings_activity.xml
Normal file
5
app/src/main/res/layout/settings_activity.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
@ -1,4 +1,8 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Material">
|
||||
<item name="android:colorAccent">#3F51B5</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -2,4 +2,12 @@
|
||||
<resources>
|
||||
<string name="app_name">固定热点IP</string>
|
||||
<string name="module_desc">使热点的IP固定不变</string>
|
||||
|
||||
|
||||
<string name="wlan_hotspot">无线热点</string>
|
||||
<string name="usb_hotspot">USB网络共享</string>
|
||||
<string name="bluetooth_hotspot">蓝牙网络共享</string>
|
||||
<string name="fixed_ip">固定IP开关</string>
|
||||
<string name="custom_ip">自定义IP</string>
|
||||
<string name="wlan_title">Custom IP</string>
|
||||
</resources>
|
@ -2,6 +2,5 @@
|
||||
<resources>
|
||||
<string-array name="scope">
|
||||
<item>android</item>
|
||||
<item>com.android.networkstack</item>
|
||||
</string-array>
|
||||
</resources>
|
@ -1,4 +1,12 @@
|
||||
<resources>
|
||||
<string name="app_name">Fixed Hotspot IP</string>
|
||||
<string name="module_desc">Make hotspot IP fixed</string>
|
||||
|
||||
<string name="wlan_hotspot">WLAN Hotspot</string>
|
||||
<string name="usb_hotspot">USB Hotspot</string>
|
||||
<string name="bluetooth_hotspot">Bluetooth Hotspot</string>
|
||||
<string name="fixed_ip">Fixed IP</string>
|
||||
<string name="custom_ip">Custom IP</string>
|
||||
<string name="wlan_title">Custom IP</string>
|
||||
|
||||
</resources>
|
@ -1,4 +1,7 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.LightStatusBar">
|
||||
<item name="android:colorAccent">#3F51B5</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
44
app/src/main/res/xml/root_preferences.xml
Normal file
44
app/src/main/res/xml/root_preferences.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory android:title="@string/wlan_hotspot">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="wlan_persistent_enable"
|
||||
android:title="@string/fixed_ip" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="192.168.6.1/24"
|
||||
android:key="wlan_ip"
|
||||
android:singleLine="true"
|
||||
android:title="@string/custom_ip" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/usb_hotspot">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="usb_persistent_enable"
|
||||
android:title="@string/fixed_ip" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="192.168.7.1/24"
|
||||
android:key="usb_ip"
|
||||
android:singleLine="true"
|
||||
android:title="@string/custom_ip" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/bluetooth_hotspot">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="bluetooth_persistent_enable"
|
||||
android:title="@string/fixed_ip" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="192.168.8.1/24"
|
||||
android:key="bluetooth_ip"
|
||||
android:singleLine="true"
|
||||
android:title="@string/custom_ip" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user