你说离线就离线,是不是真离线?

互联网时代,只有不联网的App才让人放心

讽刺

真离线的密码管理器——神锁离线版

我们推出产品后,不少用户询问,“我怎么知道是不是真的离线呢?”。

是的,我们就喜欢这样较真的用户😂

不较真

为了回答好这个问题,我们特意准备了这篇浅入深出硬核的科普文。

浅入篇 - 如何查看

App是不是真的完全离线,安卓平台其实比较简单,很多应用商店和手机上的应用管理工具都可以直接查看是否有联网权限。请认准这行字,

拥有完全的网络访问权限

上视频,国行iPhone查看联网权限

App第一次访问网络时,系统会提示是否允许联网

还可以在系统设置的App设置中,找到无线数据(WLAN与蜂窝网络),随时修改联网设置。

已经升级iOS 13的朋友请注意,由于iOS 13引入的bug,应用内购买时,神锁离线版也会弹出网络提示框,而且只有允许使用网络才能完成购买,在iOS 12上并没有这个问题。这个bug已经向苹果反馈,还没有收到苹果的回复。

Play商店查看联网权限

小米应用商店查看联网权限

OPPO软件商店查看联网权限

华为,vivo应用商店还不能查看联网权限详情。

无奈

小米应用管理查看联网权限

华为应用管理查看联网权限

三星应用管理查看联网权限

谷歌应用管理查看联网权限

深入篇 - 答疑

我的iPhone没有这个提示框?

此功能为国行版iPhone特供你的iPhone不是国行版吧?大兄弟!

真香

非国行iPhone能不能检测网络权限?

海外版iPhone在App使用网络时,不会弹出对话框。

使用蜂窝移动网络时,会记录流量。Wi-Fi不会提示,也没有记录。

港版iPhone蜂窝网络

港版iPhone蜂窝网络

那App能不能在非国行iPhone上检测到Wi-Fi时才联网,偷用户数据?

死磕到底

死磕!!!我们在硬核篇中解答。
    

为什么应用内购买可以不联网?

内购原理图

内购原理图

其实很简单,App内购通过商店的服务接口进行交易,网络部分由商店完成,完全关闭网络也无法完成内购。

在内购交易时,App仍然不能联网,也就无法偷偷把数据传到自己的服务器了。

iOS平台也类似,BillingClient对应的就是StoreKit,Play Store app对应的就是App Store。

硬核篇 - 程序员专属

App能否检查是海外版的iPhone,并且是Wi-Fi时才联网?

首先,iOS平台没有提供API获取iPhone的发行地区或者iOS的发行地区。程序可以查询当前手机系统设置的地区,但并不是iOS的发行地区。我们可以用港版的iPhone,在系统中把地区设置为中国大陆。

iPhone地区设置

地区

然后,App确实能够检测网络是不是Wi-Fi,示例代码如下,

      var monitor = NWPathMonitor()
          monitor.start(queue: DispatchQueue.main)
          monitor.pathUpdateHandler = { path in
          print("Using cellular? \(path.usesInterfaceType(.cellular))\n"+ "Using Wi-Fi? \(path.usesInterfaceType(.wifi))")
      }
    

但是,逃不过国行iPhone的法眼!

国行iPhone真神器!

完整的项目源代码 https://github.com/bluespace-labs/NetworkDetector

全球最大的同性交友平台

安卓没有联网权限,强行联网会怎样?

如果在 AndroidManifest.xml 里面没有加上联网权限,我们试试会怎样

      private fun loadImage() {
        Thread(Runnable {
          try {
            URL(url).openStream().use { input ->
              FileOutputStream(file).use { output -> input.copyTo(output) }
            }
            runOnUiThread { showImage() }
          } catch (ex: Throwable) {
              runOnUiThread {
                AlertDialog.Builder(this)
                  .setMessage(ex.toString())
                  .create()
                  .show()
            }
          }
        }).start()
      }

      private fun showImage() {
        try {
          BitmapFactory.decodeFile(file.absolutePath)?.let {
            imageView.setImageBitmap(it)
          }
        } catch (ex: Throwable) {
          ex.printStackTrace()
        }
      }
    

会抛出一个安全异常,操作系统会阻止App联网。

安全异常

只要在 AndroidManifest.xml 中加上这一行就不会有这个异常了,

<uses-permission android:name="android.permission.INTERNET" />
    

完整的项目源代码 https://github.com/bluespace-labs/AndroidTestNetwork

全球最大的同性交友平台

应用商店没有提供联网权限信息,手机应用管理也没有,怎么检查联网权限?

安卓平台的PackageManager提供了查询App信息的API,其中通过 PackageInfo.requestedPermissions 接口就可以查询到App的权限信息,包括互联网权限 android.permission.INTERNET

示例代码如下,

      private fun loadInternetPermission(packageName: String) {
        val permissions = packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS).requestedPermissions
        if (permissions?.contains(PermissionViewer.internet) == true) {
          allViews.getValue(packageName).appNameTextView.setTextColor(getColor(R.color.red))
        }
      }
    

App权限信息

完整的项目源代码 https://github.com/bluespace-labs/AppPermissionInfo
全球最大的同性交友平台

哪些才是真离线App?

在Play商店搜索“离线”,

没有一个是真的完全离线不联网的App 😅

这些离线App的意思是,不联网的时候也能用,能联网的时候还是要联的😂