mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-05-20 16:15:47 +08:00
Android CA Install guide
This commit is contained in:
@@ -237,6 +237,8 @@ class _SslState extends State<SslWidget> {
|
||||
]),
|
||||
ListView(
|
||||
children: [
|
||||
Text(localizations.androidUserCATips, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
const SizedBox(height: 10),
|
||||
SelectableText.rich(TextSpan(
|
||||
text:
|
||||
"1. ${localizations.configWifiProxy} Host:$host Port:${widget.proxyServer.port}")),
|
||||
|
||||
@@ -83,7 +83,6 @@ class _AppWhitelistState extends State<AppWhitelist> {
|
||||
body: FutureBuilder(
|
||||
future: Future.wait(appWhitelist),
|
||||
builder: (BuildContext context, AsyncSnapshot<List<AppInfo>> snapshot) {
|
||||
print(snapshot.data);
|
||||
if (snapshot.hasData) {
|
||||
if (snapshot.data!.isEmpty) {
|
||||
return Center(
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_toastr/flutter_toastr.dart';
|
||||
import 'package:network_proxy/network/bin/server.dart';
|
||||
import 'package:network_proxy/network/util/crts.dart';
|
||||
import 'package:network_proxy/network/util/file_read.dart';
|
||||
import 'package:network_proxy/utils/lang.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class MobileSslWidget extends StatefulWidget {
|
||||
@@ -36,7 +40,7 @@ class _MobileSslState extends State<MobileSslWidget> {
|
||||
title: Text(localizations.httpsProxy, style: const TextStyle(fontSize: 16)),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: ListView(children: [
|
||||
body: Column(children: [
|
||||
SwitchListTile(
|
||||
hoverColor: Colors.transparent,
|
||||
title: Text(localizations.enabledHttps),
|
||||
@@ -48,13 +52,13 @@ class _MobileSslState extends State<MobileSslWidget> {
|
||||
CertificateManager.cleanCache();
|
||||
setState(() {});
|
||||
}),
|
||||
Platform.isIOS ? ios() : Padding(padding: const EdgeInsets.only(left: 15), child: android()),
|
||||
const SizedBox(height: 20)
|
||||
Expanded(child: Platform.isIOS ? ios() : const AndroidCaInstall()),
|
||||
// const SizedBox(height: 20)
|
||||
]));
|
||||
}
|
||||
|
||||
Widget ios() {
|
||||
return Column(children: [
|
||||
return ListView(children: [
|
||||
// if (localizations.localeName != 'zh')
|
||||
// ExpansionTile(
|
||||
// title: Text(localizations.useGuide),
|
||||
@@ -89,64 +93,127 @@ class _MobileSslState extends State<MobileSslWidget> {
|
||||
]);
|
||||
}
|
||||
|
||||
Widget android() {
|
||||
bool isCN = localizations.localeName == 'zh';
|
||||
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(localizations.installRootCa),
|
||||
ExpansionTile(
|
||||
title: Text(localizations.androidRoot, style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 14)),
|
||||
tilePadding: const EdgeInsets.only(left: 0),
|
||||
expandedAlignment: Alignment.topLeft,
|
||||
initiallyExpanded: true,
|
||||
shape: const Border(),
|
||||
children: [
|
||||
Text(localizations.androidRootMagisk),
|
||||
TextButton(
|
||||
child: Text("https://${isCN ? 'gitee' : 'github'}.com/wanghongenpin/Magisk-ProxyPinCA/releases"),
|
||||
onPressed: () {
|
||||
launchUrl(
|
||||
Uri.parse("https://${isCN ? 'gitee' : 'github'}.com/wanghongenpin/Magisk-ProxyPinCA/releases"));
|
||||
}),
|
||||
SelectableText(localizations.androidRootRename),
|
||||
]),
|
||||
const SizedBox(height: 20),
|
||||
ExpansionTile(
|
||||
title: Text(localizations.androidUserCA, style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 14)),
|
||||
tilePadding: const EdgeInsets.only(left: 0),
|
||||
expandedAlignment: Alignment.topLeft,
|
||||
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
||||
initiallyExpanded: true,
|
||||
shape: const Border(),
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () => _downloadCert(),
|
||||
child: Text.rich(TextSpan(children: [
|
||||
TextSpan(text: "1. ${localizations.downloadRootCa} "),
|
||||
WidgetSpan(child: SelectableText("http://127.0.0.1:${widget.proxyServer.port}/ssl"))
|
||||
]))),
|
||||
TextButton(onPressed: () {}, child: Text("2. ${localizations.androidUserCAInstall}")),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
launchUrl(Uri.parse(isCN
|
||||
? "https://gitee.com/wanghongenpin/network-proxy-flutter/wikis/%E5%AE%89%E5%8D%93%E6%97%A0ROOT%E4%BD%BF%E7%94%A8Xposed%E6%A8%A1%E5%9D%97%E6%8A%93%E5%8C%85"
|
||||
: "https://github.com/wanghongenpin/network_proxy_flutter/wiki/Android-without-ROOT-uses-Xposed-module-to-capture-packets"));
|
||||
},
|
||||
child: Text(localizations.androidUserXposed)),
|
||||
ClipRRect(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
heightFactor: .7,
|
||||
child: Image.network(
|
||||
"https://foruda.gitee.com/images/1689352695624941051/74e3bed6_1073801.png",
|
||||
height: 680,
|
||||
)))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
void _downloadCert() async {
|
||||
CertificateManager.cleanCache();
|
||||
launchUrl(Uri.parse("http://127.0.0.1:${widget.proxyServer.port}/ssl"), mode: LaunchMode.externalApplication);
|
||||
}
|
||||
}
|
||||
|
||||
class AndroidCaInstall extends StatefulWidget {
|
||||
const AndroidCaInstall({super.key});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _AndroidCaInstallState();
|
||||
}
|
||||
|
||||
class _AndroidCaInstallState extends State<AndroidCaInstall> with SingleTickerProviderStateMixin {
|
||||
late TabController _tabController;
|
||||
|
||||
AppLocalizations get localizations => AppLocalizations.of(context)!;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(length: 2, vsync: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
endDrawerEnableOpenDragGesture: false,
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
title: Text(localizations.installRootCa, style: const TextStyle(fontSize: 16)),
|
||||
bottom: TabBar(
|
||||
controller: _tabController,
|
||||
labelPadding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
tabs: <Widget>[
|
||||
Tab(text: localizations.androidRoot),
|
||||
Tab(text: localizations.androidUserCA),
|
||||
])),
|
||||
body: TabBarView(controller: _tabController, children: [rootCA(), userCA()]));
|
||||
}
|
||||
|
||||
rootCA() {
|
||||
bool isCN = localizations.localeName == 'zh';
|
||||
return ListView(padding: const EdgeInsets.all(10), children: [
|
||||
Text(localizations.androidRootMagisk),
|
||||
TextButton(
|
||||
child: Text("https://${isCN ? 'gitee' : 'github'}.com/wanghongenpin/Magisk-ProxyPinCA/releases"),
|
||||
onPressed: () {
|
||||
launchUrl(Uri.parse("https://${isCN ? 'gitee' : 'github'}.com/wanghongenpin/Magisk-ProxyPinCA/releases"));
|
||||
}),
|
||||
const SizedBox(height: 15),
|
||||
SelectableText(localizations.androidRootRename, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
const SizedBox(height: 10),
|
||||
FilledButton(onPressed: () => _downloadCert('243f0bfb.0'), child: Text(localizations.androidRootCADownload)),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Android 13: ${isCN ? "将证书挂载到" : "Mount the certificate to"} '/system/etc/security/cacerts' ${isCN ? "目录" : "Directory"}"
|
||||
.fixAutoLines()),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
"Android 14: ${isCN ? "将证书挂载到" : "Mount the certificate to"} '/apex/com.android.conscrypt/cacerts' ${isCN ? "目录" : "Directory"}"
|
||||
.fixAutoLines()),
|
||||
const SizedBox(height: 5),
|
||||
ClipRRect(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Image.network(
|
||||
scale: 0.5,
|
||||
"https://foruda.gitee.com/images/1710181660282752846/cb520c0b_1073801.png",
|
||||
height: 460,
|
||||
)))
|
||||
]);
|
||||
}
|
||||
|
||||
userCA() {
|
||||
bool isCN = localizations.localeName == 'zh';
|
||||
|
||||
return ListView(padding: const EdgeInsets.all(10), children: [
|
||||
Text(localizations.androidUserCATips, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
const SizedBox(height: 5),
|
||||
TextButton(
|
||||
style: const ButtonStyle(alignment: Alignment.centerLeft),
|
||||
onPressed: () {},
|
||||
child: Text("1. ${localizations.downloadRootCa} ", textAlign: TextAlign.left),
|
||||
),
|
||||
FilledButton(onPressed: () => _downloadCert('243f0bfb.0'), child: Text(localizations.downloadRootCa)),
|
||||
const SizedBox(height: 5),
|
||||
TextButton(onPressed: () {}, child: Text("2. ${localizations.androidUserCAInstall}")),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
launchUrl(Uri.parse(isCN
|
||||
? "https://gitee.com/wanghongenpin/network-proxy-flutter/wikis/%E5%AE%89%E5%8D%93%E6%97%A0ROOT%E4%BD%BF%E7%94%A8Xposed%E6%A8%A1%E5%9D%97%E6%8A%93%E5%8C%85"
|
||||
: "https://github.com/wanghongenpin/network_proxy_flutter/wiki/Android-without-ROOT-uses-Xposed-module-to-capture-packets"));
|
||||
},
|
||||
child: Text(localizations.androidUserXposed)),
|
||||
ClipRRect(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
heightFactor: .7,
|
||||
child: Image.network(
|
||||
"https://foruda.gitee.com/images/1689352695624941051/74e3bed6_1073801.png",
|
||||
height: 680,
|
||||
)))
|
||||
]);
|
||||
}
|
||||
|
||||
void _downloadCert(String name) async {
|
||||
String? outputFile = await FilePicker.platform.saveFile(
|
||||
dialogTitle: 'Please select the path to save:',
|
||||
fileName: name,
|
||||
bytes: await FileRead.read('assets/certs/ca.crt'));
|
||||
|
||||
if (outputFile != null && mounted) {
|
||||
AppLocalizations localizations = AppLocalizations.of(context)!;
|
||||
FlutterToastr.show(localizations.success, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user