Administrator
发布于 2025-03-07 / 1022 阅读

SDK安卓集成文档

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())
    }
}