Ionic:使用Cordova检查互联网连接

9
我正在使用Ionic框架,遇到了在Android应用中使用Apache Cordova Network API检测网络连接的问题。 我参考了this教程,并创建了一个演示项目,它可以正常工作。
我按照以下步骤进行操作。[来自教程]
  1. ionic start testApp sidemenu

  2. ionic platform add android

  3. Open testApp/www/js/app.js

  4. Copy paste this code

    if(window.Connection) {
    
      if(navigator.connection.type == Connection.NONE) {
          alert('There is no internet connection available');
      }else{
          alert(navigator.connection.type);
      }
    }else{
          alert('Cannot find Window.Connection');
    }
    
  5. Install Cordova Plugin cordova plugin add org.apache.cordova.network-information

  6. Build ionic build android

  7. Run ionic run android

这个运行良好

问题

  1. mainproject中的www复制并粘贴到testApp,然后执行步骤6和7

我收到了一个警告:无法找到Window.Connection

复制粘贴app.js之后,它看起来像这样

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }
    // check internet connection
    //alert(window.Connection);
    alert('Hi')
    try {
       alert('Naviagtor says'+navigator.connection.type);
     }
    catch(err) {
       alert( 'Error '+ err.message) 
       //here i get 'Error cannot read property type of undefined'
     }

if(window.Connection) {
    if(navigator.connection.type == Connection.NONE) {
        alert('There is no internet connection available');
    }else{
        alert(navigator.connection.type);
    }
}else{
    alert('Cannot find Window.Connection');
}

  });
})

当我将我的app.jscontrollers.js复制粘贴到testApp/www/js目录中时,整个东西都崩溃了。
非常感谢任何关于调试的帮助。
谢谢,
注意:
我在index.html中有cordova.js
在复制粘贴后,我已重新安装了platformsplugins

你尝试在检查window.Connection之前打印navigator.connection.type了吗?它显示什么? - trainoasis
谢谢回复,我已经更新了上面的代码。正如你所说,我尝试打印 navigator.connection.type 但是看起来这个对象是未定义的。 - Incpetor
运行 cordova plugins ls 命令,查看是否列出了 SMS 插件。如果没有列出,请移除 platforms android/ios 并重新添加它们。 - divyenduz
请确保主项目的www文件夹中包含插件文件夹,以及您安装的插件。 - Mohammed Imran N
www文件夹中不包含插件文件夹。它在mainproject文件夹之外。 - Incpetor
5个回答

21

我通过使用ngcordova解决了类似的问题。它为插件提供了一个angular包装器,实现了promises。

通常,在尝试调用它们时,Cordova插件还没有准备好,使用promise接口可以避免获取undefined错误。

我从这里 ngcordova页面上的网络插件示例中借鉴了一些内容。

module.controller('MyCtrl', function($scope, $rootScope, $cordovaNetwork) {

 document.addEventListener("deviceready", function () {

    var type = $cordovaNetwork.getNetwork()

    var isOnline = $cordovaNetwork.isOnline()

    var isOffline = $cordovaNetwork.isOffline()


    // listen for Online event
    $rootScope.$on('networkOffline', function(event, networkState){
      var onlineState = networkState;
    })

    // listen for Offline event
    $rootScope.$on('networkOffline', function(event, networkState){
      var offlineState = networkState;
    })

  }, false);
});

嗨,感谢回复。$cordovaNetwork.getNetwork() 返回 0 而不是 Connection.NONE,而 $cordova.isOnline() 则出错。我仍然卡在这个问题上。 - Incpetor
你是否仔细遵循了安装说明并在设备或AVD上运行它?我个人使用了一个测试调用来检查是否连接到服务器。因为有WiFi并不意味着有互联网访问。也许编写一个调用服务器并处理返回结果的代码,以检查是否连接成功。 - Armed10
请使用 $rootScope.$on('$cordovaNetwork:offline'$rootScope.$on('$cordovaNetwork:online' 替代您的监听器。 - ADyDyka

6
对于那些初次访问并且在尝试使用Armed10的答案时遇到问题的人,您可能想查看我编写的帖子,该帖子字字珠玑地一步一步告诉您应该放置某段代码的位置和原因(如果您刚开始使用Ionic,这可能会有所帮助):http://www.nikola-breznjak.com/blog/codeproject/check-network-information-change-with-ionic-famework/
此外,我已经在Github上免费提供了示例代码:https://github.com/Hitman666/IonicNetworkInfo编辑:根据StackOverflow的规定,我也在这里添加了文章内容:
一步一步教您如何自己做:
通过以下方式启动新的Ionic项目:
ionic start IonicNetworkInfo blank

接下来,将目录切换到新创建的IonicNetworkInfo目录:

cd IonicNetworkInfo

使用Bower安装ngCordova:

bower install ngCordova

如果您没有安装bower,可以使用npm进行安装:

npm install bower -g

在您喜欢的编辑器中打开www/index.html文件,并添加对ngCordova的引用(就在cordova.js脚本上方):
<!-- This is what you should add, the cordova below you'll already have -->
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>

<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>

在终端/命令提示符中执行以下命令安装ngCordova网络插件(您应该从应用程序的根目录执行此操作;因此,在我们的情况下是IonicNetworkInfo目录):
cordova plugin add org.apache.cordova.network-information

要检查插件是否成功安装,您可以运行以下命令(从根目录运行 - 我不会再重复了;当我说您应该从终端/命令提示符运行某个命令时,这意味着从应用程序的根目录运行):

cordova plugin list

您应该看到以下输出:
> cordova plugin list                                                                                                                           
com.ionic.keyboard 1.0.4 "Keyboard"
org.apache.cordova.network-information 0.2.15 "Network Information"

打开www/js/app.js文件,将ngCordova添加到依赖项列表中,这样基本上第一行看起来像这样:
angular.module('starter', ['ionic', 'ngCordova'])

在www/js/app.js文件中创建一个名为MyCtrl的新控制器,内容如下:
.controller('MyCtrl', function($scope, $cordovaNetwork, $rootScope) {
    document.addEventListener("deviceready", function () {

        $scope.network = $cordovaNetwork.getNetwork();
        $scope.isOnline = $cordovaNetwork.isOnline();
        $scope.$apply();

        // listen for Online event
        $rootScope.$on('$cordovaNetwork:online', function(event, networkState){
            $scope.isOnline = true;
            $scope.network = $cordovaNetwork.getNetwork();

            $scope.$apply();
        })

        // listen for Offline event
        $rootScope.$on('$cordovaNetwork:offline', function(event, networkState){
            console.log("got offline");
            $scope.isOnline = false;
            $scope.network = $cordovaNetwork.getNetwork();

            $scope.$apply();
        })

  }, false);
})

在这个控制器中,你会在deviceready事件上附加一个事件监听器(因为在代码运行时设备可能尚未初始化),并通过以下方式获取网络信息:
$cordovaNetwork.getNetwork();

以下是检查您是否连接到互联网的代码:

$scope.isOnline = $cordovaNetwork.isOnline();

然后,你需要注册两个事件 $cordovaNetwork:online 和 $cordovaNetwork:offline,它们会在设备上线/离线时触发。在这些事件中,你只需要更新 $scope 变量 ()。 仅供参考,www/js/app.js 文件的整个内容应该是:

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('starter', ['ionic', 'ngCordova'])

.run(function($ionicPlatform, $cordovaNetwork, $rootScope) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }

  });
})

.controller('MyCtrl', function($scope, $cordovaNetwork, $rootScope) {
    document.addEventListener("deviceready", function () {

        $scope.network = $cordovaNetwork.getNetwork();
        $scope.isOnline = $cordovaNetwork.isOnline();
        $scope.$apply();

        // listen for Online event
        $rootScope.$on('$cordovaNetwork:online', function(event, networkState){
            $scope.isOnline = true;
            $scope.network = $cordovaNetwork.getNetwork();

            $scope.$apply();
        })

        // listen for Offline event
        $rootScope.$on('$cordovaNetwork:offline', function(event, networkState){
            console.log("got offline");
            $scope.isOnline = false;
            $scope.network = $cordovaNetwork.getNetwork();

            $scope.$apply();
        })

  }, false);
});

在index.html文件中,在ion-content标签内粘贴以下内容:
<div class="card">
    <div class="item item-text-wrap">
        <h1>Network: {{network}}</h1>
    </div>
</div>


<div class="card">
    <div class="item item-text-wrap">
        <ion-toggle ng-model="isOnline" ng-checked="item.checked">
            <h1 ng-show="isOnline">I'm online</h1>
            <h1 ng-show="! isOnline">I'm offline</h1>
        </ion-toggle>
    </div>
</div>

我们在这里做的基本上是展示网络变量的内容(该变量通过控制器与 $scope 相关联)。此外,通过使用 ion-toggle 组件,我们展示“我在线”/“我离线”的通知。

仅供参考,整个 index.html 文件的内容应如下所示:

    <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
    <link href="css/ionic.app.css" rel="stylesheet">
    -->

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>
</head>
<body ng-app="starter" ng-controller="MyCtrl">

    <ion-pane>
        <ion-header-bar class="bar-stable">
            <h1 class="title">Ionic Blank Starter</h1>
        </ion-header-bar>

        <ion-content padding="true">
            <div class="card">
                <div class="item item-text-wrap">
                    <h1>Network: {{network}}</h1>
                </div>
            </div>

            <div class="card">
                <div class="item item-text-wrap">
                    <ion-toggle ng-model="isOnline" ng-checked="item.checked">
                        <h1 ng-show="isOnline">I'm online</h1>
                        <h1 ng-show="! isOnline">I'm offline</h1>
                    </ion-toggle>
                </div>
            </div>

        </ion-content>
    </ion-pane>
</body>
</html>

为了测试此应用程序,您应该在设备上运行它(因为您无法在iOS模拟器中禁用网络)。如果您将Android设备插入计算机并安装所有必要的SDK,您可以运行以下命令以在Android设备上运行应用程序:

ionic build android && ionic run android

@kleopatra:感谢提醒。不过,基本上把我在这里发布的帖子全部内容也贴在这里是“允许”的吗?我的意思是,我没有问题,只是想问一下 - 如果可以的话,谢谢,我会尽快更新。 - Nikola
嗨@Nikola,我遇到了同样的问题,但我的代码结构有点不同。只是想问一下你如何将其实现为服务/工厂。我在这里包含了关于我的特定问题的更多细节:http://stackoverflow.com/questions/40123495/checking-network-status-on-ionic-application。简而言之,我想为我的应用程序创建一个实时连接状态监视器,但除了setinerval(如此处所示:http://stackoverflow.com/a/40201808)之外,我真的不知道该怎么做。请帮帮我! - methuselah

2

只需在您的app.js中使用此代码,放在.run内部即可。

if (window.Connection) {
       if (navigator.connection.type == Connection.NONE) {
         toast.show("Internet is disconnected on your device");
       };
     };

1
如果您最近更新了 (运行 cordova 5.0),我猜测您需要安装 cordova-plugin-whitelist。安装后,请将以下内容添加到 config.xml 中以允许所有 http/s 请求:
allow-intent href="http://\*/\*"

allow-intent href="https://\*/\*"

Shell:

ionic plugin add https://github.com/apache/cordova-plugin-whitelist.git

Config.xml:

<allow-navigation href="*" />

1
在调用“connection”之前,您需要检查设备:
document.addEventListener("deviceready", function () {
    ...
});

你会如何在工厂/服务中实现这个? - methuselah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接