Target Android 13 on freedom as well
This commit is contained in:
@@ -11,8 +11,6 @@ Connecting things to your VPN made simple. Share your VPN connection over hotspo
|
|||||||
|
|
||||||
| Release channel | [GitHub (recommended)](https://github.com/Mygod/VPNHotspot/releases) | [Google Play](https://play.google.com/store/apps/details?id=be.mygod.vpnhotspot) ([beta](https://play.google.com/apps/testing/be.mygod.vpnhotspot)) |
|
| Release channel | [GitHub (recommended)](https://github.com/Mygod/VPNHotspot/releases) | [Google Play](https://play.google.com/store/apps/details?id=be.mygod.vpnhotspot) ([beta](https://play.google.com/apps/testing/be.mygod.vpnhotspot)) |
|
||||||
|---------------------------------------------------------|:--------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------:|
|
|---------------------------------------------------------|:--------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------:|
|
||||||
| Monitor connected clients without root | Up to Android 12L | Up to Android 10 |
|
|
||||||
| Use repeater/temporary hotspot without location enabled | Up to Android 10/9 | Up to Android 10/9 or Android 13+ |
|
|
||||||
| Auto update | Email updates via watching releases | ✓ |
|
| Auto update | Email updates via watching releases | ✓ |
|
||||||
| In-app update channel | GitHub | Google Play |
|
| In-app update channel | GitHub | Google Play |
|
||||||
| [Sponsor/Donation](https://github.com/sponsors/Mygod) | ✓ | Google Play In-App Purchases only |
|
| [Sponsor/Donation](https://github.com/sponsors/Mygod) | ✓ | Google Play In-App Purchases only |
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "be.mygod.vpnhotspot"
|
applicationId = "be.mygod.vpnhotspot"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
@android.annotation.SuppressLint("ExpiredTargetSdkVersion")
|
targetSdk = 33
|
||||||
targetSdk = 29
|
|
||||||
resourceConfigurations.addAll(arrayOf("it", "ru", "zh-rCN", "zh-rTW"))
|
resourceConfigurations.addAll(arrayOf("it", "ru", "zh-rCN", "zh-rTW"))
|
||||||
versionCode = 302
|
versionCode = 302
|
||||||
versionName = "2.15.2"
|
versionName = "2.15.2"
|
||||||
@@ -35,7 +34,6 @@ android {
|
|||||||
put("room.schemaLocation", "$projectDir/schemas")
|
put("room.schemaLocation", "$projectDir/schemas")
|
||||||
}
|
}
|
||||||
buildConfigField("boolean", "DONATIONS", "true")
|
buildConfigField("boolean", "DONATIONS", "true")
|
||||||
buildConfigField("int", "TARGET_SDK", "29")
|
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
dataBinding = true
|
dataBinding = true
|
||||||
@@ -59,10 +57,8 @@ android {
|
|||||||
}
|
}
|
||||||
create("google") {
|
create("google") {
|
||||||
dimension = "freedom"
|
dimension = "freedom"
|
||||||
targetSdk = 33
|
|
||||||
versionNameSuffix = "-g"
|
versionNameSuffix = "-g"
|
||||||
buildConfigField("boolean", "DONATIONS", "false")
|
buildConfigField("boolean", "DONATIONS", "false")
|
||||||
buildConfigField("int", "TARGET_SDK", "33")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceSets.getByName("androidTest").assets.srcDir("$projectDir/schemas")
|
sourceSets.getByName("androidTest").assets.srcDir("$projectDir/schemas")
|
||||||
@@ -85,6 +81,7 @@ dependencies {
|
|||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||||
implementation("be.mygod.librootkotlinx:librootkotlinx:1.0.0")
|
implementation("be.mygod.librootkotlinx:librootkotlinx:1.0.0")
|
||||||
implementation("com.android.billingclient:billing-ktx:5.1.0")
|
implementation("com.android.billingclient:billing-ktx:5.1.0")
|
||||||
|
implementation("com.github.tiann:FreeReflection:3.1.0")
|
||||||
implementation("com.google.android.gms:play-services-oss-licenses:17.0.0")
|
implementation("com.google.android.gms:play-services-oss-licenses:17.0.0")
|
||||||
implementation("com.google.android.material:material:1.7.0")
|
implementation("com.google.android.material:material:1.7.0")
|
||||||
implementation("com.google.firebase:firebase-analytics-ktx:21.2.0")
|
implementation("com.google.firebase:firebase-analytics-ktx:21.2.0")
|
||||||
@@ -95,7 +92,6 @@ dependencies {
|
|||||||
implementation("com.takisoft.preferencex:preferencex-simplemenu:1.1.0")
|
implementation("com.takisoft.preferencex:preferencex-simplemenu:1.1.0")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.5")
|
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.5")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
|
||||||
add("googleImplementation", "com.github.tiann:FreeReflection:3.1.0")
|
|
||||||
add("googleImplementation", "com.google.android.play:core:1.10.3")
|
add("googleImplementation", "com.google.android.play:core:1.10.3")
|
||||||
add("googleImplementation", "com.google.android.play:core-ktx:1.8.1")
|
add("googleImplementation", "com.google.android.play:core-ktx:1.8.1")
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package be.mygod.vpnhotspot.util
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import java.lang.reflect.Method
|
|
||||||
|
|
||||||
fun UnblockHelper(context: Context) {
|
|
||||||
val getDeclaredMethod = Class::class.java.getDeclaredMethod("getDeclaredMethod",
|
|
||||||
String::class.java, arrayOf<Class<*>>()::class.java)
|
|
||||||
val clazz = Class.forName("dalvik.system.VMRuntime")
|
|
||||||
val setHiddenApiExemptions = getDeclaredMethod(clazz, "setHiddenApiExemptions",
|
|
||||||
arrayOf(Array<String>::class.java)) as Method
|
|
||||||
setHiddenApiExemptions(clazz.getDeclaredMethod("getRuntime")(null), arrayOf(""))
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<!-- Required since API 31, when targeting API 31 -->
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
|
||||||
<!-- Required since API 33, when targeting API 33 -->
|
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
|
||||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"
|
|
||||||
android:maxSdkVersion="32"/>
|
|
||||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"
|
|
||||||
android:maxSdkVersion="32"/>
|
|
||||||
</manifest>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package be.mygod.vpnhotspot.util
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import me.weishu.reflection.Reflection
|
|
||||||
|
|
||||||
fun UnblockHelper(context: Context) {
|
|
||||||
check(Reflection.unseal(context) == 0)
|
|
||||||
}
|
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
||||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
android:usesPermissionFlags="neverForLocation"/>
|
android:usesPermissionFlags="neverForLocation"/>
|
||||||
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
|
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
|
||||||
tools:ignore="ProtectedPermissions"/>
|
tools:ignore="ProtectedPermissions"/>
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||||
<uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL"
|
<uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL"
|
||||||
tools:ignore="ProtectedPermissions"/>
|
tools:ignore="ProtectedPermissions"/>
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
@@ -50,9 +52,10 @@
|
|||||||
tools:ignore="ProtectedPermissions"/>
|
tools:ignore="ProtectedPermissions"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"
|
<uses-permission android:name="android.permission.WRITE_SETTINGS"
|
||||||
tools:ignore="ProtectedPermissions"/>
|
tools:ignore="ProtectedPermissions"/>
|
||||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"
|
||||||
<!-- Required since API 29 -->
|
android:maxSdkVersion="32"/>
|
||||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||||
|
android:maxSdkVersion="32"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
|
|||||||
@@ -115,12 +115,13 @@ class App : Application() {
|
|||||||
* https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiSettingsStore.java#228
|
* https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiSettingsStore.java#228
|
||||||
*/
|
*/
|
||||||
inline fun <reified T> startServiceWithLocation(context: Context) {
|
inline fun <reified T> startServiceWithLocation(context: Context) {
|
||||||
if (BuildConfig.TARGET_SDK >= 33 && Build.VERSION.SDK_INT >= 33 || if (Build.VERSION.SDK_INT >= 28) {
|
val canStart = Build.VERSION.SDK_INT >= 33 || if (Build.VERSION.SDK_INT >= 28) {
|
||||||
location?.isLocationEnabled == true
|
location?.isLocationEnabled == true
|
||||||
} else @Suppress("DEPRECATION") {
|
} else @Suppress("DEPRECATION") {
|
||||||
Settings.Secure.getInt(context.contentResolver, Settings.Secure.LOCATION_MODE,
|
Settings.Secure.getInt(context.contentResolver, Settings.Secure.LOCATION_MODE,
|
||||||
Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF
|
Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF
|
||||||
}) ContextCompat.startForegroundService(context, Intent(context, T::class.java)) else try {
|
}
|
||||||
|
if (canStart) ContextCompat.startForegroundService(context, Intent(context, T::class.java)) else try {
|
||||||
context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
|
context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
|
||||||
Toast.makeText(context, R.string.tethering_location_off, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, R.string.tethering_location_off, Toast.LENGTH_LONG).show()
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import java.net.NetworkInterface
|
|||||||
class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager(), ServiceConnection {
|
class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager(), ServiceConnection {
|
||||||
companion object {
|
companion object {
|
||||||
val permission = when {
|
val permission = when {
|
||||||
BuildConfig.TARGET_SDK >= 33 && Build.VERSION.SDK_INT >= 33 -> Manifest.permission.NEARBY_WIFI_DEVICES
|
Build.VERSION.SDK_INT >= 33 -> Manifest.permission.NEARBY_WIFI_DEVICES
|
||||||
Build.VERSION.SDK_INT >= 29 -> Manifest.permission.ACCESS_FINE_LOCATION
|
Build.VERSION.SDK_INT >= 29 -> Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
else -> Manifest.permission.ACCESS_COARSE_LOCATION
|
else -> Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
|
|||||||
when (binder?.service?.status) {
|
when (binder?.service?.status) {
|
||||||
RepeaterService.Status.IDLE -> if (Build.VERSION.SDK_INT < 29) parent.requireContext().let { context ->
|
RepeaterService.Status.IDLE -> if (Build.VERSION.SDK_INT < 29) parent.requireContext().let { context ->
|
||||||
ContextCompat.startForegroundService(context, Intent(context, RepeaterService::class.java))
|
ContextCompat.startForegroundService(context, Intent(context, RepeaterService::class.java))
|
||||||
} else parent.startRepeater.launch(if (BuildConfig.TARGET_SDK >= 33 && Build.VERSION.SDK_INT >= 33) {
|
} else parent.startRepeater.launch(if (Build.VERSION.SDK_INT >= 33) {
|
||||||
Manifest.permission.NEARBY_WIFI_DEVICES
|
Manifest.permission.NEARBY_WIFI_DEVICES
|
||||||
} else Manifest.permission.ACCESS_FINE_LOCATION)
|
} else Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
RepeaterService.Status.ACTIVE -> binder.shutdown()
|
RepeaterService.Status.ACTIVE -> binder.shutdown()
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ abstract class IpMonitor {
|
|||||||
var currentMode: Mode
|
var currentMode: Mode
|
||||||
get() {
|
get() {
|
||||||
// Completely restricted on Android 13: https://github.com/termux/termux-app/issues/2993#issuecomment-1250312777
|
// Completely restricted on Android 13: https://github.com/termux/termux-app/issues/2993#issuecomment-1250312777
|
||||||
val isLegacy = Build.VERSION.SDK_INT < 33 && (Build.VERSION.SDK_INT < 30 || BuildConfig.TARGET_SDK < 30)
|
val defaultMode = if (Build.VERSION.SDK_INT < 30) @Suppress("DEPRECATION") {
|
||||||
val defaultMode = if (isLegacy) @Suppress("DEPRECATION") {
|
|
||||||
Mode.Poll
|
Mode.Poll
|
||||||
} else Mode.MonitorRoot
|
} else Mode.MonitorRoot
|
||||||
return Mode.valueOf(app.pref.getString(KEY, defaultMode.toString()) ?: "")
|
return Mode.valueOf(app.pref.getString(KEY, defaultMode.toString()) ?: "")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.net.wifi.SoftApConfiguration
|
|||||||
import android.net.wifi.p2p.WifiP2pConfig
|
import android.net.wifi.p2p.WifiP2pConfig
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
|
import me.weishu.reflection.Reflection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central object for accessing all the useful blocked APIs. Thanks Google!
|
* The central object for accessing all the useful blocked APIs. Thanks Google!
|
||||||
@@ -20,7 +21,7 @@ object UnblockCentral {
|
|||||||
/**
|
/**
|
||||||
* Retrieve this property before doing dangerous shit.
|
* Retrieve this property before doing dangerous shit.
|
||||||
*/
|
*/
|
||||||
private val init by lazy { if (needInit) UnblockHelper(app.deviceStorage) }
|
private val init by lazy { if (needInit) check(Reflection.unseal(app.deviceStorage) == 0) }
|
||||||
|
|
||||||
@RequiresApi(33)
|
@RequiresApi(33)
|
||||||
fun getCountryCode(clazz: Class<*>) = init.let { clazz.getDeclaredMethod("getCountryCode") }
|
fun getCountryCode(clazz: Class<*>) = init.let { clazz.getDeclaredMethod("getCountryCode") }
|
||||||
|
|||||||
Reference in New Issue
Block a user