mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
override apn setting
This commit is contained in:
@@ -8,8 +8,13 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.net.wifi.WifiSsid
|
||||
import android.os.Build.VERSION
|
||||
import android.telephony.TelephonyManager
|
||||
import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID
|
||||
import android.telephony.data.ApnSetting
|
||||
import android.telephony.data.ApnSetting.*
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
@@ -18,15 +23,19 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
|
||||
@Composable
|
||||
fun Network(){
|
||||
@@ -248,6 +257,373 @@ fun Network(){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(VERSION.SDK_INT>=28&&isDeviceOwner(myDpm)){
|
||||
Column(modifier = sections()){
|
||||
val setting = myDpm.getOverrideApns(myComponent)
|
||||
var inputNum by remember{mutableStateOf("0")}
|
||||
var nextStep by remember{mutableStateOf(false)}
|
||||
val builder = Builder()
|
||||
Text(text = "APN设置", style = typography.titleLarge)
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
|
||||
Text(text = "启用", style = typography.titleLarge)
|
||||
Switch(checked = myDpm.isOverrideApnEnabled(myComponent), onCheckedChange = {myDpm.setOverrideApnsEnabled(myComponent,it)})
|
||||
}
|
||||
Text(text = "一共有${setting.size}个APN设置", style = bodyTextStyle)
|
||||
if(setting.size>0){
|
||||
Text(text = "选择一个你要修改的APN设置(1~${setting.size})或者输入0以新建APN设置", style = bodyTextStyle)
|
||||
TextField(
|
||||
value = inputNum,
|
||||
label = { Text("序号")},
|
||||
onValueChange = {inputNum = it},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp),
|
||||
enabled = !nextStep
|
||||
)
|
||||
}else{
|
||||
Text(text = "当前没有APN设置,你可以新建一个APN设置", style = bodyTextStyle)
|
||||
}
|
||||
Button(
|
||||
onClick = {focusMgr.clearFocus(); nextStep=!nextStep},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = inputNum!=""&&(nextStep||inputNum=="0"||setting[inputNum.toInt()-1]!=null)
|
||||
) {
|
||||
Text(if(nextStep){"上一步"}else{"下一步"})
|
||||
}
|
||||
var result = Builder().build()
|
||||
AnimatedVisibility(nextStep) {
|
||||
/*TODO*/
|
||||
var carrierEnabled by remember{mutableStateOf(false)}
|
||||
var inputApnName by remember{mutableStateOf("")}
|
||||
var user by remember{mutableStateOf("")}
|
||||
var profileId by remember{mutableStateOf("")}
|
||||
var selectedAuthType by remember{mutableIntStateOf(AUTH_TYPE_NONE)}
|
||||
var carrierId by remember{mutableStateOf("$UNKNOWN_CARRIER_ID")}
|
||||
var apnTypeBitmask by remember{mutableStateOf("")}
|
||||
var entryName by remember{mutableStateOf("")}
|
||||
var mmsProxyAddress by remember{mutableStateOf("")}
|
||||
var mmsProxyPort by remember{mutableStateOf("")}
|
||||
var proxyAddress by remember{mutableStateOf("")}
|
||||
var proxyPort by remember{mutableStateOf("")}
|
||||
var mmsc by remember{mutableStateOf("")}
|
||||
var mtuV4 by remember{mutableStateOf("")}
|
||||
var mtuV6 by remember{mutableStateOf("")}
|
||||
var mvnoType by remember{mutableIntStateOf(-1)}
|
||||
var networkTypeBitmask by remember{mutableStateOf("")}
|
||||
var operatorNumeric by remember{mutableStateOf("")}
|
||||
var password by remember{mutableStateOf("")}
|
||||
var persistent by remember{mutableStateOf(false)}
|
||||
var protocol by remember{mutableIntStateOf(-1)}
|
||||
var roamingProtocol by remember{mutableIntStateOf(-1)}
|
||||
var id by remember{mutableStateOf(0)}
|
||||
|
||||
if(inputNum!="0"){
|
||||
val current = setting[inputNum.toInt()-1]
|
||||
id = current.id
|
||||
carrierEnabled = current.isEnabled
|
||||
inputApnName = current.apnName
|
||||
user = current.user
|
||||
if(VERSION.SDK_INT>=33){profileId = current.profileId.toString()}
|
||||
selectedAuthType = current.authType
|
||||
apnTypeBitmask = current.apnTypeBitmask.toString()
|
||||
entryName = current.entryName
|
||||
if(VERSION.SDK_INT>=29){mmsProxyAddress = current.mmsProxyAddressAsString}
|
||||
mmsProxyPort = current.mmsProxyPort.toString()
|
||||
if(VERSION.SDK_INT>=29){proxyAddress = current.proxyAddressAsString}
|
||||
proxyPort = current.proxyPort.toString()
|
||||
mmsc = current.mmsc.toString()
|
||||
if(VERSION.SDK_INT>=33){ mtuV4 = current.mtuV4.toString(); mtuV6 = current.mtuV6.toString() }
|
||||
mvnoType = current.mvnoType
|
||||
networkTypeBitmask = current.networkTypeBitmask.toString()
|
||||
operatorNumeric = current.operatorNumeric
|
||||
password = current.password
|
||||
if(VERSION.SDK_INT>=33){persistent = current.isPersistent}
|
||||
protocol = current.protocol
|
||||
roamingProtocol = current.roamingProtocol
|
||||
}
|
||||
|
||||
Column {
|
||||
|
||||
Text(text = "APN", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = inputApnName,
|
||||
onValueChange = {inputApnName=it},
|
||||
label = {Text("名称")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
|
||||
Text(text = "启用", style = typography.titleLarge)
|
||||
Switch(checked = carrierEnabled, onCheckedChange = {carrierEnabled=it})
|
||||
}
|
||||
|
||||
Text(text = "用户名", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = user,
|
||||
onValueChange = {user=it},
|
||||
label = {Text("用户名")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
if(VERSION.SDK_INT>=33){
|
||||
Text(text = "资料ID", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = profileId,
|
||||
onValueChange = {profileId=it},
|
||||
label = {Text("ID")},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Text(text = "验证类型", style = typography.titleLarge)
|
||||
RadioButtonItem("无",{selectedAuthType==AUTH_TYPE_NONE},{selectedAuthType=AUTH_TYPE_NONE})
|
||||
RadioButtonItem("CHAP",{selectedAuthType==AUTH_TYPE_CHAP},{selectedAuthType=AUTH_TYPE_CHAP})
|
||||
RadioButtonItem("PAP",{selectedAuthType==AUTH_TYPE_PAP},{selectedAuthType=AUTH_TYPE_PAP})
|
||||
RadioButtonItem("PAP/CHAP",{selectedAuthType==AUTH_TYPE_PAP_OR_CHAP},{selectedAuthType=AUTH_TYPE_PAP_OR_CHAP})
|
||||
|
||||
if(VERSION.SDK_INT>=29){
|
||||
val ts = myContext.getSystemService(ComponentActivity.TELEPHONY_SERVICE) as TelephonyManager
|
||||
carrierId = ts.simCarrierId.toString()
|
||||
Text(text = "CarrierID", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = carrierId,
|
||||
onValueChange = {carrierId=it},
|
||||
label = {Text("ID")},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Text(text = "APN类型", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = apnTypeBitmask,
|
||||
onValueChange = {apnTypeBitmask=it},
|
||||
label = {Text("位掩码")},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
Text(text = "描述", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = entryName,
|
||||
onValueChange = {entryName=it},
|
||||
label = {Text("文本")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
Text(text = "MMS代理", style = typography.titleLarge)
|
||||
if(VERSION.SDK_INT>=29){
|
||||
TextField(
|
||||
value = mmsProxyAddress,
|
||||
onValueChange = {mmsProxyAddress=it},
|
||||
label = {Text("地址")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
}
|
||||
TextField(
|
||||
value = mmsProxyPort,
|
||||
onValueChange = {mmsProxyPort=it},
|
||||
label = {Text("端口")},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
Text(text = "代理", style = typography.titleLarge)
|
||||
if(VERSION.SDK_INT>=29){
|
||||
TextField(
|
||||
value = proxyAddress,
|
||||
onValueChange = {proxyAddress=it},
|
||||
label = {Text("地址")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
}
|
||||
TextField(
|
||||
value = proxyPort,
|
||||
onValueChange = {proxyPort=it},
|
||||
label = {Text("端口")},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
Text(text = "MMSC", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = mmsc,
|
||||
onValueChange = {mmsc=it},
|
||||
label = {Text("Uri")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
if(VERSION.SDK_INT>=33){
|
||||
Text(text = "MTU", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = mtuV4,
|
||||
onValueChange = {mtuV4=it},
|
||||
label = {Text("IPV4")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
TextField(
|
||||
value = mtuV6,
|
||||
onValueChange = {mtuV6=it},
|
||||
label = {Text("IPV6")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
Text(text = "MVNO", style = typography.titleLarge)
|
||||
RadioButtonItem("SPN",{mvnoType==MVNO_TYPE_SPN},{mvnoType=MVNO_TYPE_SPN})
|
||||
RadioButtonItem("IMSI",{mvnoType==MVNO_TYPE_IMSI},{mvnoType=MVNO_TYPE_IMSI})
|
||||
RadioButtonItem("GID",{mvnoType==MVNO_TYPE_GID},{mvnoType=MVNO_TYPE_GID})
|
||||
RadioButtonItem("ICCID",{mvnoType==MVNO_TYPE_ICCID},{mvnoType=MVNO_TYPE_ICCID})
|
||||
|
||||
Text(text = "网络类型", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = networkTypeBitmask,
|
||||
onValueChange = {networkTypeBitmask=it},
|
||||
label = {Text("位掩码")},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
Text(text = "OperatorNumeric", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = operatorNumeric,
|
||||
onValueChange = {operatorNumeric=it},
|
||||
label = {Text("ID")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
Text(text = "密码", style = typography.titleLarge)
|
||||
TextField(
|
||||
value = password,
|
||||
onValueChange = {password=it},
|
||||
label = {Text("密码")},
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 2.dp, bottom = 4.dp)
|
||||
)
|
||||
|
||||
if(VERSION.SDK_INT>=33){
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically){
|
||||
Text(text = "持久的", style = typography.titleLarge)
|
||||
Switch(checked = persistent, onCheckedChange = {persistent=it})
|
||||
}
|
||||
}
|
||||
|
||||
Text(text = "协议", style = typography.titleLarge)
|
||||
RadioButtonItem("IPV4",{protocol==PROTOCOL_IP},{protocol=PROTOCOL_IP})
|
||||
RadioButtonItem("IPV6",{protocol==PROTOCOL_IPV6},{protocol=PROTOCOL_IPV6})
|
||||
RadioButtonItem("IPV4/IPV6",{protocol==PROTOCOL_IPV4V6},{protocol=PROTOCOL_IPV4V6})
|
||||
RadioButtonItem("PPP",{protocol==PROTOCOL_PPP},{protocol=PROTOCOL_PPP})
|
||||
if(VERSION.SDK_INT>=29){
|
||||
RadioButtonItem("non-IP",{protocol==PROTOCOL_NON_IP},{protocol=PROTOCOL_NON_IP})
|
||||
RadioButtonItem("Unstructured",{protocol==PROTOCOL_UNSTRUCTURED},{protocol=PROTOCOL_UNSTRUCTURED})
|
||||
}
|
||||
|
||||
Text(text = "漫游协议", style = typography.titleLarge)
|
||||
RadioButtonItem("IPV4",{roamingProtocol==PROTOCOL_IP},{roamingProtocol=PROTOCOL_IP})
|
||||
RadioButtonItem("IPV6",{roamingProtocol==PROTOCOL_IPV6},{roamingProtocol=PROTOCOL_IPV6})
|
||||
RadioButtonItem("IPV4/IPV6",{roamingProtocol==PROTOCOL_IPV4V6},{roamingProtocol=PROTOCOL_IPV4V6})
|
||||
RadioButtonItem("PPP",{roamingProtocol==PROTOCOL_PPP},{roamingProtocol=PROTOCOL_PPP})
|
||||
if(VERSION.SDK_INT>=29){
|
||||
RadioButtonItem("non-IP",{roamingProtocol==PROTOCOL_NON_IP},{roamingProtocol=PROTOCOL_NON_IP})
|
||||
RadioButtonItem("Unstructured",{roamingProtocol==PROTOCOL_UNSTRUCTURED},{roamingProtocol=PROTOCOL_UNSTRUCTURED})
|
||||
}
|
||||
|
||||
var finalStep by remember{mutableStateOf(false)}
|
||||
Button(
|
||||
onClick = {
|
||||
if(!finalStep){
|
||||
builder.setCarrierEnabled(carrierEnabled)
|
||||
builder.setApnName(inputApnName)
|
||||
builder.setUser(user)
|
||||
if(VERSION.SDK_INT>=33){builder.setProfileId(profileId.toInt())}
|
||||
builder.setAuthType(selectedAuthType)
|
||||
if(VERSION.SDK_INT>=29){builder.setCarrierId(carrierId.toInt())}
|
||||
builder.setApnTypeBitmask(apnTypeBitmask.toInt())
|
||||
builder.setEntryName(entryName)
|
||||
if(VERSION.SDK_INT>=29){builder.setMmsProxyAddress(mmsProxyAddress)}
|
||||
builder.setMmsProxyPort(mmsProxyPort.toInt())
|
||||
if(VERSION.SDK_INT>=29){builder.setProxyAddress(proxyAddress)}
|
||||
builder.setProxyPort(proxyPort.toInt())
|
||||
builder.setMmsc(mmsc.toUri())
|
||||
if(VERSION.SDK_INT>=33){ builder.setMtuV4(mtuV4.toInt()); builder.setMtuV6(mtuV6.toInt()) }
|
||||
builder.setMvnoType(mvnoType)
|
||||
builder.setNetworkTypeBitmask(networkTypeBitmask.toInt())
|
||||
builder.setOperatorNumeric(operatorNumeric)
|
||||
builder.setPassword(password)
|
||||
if(VERSION.SDK_INT>=33){builder.setPersistent(persistent)}
|
||||
builder.setProtocol(protocol)
|
||||
builder.setRoamingProtocol(roamingProtocol)
|
||||
result = builder.build()
|
||||
}
|
||||
|
||||
finalStep=!finalStep
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(if(finalStep){"上一步"}else{"下一步"})
|
||||
}
|
||||
AnimatedVisibility(finalStep) {
|
||||
if(inputNum=="0"){
|
||||
Button(
|
||||
onClick = {myDpm.addOverrideApn(myComponent,result)},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("新建")
|
||||
}
|
||||
}else{
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
|
||||
Button(
|
||||
onClick = {
|
||||
val success = myDpm.updateOverrideApn(myComponent,id,result)
|
||||
Toast.makeText(myContext, if(success){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
Modifier.fillMaxWidth(0.49F)
|
||||
){
|
||||
Text("更新")
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
val success = myDpm.removeOverrideApn(myComponent,id)
|
||||
Toast.makeText(myContext, if(success){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
Modifier.fillMaxWidth(0.96F)
|
||||
){
|
||||
Text("移除")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Text(text = "这个功能没有被全面测试过", style = bodyTextStyle)
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user