Can't find variable: device

9.2k Views Asked by At

I'm stuck in this phonegap project. Everything works perfect on Android and iOS <= 7 but fails on iOS >= 8.0. A popup-window appears with the message: "Can't find variable: device"

enter image description here

This is the message i get:

This is my HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="msapplication-tap-highlight" content="no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, target-densitydpi=device-dpi" />
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <title>Hello World</title>
        <script type="text/javascript" src="cordova.js" charset="utf-8"></script>
        <script type="text/javascript" src="js/PushNotification.js" charset="utf-8"></script>
    </head>
    <body onload="documentReady();">
        <div class="app">
            <h1>Apache Cordova</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
            </div>
        </div>
        <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

And this is my 'index.js' as loaded in the bottom of the tag.

var myPushNotification;

// result contains any message sent from the plugin call
function successHandler (result) {
    alert('result = ' + result);
}
// result contains any error description text returned from the plugin call
function errorHandler (error) {
    alert('error = ' + error);
}

var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicitly call 'app.receivedEvent(...);'
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        try
        {
  if(window.plugins && window.plugins.pushNotification){
              myPushNotification = window.plugins.pushNotification;
  }else{
   window.plugins = {};
   window.plugins.pushNotification = new PushNotification();
  }
        
            if(typeof window.device === 'undefined' || typeof device === 'undefined'){
                alert('Device plugin not found');
            }else{

                //Android register
                if (device.platform == 'android' || device.platform == 'Android' || device.platform == "amazon-fireos" ){
                    myPushNotification.register(
                    successHandler,
                    errorHandler,
                    {
                        "senderID":"1010852256891",
                        "ecb":"onNotification"
                    });

                //Blackberry
                }else if(device.platform == 'blackberry10'){
                    myPushNotification.register(
                    successHandler,
                    errorHandler,
                    {
                        invokeTargetId : "replace_with_invoke_target_id",
                        appId: "replace_with_app_id",
                        ppgUrl:"replace_with_ppg_url", //remove for BES pushes
                        ecb: "pushNotificationHandler",
                        simChangeCallback: replace_with_simChange_callback,
                        pushTransportReadyCallback: replace_with_pushTransportReady_callback,
                        launchApplicationOnPush: true
                    });

                //iPhone - iPad
                }else{
                    myPushNotification.register(
                    tokenHandler,
                    errorHandler,
                    {
                        "badge":"true",
                        "sound":"true",
                        "alert":"true",
                        "ecb":"onNotificationAPN"
                    });
                }

            }//End device plugin check.
            
        }catch(e){
            alert("Plugin of PushNotify niet beschikbaar\n" + e.message);
        }
    }
};

// Android and Amazon Fire OS onNotification
function onNotification(e) {

    switch( e.event )
    {
        case 'registered':
            if ( e.regid.length > 0 )
            {
                //Register our device
                $.post('http://www.my_webaddress.com/action/device',
                {
                    device:e.regid
                }
                ,function(res){
                    alert(res);
                });
                // Your GCM push server needs to know the regID before it can push to this device
                // here is where you might want to send it the regID for later use.
                //console.log("regID = " + e.regid);
            }
        break;

        case 'message':
            // if this flag is set, this notification happened while we were in the foreground.
            // you might want to play a sound to get the user's attention, throw up a dialog, etc.
            if ( e.foreground )
            {
                alert('<li>--INLINE NOTIFICATION--' + '</li>');

                // on Android soundname is outside the payload.
                // On Amazon FireOS all custom attributes are contained within payload
                var soundfile = e.soundname || e.payload.sound;
                // if the notification contains a soundname, play it.
                var my_media = new Media("/android_asset/www/"+ soundfile);
                my_media.play();
            }
            else
            {  // otherwise we were launched because the user touched a notification in the notification tray.
                if ( e.coldstart )
                {
                    alert('<li>--COLDSTART NOTIFICATION--' + '</li>');
                }
                else
                {
                    alert('<li>--BACKGROUND NOTIFICATION--' + '</li>');
                }
            }

           alert('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
               //Only works for GCM
           alert('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
           //Only works on Amazon Fire OS
           alert('<li>MESSAGE -> TIME: ' + e.payload.timeStamp + '</li>');
        break;

        case 'error':
            alert('<li>ERROR -> MSG:' + e.msg + '</li>');
        break;

        default:
            alert('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
        break;
  }
}

// iOS
function onNotificationAPN (event) {

    if ( event.alert )
    {
        navigator.notification.alert(event.alert);
    }

    if ( event.sound )
    {
        var snd = new Media(event.sound);
        snd.play();
    }

    if ( event.badge )
    {
        myPushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);
    }
}

// BlackBerry10
function pushNotificationHandler(pushpayload) {
    var contentType = pushpayload.headers["Content-Type"],
        id = pushpayload.id,
        data = pushpayload.data;//blob

    // If an acknowledgement of the push is required (that is, the push was sent as a confirmed push
    // - which is equivalent terminology to the push being sent with application level reliability),
    // then you must either accept the push or reject the push
    if (pushpayload.isAcknowledgeRequired) {
        // In our sample, we always accept the push, but situations might arise where an application
        // might want to reject the push (for example, after looking at the headers that came with the push
        // or the data of the push, we might decide that the push received did not match what we expected
        // and so we might want to reject it)
        pushpayload.acknowledge(true);
    }
}

function tokenHandler(result){
    // Your iOS push server needs to know the token before it can push to this device
    // here is where you might want to send it the token for later use.
    
    //alert('device token = ' + result);
    $.post('http://www.my_webaddress.com/action/device',
    {
        device:result
    }, function(res){
        alert(res);
    });
}

//When HTML document is finished loading. Jquery should be available
function documentReady(){
    $(function(){
        alert('Jquery loaded');        
    });
}

app.initialize();

This is my config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="0.0.5" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>HelloCordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="[email protected]" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <access origin="*" />
    <plugin name="Device" value="org.apache.cordova.Device" />
    <feature name="Device">
        <param name="android-package" value="org.apache.cordova.device.Device" />
    </feature>    
<feature name="Device">
 <param name="ios-package" value="CDVDevice" />
</feature>
<feature name="PushPlugin">
    <param name="ios-package" value="com.phonegap.plugins.PushPlugin" />
</feature>
 <preference name="BackupWebStorage" value="local" />    
</widget>

2

There are 2 best solutions below

1
On BEST ANSWER

Yeah i tried that ofc diddn't work. I found out that the problem lies in the fact that you need to compile the plugin for ios before you can use it. And that is simply not possible on Windows machines. Something (Windows users) needs to think about.

1
On

you need to install device cordova plugin first.

https://github.com/apache/cordova-plugin-device

command

cordova plugin add https://github.com/apache/cordova-plugin-device