3.3 Android SDK 常见问题 QA

优质
小牛编辑
129浏览
2023-12-01

1、连接不到VPN

表现: 连接不到VPN,日志输出为 connect vpn failed.连接服务器失败

解决: 1.查看IP和端口是否正确:是否有去空处理,打日志和加断点调试。 2.网络不通:在手机上打开浏览器,输入VPN的地址和端口,看一下能不能访问VPN服务端。如访问 https://vpnip:vpnport/ 。如果访问不到,说明你的手机或平板不能访问VPN服务器,你需要先确认4G或wifi能连通到VPN服务端。

2、认证时出现密码安全策略错误

注意:密码安全策略是针对VPN私有账号的,公有账号请忽略。 表现: 当提示“当前密码不符合以下密码策略”时,表示vpn服务端开启了密码安全策略,并且用户当前登录密码不符合其中的一些规则。 服务端密码策略配置:

客户端提示:

解决: 当用户密码不符合密码策略时,代码逻辑会走到onLoginProcess流程中,提示进行密码修改。将Demo中onLoginProcess相关代码复制到工程中。

3、登陆VPN成功后,却不能访问资源

参考开发前准备中的账号验证

4、VPN帐号的问题

公有、私有账号

公有账号:

多台设备可同时适用同一个账号。在线用户出现多个同名账户。

注意事项:公有账号容易出现授权占满的情况。

解决: 1.将VPN设备上,移动端的超时注销时间设置端一点。在SSL VPN设置---策略组管理-----默认策略组(选择用户所属的策略组)----账号控制--------移动端应用接入,设置超时注销时间。 2.app退出时,调用VPNlogout,等回调后再退出,通知服务端注销用户。

私有账号:

同一个时间,只能允许登陆一个账号。在线用户只会出现一个。 注意事项:容易出现一个账号,两个设备同时登陆,出现互踢现象。A设备登陆,B设备再登陆,B将A踢下线。A发现被下线之后,后台调用重连功能,自动登陆,又将B踢下线。B被踢后,又开启重连。造成A和B互踢。

解决:注销其中一台设备。私有账号不分享给其他人用。

本地和外部账号

一般情况下有两种结合方式:

  • 如果用户对认证要求不严格的话,也就是只是用VPN的SDK来保证传输安全。这样可以分配一个公有帐号,所有客户端都使用同一帐号,直接把帐号写死在程序里面就可以了。
  • 如果第一种方式不行,建议的方案采用外部账号:在VPN后台把VPN认证的帐号与业务系统的帐号配成一样。如没有使用VPN时,业务系统的使用的LDAP认证,则让VPN也允许LDAP认证。 在客户端,程序必须先通过VPN认证以后,再做业务系统的二次认证。不论哪一步认证失败,都给用户显示认证失败。最终用户看起来,就如同没有使用VPN帐号一样。

5、联通电信3G、4G网络问题

问题描述:

3G环境,EasyApp模块,认证正常,但是访问资源一直访问不上。日志上显示连接的资源地址为10.0.0.200\/10.0.0.172(电信代理服务器,联通不一样),这个地址本应该为资源地址。

原因:

不支持代理服务器连接VPN。 电信或者联通的wap网络会将连接转为运营商的代理服务器,导致连接使用了代理连接。

解决方法:

手机的运营商网络设置中,将wap网络改成net网络,这样手机就不会通过代理访问网络。

设置---更多---移动网络设置---接入点APN,wap和Net

6、L3VPN 环境检测

网络环境:

问题描述:

合入L3VPN sdk后用浏览器等访问内网资源有问题。

原因:

使用L3VPN必须满足一下三点:

  1. 确定手机Android 4.0以上
  2. 服务端pptp选项关闭   系统设置 ==》 SSLVPN选项 ==》 系统选项 ==》 接入选项下面 ==》 不启用pptp接入服务
  3. 配置的资源里面有L3VPN资源   以上三条满足之后登陆后,直接导航栏会有权限对话框,弹出,同意后导航栏有一个小钥匙的标识。

开发环境:

问题描述:

L3VPN启动失败。

原因:
  1. manifest文件中是否有注册 vpn-service服务
  2. manifest文件是否有注册timeqry服务
  3. 服务端虚拟ip资源是否充足
  4. 在部分Android4.4的手机上由于系统bug会导致vpn远端服务无响应,此时只能重启手机解决。。

7、L3VPN没有小钥匙

日志提示Device not support service

可能原因:
  1. VPN服务器没有配置L3VPN资源。解决:找管理VPN设备的负责人配置L3VPN资源。
  2. L3VPN弹得允许框,之前没有允许。因为L3需要建立虚拟网卡,系统会自动弹框,用户允许才可以开启L3服务。前一次弹框用户没有允许,系统记住该配置,下次便默认采用上次的选择。
  3. 在系统弹窗后没有通知sdk授权结果,导致sdk不再继续执行
  4. 部分手机开启应用白名单后会导致通知栏小钥匙显示不准确,此时不必惊慌,vpn网络可以正常使用。
解决:重启手机,再次弹框,选择允许。

8、Android 64位库问题

不支持64位库,但可以在64位机上运行32位库。
解决:
  1. 针对使用其他三方库的情况:将64位库中的so库移到armeabi文件夹中。删除libs下的64位文件夹。当手机是64位时,会在64位文件夹中查找库,如果不存在64位文件夹,就会到默认文件夹中去查找armeabi。但如果存在64位文件夹,却缺少库,会报错。

针对自己编译的库,编译时在Application.mk中去掉64位的编译选项。

9、Android 6.0问题

read_phone_state权限 Android6.0以上需要动态获取
解决:

参考demo中6.0权限申请代码。

10、reset by peer

问题:登陆VPN之后,访问内网地址时,访问不上。出现Connection reset by peer read data from SVPN or USER failed!:Connection reset by peer日志。
原因:

(1)VPN服务器端断开:私有账号同一个时间多设备登陆。登陆后VPN服务器会把前一个设备踢下线,而SDK设备后台又重连,导致两台设备互踢。伴有relogin关键字日志。

解决:

使用公有账号测试下。或者确保同一个私有账号同一时间只有一台SDK设备登陆。

原因:

(2)防火墙或者内网服务器断开:在VPN抓包,或者在VPN之后的其他网络设备上抓包分析。

解决:联系办事处客服配合抓包。或者联系4006306430转2总部客服抓包处理。

11、 公有账号超时注销

现象:使用公有账号,在线用户一直在增加,最终导致授权占满,无法登陆。 解决: 1.客户端退出时,使用vpnlogout,收到logout回调之后再退出。参照demo中的写法。 2.设置超时注销:SSL VPN设置---策略组管理---默认策略组(用户所在策略组)-----账号控制------常规接入和移动端接入均设置超时时间。

备注:以前版本的SDK会以“常规接入”的超时注销为准,但当前版本SDK已经使用“移动应用接入”超时注销。

12、 认为vpn网络不稳定,经常断线

此时可以使用普通http请求访问百度以及我们vpn的登录地址,若是可以正常访问,可以检查一下当前vpn的状态是否为离线,若是离线,需要重新登录vpn,若是处于并一直处于重连中,则可以通知用户换用我们其他产品如aWork或者EC进行登录,以排除中间网络的影响。

对于经常出问题的用户,也可以下载 miniConnect,当vpn出现问题时,使用其自带的诊断功能诊断网络状态。

特别强调,不要直接监听tun0网卡的状态,因为即便tun0网卡在启用,外部网络不通或者vpn的网络服务被系统阻断,也是不能正常使用vpn的,我们会有一个vpn状态回调,会通知app vpn外部网络通道的状态,应该以此为准。再者,一些情况下,手机内的虚拟网卡名字可能是tun1,tun2等。

13、 关于多应用共用l3vpn

由于系统限制,L3VPN同时只能存在一个,这就造成了互相推挤的问题。为此,我们提供两种方案供使用,这两种方案各有优缺点,我们也在考虑采取哪一种。

  1. 发包检测vpn是否存在

    我们提供了一个接口 detectTunnel 来检测当前的vpn,该接口传入一个vpn地址,并构造数据包发给虚拟网卡,根据虚拟网卡回复数据包判断当前登录的vpn是否和目标vpn一致。 所有应用注册一个接口 com.sangfor.ssl.common.Foreground,当app从后台进入前台时会收到这个接口的回调,在回调中判断vpn是否还在。 可以使用这个接口检测当前有没有vpn在线,有没有必要启用vpn。

    • 优点:原生支持,只需要调用接口即可
    • 缺点:在开启vpn的应用被系统杀死后,无法通知其他应用去启动l3vpn。
  2. 使用文件锁抢占建立vpn

    创建文件锁,所有要拉起vpn的应用都去获取此文件锁。获得锁的应用负责拉起vpn,当注销时,释放该锁,以供其他应用拉起vpn。没有获得文件锁的应用起异步任务阻塞式获取锁,直到成功加锁。

    • 优点:可以及时通知到vpn的断开消息
    • 缺点:需要用户自己实现

14、 关于数据安全

  • 在开启l3vpn时,可以添加应用白名单,这样可以只针对部分可信应用开启vpn。此功能需要Android5.0及以上系统才支持。
  • 强烈阻止将vpn账户内置到app的行为

15、 关于日志

sdk的日志存在 /sdcard/sangfor/sdklog/[包名] 文件夹下。其中 process 文件夹存放的是运行时日志,*-2.log 文件是备份文件,另一个是当前的日志文件,文件只保留两份,多余的将自动删除。 crash目录保存的是捕获到的崩溃日志,这里的崩溃不一定是sdk造成的。

目前不能指定日志提交服务器,但是提供了一个接口packLogs打包日志,包括 sdk运行日志、崩溃日志、设备信息、当前程序的logcat日志。

16、 关于保活

sdk本身没有保活机制,需要app引导用户去设置保活。sdk也可以申请一些权限来实现不被系统限制网络。

  1. 可以开启前台服务,此前台服务显示一个通知栏通知,既可以显示vpn状态,也可以一定程度上做到保活。
  2. 可以申请系统的悬浮窗权限,开启一个悬浮窗指示vpn状态,在一些手机上如华为,悬浮窗应用的优先级等同于前台应用。

我们观察到一些常见机型都对后台应用有限制,可以在设置中手动配置,这里提供一些参考:

    private static Intent getSettingIntent(@NonNull Context context) {
        String brand = Build.BRAND.toLowerCase();
        ArrayList<ComponentName> componentNames = new ArrayList<>();
        switch(brand){
            case "samsung":
                componentNames.add(new ComponentName("com.samsung.android.sm",/* 无法跳转 */
                        "com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity"));
                break;
            case "meizu":
                componentNames.add(new ComponentName("com.meizu.safe",
                        "com.meizu.safe.permission.SmartBGActivity"));
                break;
            case "vivo":
                componentNames.add(new ComponentName("com.iqoo.secure", /* 无法跳转 */
                        "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity"));
                break;
            case "oppo":
                componentNames.add(new ComponentName("com.coloros.oppoguardelf",
                        "com.coloros.powermanager.fuelgaue.PowerUsageModelActivity"));
                break;
            case "360":
                componentNames.add(new ComponentName("com.yulong.android.coolsafe",
                        "com.yulong.android.coolsafe.ui.activity.autorun.AutoRunListActivity"));
                break;
            case "xiaomi":
                componentNames.add(new ComponentName("com.miui.securitycenter", /* 可用 */
                        "com.miui.permcenter.autostart.AutoStartManagementActivity"));
                break;
            case "huawei":
                componentNames.add(new ComponentName("com.huawei.systemmanager",/* 可用 */
                        "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity"));
                break;
            case "oneplus":
                componentNames.add(new ComponentName("com.oneplus.security",
                        "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity"));
                break;
            default:
        }
        if(componentNames.size()==0){
            return new Intent(Settings.ACTION_SETTINGS);
        }
        for (ComponentName componentName : componentNames ) {
            Intent intent = new Intent();
            intent.setComponent(componentName);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY)!=null) {
                return intent;
            }
        }
       return new Intent(Settings.ACTION_SETTINGS);
    }

还有一些其他的设置,需要针对不同的机型去摸索