【问题标题】:How to add additional handlings to Vpn disconnection in Android?如何在 Android 中为 Vpn 断开连接添加额外的处理?
【发布时间】:2013-03-08 22:24:02
【问题描述】:

我有一个 VpnService 的自定义实现,它需要在断开连接时执行一些额外的清理。当我使用服务绑定从我的应用程序中停止 VpnService 时,一切正常,但是当客户端使用系统对话框从 Vpn 断开连接时,我需要执行该清理。

那么,我怎样才能捕捉到断开连接并为此添加一些处理?

Get VPN Connection status on Android - 这可能是解决方案,但它不适用于 android 4+。

从日志的角度来看,只有两个条目:

03-20 03:27:09.478: INFO/Vpn(504): Switched from org.my.package to [Legacy VPN] 03-20 03:27:09.478: DEBUG/Vpn(504): setting state=IDLE, reason=prepare

【问题讨论】:

标签: android vpn


【解决方案1】:

我刚刚遇到了同样的问题。没有调用 VpnService.onRevoke()。

事实证明,这是因为我使用了一个通过 AIDL 定义的自定义 IBinder,我从 onBind() 返回。 VpnService 也实现了 onBind() 并返回 VpnService.Callback 的一个实例。 以这种方式实现的:

private class Callback extends Binder {
    @Override
    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
        if (code == IBinder.LAST_CALL_TRANSACTION) {
            onRevoke();
            return true;
        }
        return false;
    }
}

VpnService.Callback 不使用 AIDL,只检查函数代码 IBinder.LAST_CALL_TRANSACTION 是否已发送。如果是,则执行 onRevoke()。

我将此代码片段集成到我的自定义 IBinder 实现中,现在我收到了 onRevoke() 消息。请参阅以下示例:

private final IBinder mBinder = new ServiceBinder();    
@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}
public final class ServiceBinder extends ICustomVpnService.Stub
{
    ... implement methods defined in ICustomVpnService.Stub ....

    /**
     * Intercept remote method calls and check for "onRevoke" code which
     * is represented by IBinder.LAST_CALL_TRANSACTION. If onRevoke message
     * was received, call onRevoke() otherwise delegate to super implementation.
     */
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
    throws RemoteException
    {
        // see Implementation of android.net.VpnService.Callback.onTransact()
        if ( code == IBinder.LAST_CALL_TRANSACTION )
        {
            onRevoke();
            return true;
        }
        return super.onTransact( code, data, reply, flags );
    }

    private void onRevoke()
    {
        // shutdown VpnService, e.g. call VpnService.stopSelf()
    }
}

我是怎么知道的?我在 android 源代码中搜索了实际调用 onRevoke() 的位置。为此,我发现grepcode (android) 非常有帮助。我经常阅读 android 源代码以了解其工作原理。

【讨论】:

  • 干得好!不幸的是,Callback 是一个私有类。如果可以创建一个 Callback 实例并将 onTransact 调用委托给该实例,情况会更好。截至目前,我们依赖代码重复......
  • 谢谢,它拯救了我的一天
【解决方案2】:

事实证明,这是因为我使用了一个通过 AIDL 定义的自定义 IBinder,我从 onBind() 返回。 VpnService 也实现了 onBind() 并返回 VpnService.Callback 的一个实例。

是的,没错。所以,我认为这是另一种解决方法:

@Override
public IBinder onBind(Intent intent) {
    String action = null;
    if (intent != null) {
        action = intent.getAction();
    }

    if (VpnService.SERVICE_INTERFACE == action) {
        return super.onBind(intent);
    }

    return yourBinder;
}

【讨论】:

    猜你喜欢
    • 2015-11-06
    • 1970-01-01
    • 2015-05-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多