Android集成
一、安卓
1.下载导入SDK
下载 ProxyLibrary-release.aar,放到项目的 libs 文件夹中,并使用 gradle 导入
implementation(files("libs\\ProxyLibrary-release.aar"))
或者导入libs目录中所有 jar 文件
implementation fileTree(dir: 'libs', include: ['*.jar'])
sdk最小支持安卓sdk26,所以您的项目中,运行在所有 API Level ≥ 26 的设备上
minSdk = 26
2.初始化
在 AndroidManifest.xml 文件中添加权限声明(网络权限和应用内部文件的读写)
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
在 AndroidManifest.xml 文件中的 application 标签内设置 com.wayl.proxy.UUID(修改,和iOS保持统一)
<meta-data
android:name="com.wayl.proxy.UUID"
android:value="xxxxxxxxxxxxxxxxxxxxxxxxx" />
完整 AndroidManifest.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.android"
usesCleartextTraffic="true"
tools:targetApi="31"
tools:ignore="MissingApplicationIcon">
<!--UUID-->
<meta-data
android:name="com.wayl.proxy.UUID"
android:value="xxxxxxxxxxxxxxxxxxx" />
<activity
android:name="com.proxy.test.MainActivity"
android:exported="true"
android:theme="@style/Theme.android">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
调用init初始化修改,直接调用
注意:
如果app存在权限申请,确保初始化和权限申请不要同步进行(最好在权限申请完成后调用)。
/**
* 初始化代理服务
*
* @param context 上下文
* @param callback 初始化完成后的回调
*/
public static Result init(@NonNull Context context) {}
val result = WaylProxy.init(this)
3.功能使用
启动代理,传入需要的端口号,启动成功以后将监听该本地端口的所有请求
当然也可以不传,我们默认会随机一个端口使用 {"data":{"port":8088},"message":"代理启动成功,监听端口: 8088","success":true}
/**
* 启动代理服务
*
* @param context 上下文
* @param port 端口号
* @return 启动结果
*/
public static Result start(@NonNull Context context, @NonNull Integer port) {}
/**
* 启动代理服务 (无端口)
*
* @param context 上下文
* @return 启动结果
*/
public static Result start(@NonNull Context context) {}
Result start = WaylProxy.start(context, 8080);
//成功打印数据 {"data":{"port":8080},"message":"代理启动成功,监听端口: 12345","success":true}
Result start = WaylProxy.start(context);
//成功打印数据 {"data":{"port":12345},"message":"代理启动成功,监听端口: 12345","success":true}
//获取当前版本
String version = WaylProxy.getVersion()
也可以调用该方法先拿到一个空闲端{"data":{"port":12348},"message":"完成","success":true}
Result result = WaylProxy.getFreePort();
//成功打印数据 {"data":{"port":12348},"message":"完成","success":true}
停止代理服务
WaylProxy.stop()
清除代理服务,该方法会清除掉所有的代理数据,(清理以后,是无法再次调用启动方法,需要初始化重新开启)
WaylProxy.clear()
获取代理状态,一共有三个值,
初始化是否成功
启动是否成功
验证套餐是否成功
// 初始化状态 true fasle
Boolean initStatus = WaylProxy.initStatus();
// 启动状态 true fasle
Boolean startStatus = WaylProxy.startStatus();
// 验证状态 true fasle
Boolean validationStatus = WaylProxy.validationStatus();
Log.i(TAG, "initStatus:" + initStatus);
Log.i(TAG, "validationStatus:" + validationStatus);
Log.i(TAG, "startStatus:" + startStatus);
//设置监听
WaylProxy.addStateChangeListener(new ProxyStateChangeListener() {
@Override
public void onInitStatusChanged(boolean newStatus) {
Log.i("WaylProxyListener", "初始化状态: " + newStatus);
}
@Override
public void onValidationStatusChanged(boolean newStatus) {
Log.i("WaylProxyListener", "验证状态: " + newStatus);
}
@Override
public void onStartStatusChanged(boolean newStatus) {
Log.i("WaylProxyListener", "验证状态: " + newStatus);
}
});
4.举例:
启动成功以后,sdk会监听本地端口的所有请求。
然后您将请求转入到本地的代理端口,类型全部是socks,http也可以。
socks 代理,如:socks://127.0.0.1:8080
http 代理,如:http://127.0.0.1:8080
如需要使用其他依赖,请查看其他第三方依赖如何设置请求代理,这里不一 一举例了
(建议需要代理的所有请求不要使用缓存)
okhttp设置代理 java:
// socks://127.0.0.1:8080
SocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socketAddress);
OkHttpClient client = new OkHttpClient.Builder()
.pingInterval(20, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(0, 1, TimeUnit.MILLISECONDS)) //禁用连接池
.cache(null)
.proxy(proxy)
.build();
整体使用案例kotlin:
package com.wayl.proxy.test
import android.annotation.SuppressLint
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.concurrent.TimeUnit
object OkHttpRequestClient {
private val client: OkHttpClient
fun getClient(): OkHttpClient = client
init {
// 设置代理
val proxyAddress = InetSocketAddress("127.0.0.1", 8080)
val proxy = Proxy(Proxy.Type.SOCKS, proxyAddress)
val logging = HttpLoggingInterceptor().apply {
HttpLoggingInterceptor.Level.BODY.also { this.level = it }
}
val headerInterceptor = Interceptor { chain ->
val originalRequest = chain.request()
val requestBuilder = originalRequest.newBuilder()
.header("Content-Type", "application/json")
val modifiedRequest = requestBuilder.build()
chain.proceed(modifiedRequest)
}
client = OkHttpClient.Builder()
.pingInterval(20, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.hostnameVerifier { _, _ -> true }
.addInterceptor(logging)
.connectionPool(ConnectionPool(0, 5, TimeUnit.SECONDS))
.cache(null)
.proxy(proxy)
.addInterceptor(headerInterceptor)
.build()
}
}
package com.wayl.proxy.test
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.lifecycleScope
import com.wayl.proxy.library.WaylProxy
import com.wayl.proxy.library.listener.ProxyStateChangeListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
class MainActivity : AppCompatActivity() {
companion object {
private const val TAG = "MainActivity"
}
private lateinit var drawerLayout: DrawerLayout
private val port: Int = 8080
private val requestURL: String = "https://google.com"
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
drawerLayout = findViewById(R.id.drawer_layout)
val close: Button = findViewById(R.id.close_btn)
val open: Button = findViewById(R.id.open_btn)
val clear: Button = findViewById(R.id.clear_btn)
val request: Button = findViewById(R.id.request_btn)
val init: Button = findViewById(R.id.init_btn)
WaylProxy.addStateChangeListener(object : ProxyStateChangeListener {
override fun onInitStatusChanged(newStatus: Boolean) {
Log.i(TAG, "初始化状态: $newStatus")
}
override fun onValidationStatusChanged(newStatus: Boolean) {
Log.i(TAG, "验证状态: $newStatus")
}
override fun onStartStatusChanged(newStatus: Boolean) {
Log.i(TAG, "启动状态: $newStatus")
}
})
init.setOnClickListener {
val result = WaylProxy.init(this)
Log.i(TAG, result.toString())
}
request.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
val request = Request.Builder()
.url(requestURL)
.get().build()
OkHttpRequestClient.getClient().newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
Log.e(TAG, "请求失败", e)
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
Log.i(TAG, "请求成功")
} else {
Log.e(TAG, "请求失败")
}
}
})
}
}
clear.setOnClickListener {
WaylProxy.clear()
}
close.setOnClickListener {
WaylProxy.stop()
}
open.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
val start = WaylProxy.start(this@MainActivity, port)
Log.i(TAG, start.toString())
}
}
Log.i(TAG, WaylProxy.getFreePort().toString())
val result = WaylProxy.init(this)
Log.i(TAG, result.toString())
}
}