Статьи

PhoneGap с нуля: API устройства

Хотите узнать, как использовать PhoneGap, но не знаете, с чего начать? Присоединяйтесь к нам, чтобы мы собрали «Sculder», не только дань отличного фантастического телесериала, но и полноценное мобильное приложение для верующих в вас!

В первой части мы рассмотрели настройку среды разработки и настройку PhoneGap на iOS и Android SDK. Во второй части нашей серии PhoneGap мы рассмотрим некоторые API-интерфейсы устройств, к которым PhoneGap предоставляет нам доступ, и обсудим, как мы можем их использовать.


В этой части серии мы просто рассмотрим некоторые функции PhoneGap, поэтому сейчас мы просто настроим тест.

Идите вперед и настройте свой проект в любой среде, которую вы выбрали: Xcode для iOS или Eclipse для Android. Я укажу любые различия между этими двумя, поскольку мы продвигаемся, если это становится необходимым.

Мы начнем с базового HTML и включим файл Phongap.js. Если вы создали свой проект с XCode, это в значительной степени основной HTML, который создается.

01
02
03
04
05
06
07
08
09
10
11
12
<!DOCTYPE html>
<html>
  <head>
    <title>Acceleration</title>
 
    <script type=»text/javascript» charset=»utf-8″ src=»PhoneGap.js»></script>
 
  </head>
  <body>
     
  </body>
</html>

На протяжении этой части серии мы хотим иметь возможность проводить тестирование по крайней мере на одном реальном устройстве, поскольку симулятор имеет ограничения, когда речь идет о датчиках устройства, таких как акселерометр и камера. Чтобы устройство iOS заработало и работало в качестве тестового устройства, вам необходимо иметь платную учетную запись разработчика, а затем, когда вы подключаете свое устройство к компьютеру и запускаете Xcode, у вас есть возможность сделать этот телефон телефоном для разработки. Перейдите к настройке, и теперь, когда вы решите создать и запустить свое приложение, вы можете выбрать свое устройство из выпадающего меню.

Для Android это почти то же самое, за исключением того, что вы делаете это в Eclipse. Подключите телефон и убедитесь, что он у вас в режиме отладки VIA USB (в настройках телефона), а затем, когда вы хотите запустить свое приложение, выберите «Запуск от имени приложения Android».

Давайте посмотрим на некоторые основы устройства датчика.


Акселерометр обеспечивает обратную связь для движения устройств по всем трем осям. У нас есть несколько методов для акселерометра в PhoneGap: getCurrentAcceleration , watchAcceleration и clearWatch

Есть также некоторые аргументы, которые нужно передать в методе акселерометра. accelerometerSuccess , accelerometerError и accelerometerOptions .

Мы используем наш первый метод accelerometer.getCurrentAcceleration следующим образом.

1
navigator.accelerometer.getCurrentAcceleration(accelerometerSuccess, accelerometerError);

Текущее ускорение возвращается с помощью функции accelerometerSuccess, и все данные, которые нам нужны, находятся в объекте acceleration который мы возвращаем в нашу функцию успеха. Позволяет получить пример и работает. Возьмите наш основной макет, который мы создали в начале этой части, и давайте добавим к нему.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html>
  <head>
    <title>Acceleration</title>
 
    <script type=»text/javascript» charset=»utf-8″ src=»PhoneGap.js»></script>
    <script>
        //first we want to wait for PhoneGap to load
        document.addEventListener(«deviceready», loaded, false)
        //PhoneGap is loaded
        function loaded(){
            navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);
        }
 
        //Get the current Acceleration data if Successful
        function onSuccess(acceleration){
            alert(‘Acceleration X: ‘ + acceleration.x + ‘\n’ +
              ‘Acceleration Y: ‘ + acceleration.y + ‘\n’ +
              ‘Acceleration Z: ‘ + acceleration.z + ‘\n’ +
              ‘Timestamp: ‘ + acceleration.timestamp + ‘\n’);
        }
 
        // alert if there is an error
        function onError(){
            alert(«Error»);
        }
 
    </script>
 
  </head>
  <body>
     
  </body>
</html>

Когда вы запускаете это в симуляторе или устройстве, вы получите одно предупреждение о нагрузке. Что нам нужно сделать, это наблюдать за ускорением через определенные промежутки времени, а затем выводить данные. Мы можем сделать это с watchAcceleration метода watchAcceleration . Мы используем его со следующим:

1
var watchID = navigator.accelerometer.watchAcceleration(Success, Error, [Options]);

watchID — это ссылка, к которой мы можем прикрепить наши параметры, а также способ, который мы можем использовать при использовании метода clearWatch .

Давайте продолжим и заменим наш старый JavaScript следующим:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//wait for PhoneGap to load
document.addEventListener(«deviceready», loaded, false);
 
// PhoneGap is ready
function loaded() {
    startWatch();
}
 
// Start watching the acceleration
 
function startWatch() {
 
    // Update acceleration every 3 seconds
    var options = { frequency: 3000 };
 
    watchID = navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
}
 
// Stop watching the acceleration
function stopWatch() {
    if (watchID) {
        navigator.accelerometer.clearWatch(watchID);
        watchID = null;
    }
}
 
// Success
function onSuccess(acceleration) {
    var element = document.getElementById(‘accelerometer’);
    element.innerHTML = ‘Acceleration X: ‘ + acceleration.x + ‘<br />’ +
                        ‘Acceleration Y: ‘ + acceleration.y + ‘<br />’ +
                        ‘Acceleration Z: ‘ + acceleration.z + ‘<br />’ +
                        ‘Timestamp: ‘ + acceleration.timestamp + ‘<br />’;
}
 
 // Error
function onError() {
    alert(‘onError!’);
}

Как видите, мы передаем опцию frequency в метод watch. Это в миллисекундах, поэтому каждые 3 секунды этот метод будет запускаться снова, и в случае успеха мы будем обновлять HTML-код элемента с помощью идентификатора accelerometer . Нам просто нужно включить этот элемент в наш текущий HTML.

1
2
3
<body>
    <div id=»accelerometer»>Waiting for accelerometer…</div>
</body>

Теперь, если вы загрузите приложение, вы увидите изменение данных акселерометра.

PhoneGap с нуля

Если вы используете симуляторы, а не реальные устройства, вы не увидите каких-либо изменений на выходе акселерометра.

Вот и все, что нужно для доступа к API устройства акселерометра. Теперь давайте посмотрим, как использовать его для обнаружения дрожания в PhoneGap.

Чтобы обнаружить сотрясение с помощью PhoneGap, мы собираемся избавиться от нашей функции onSuccess и переписать нашу функцию startWatch . Чтобы узнать, было ли устройство потрясено, нам нужно узнать, какая была предыдущая ориентация, чтобы сравнить ее с текущей ориентацией. Мы делаем это, устанавливая переменную в начале функции startWatch .

1
2
3
4
5
var previousReading = {
    x: null,
    y: null,
    z: null
}

Далее мы запускаем функцию watchAcceleration.

1
navigator.accelerometer.watchAcceleration();

При успешном получении ускорения мы установим пару переменных, которые помогут нам обнаружить дрожание.

1
2
var changes = {},
bound = 0.2;

Теперь мы можем сравнить предыдущее ускорение с текущим ускорением, и если оно выходит за пределы того, что мы также установили для нашей bound переменной, то мы можем запустить нашу потрясенную функцию.

1
2
3
4
5
6
7
8
9
if (previousReading.x !== null) {
    changes.x = Math.abs(previousReading.x, acceleration.x);
    changes.y = Math.abs(previousReading.y, acceleration.y);
    changes.z = Math.abs(previousReading.z, acceleration.z);
}
 
if (changes.x > bound && changes.y > bound && changes.z > bound) {
    shaken();
}

Затем мы можем установить предыдущее значение на текущее значение для следующего раунда.

1
2
3
4
5
previousReading = {
 x: acceleration.x,
 y: acceleration.y,
 z: acceleration.z
}

Наконец, давайте не забудем написать «встряхиваемую» функцию, которая фактически обрабатывает встряску. На данный момент он просто предупредит сообщение.

1
2
3
function shaken(){
    alert(«Shaken»);
}

Вы должны будете не забыть добавить свой обработчик ошибок и частоту в конец метода watchAcceleration .

Ваш окончательный код теперь должен выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!DOCTYPE html>
<html>
    <head>
        <title>Acceleration</title>
         
        <script type=»text/javascript» charset=»utf-8″ src=»PhoneGap.js»></script>
        <script type=»text/javascript» charset=»utf-8″>
             
            // The watch id references the current `watchAcceleration`
            var watchID = null;
             
            //wait for PhoneGap to load
            document.addEventListener(«deviceready», loaded, false);
             
            // PhoneGap is ready
            function loaded() {
                startWatch();
            }
             
            // Start watching the acceleration
             
            function startWatch() {
                 
                var previousReading = {
                    x: null,
                    y: null,
                    z: null
                }
                 
                navigator.accelerometer.watchAcceleration(function (acceleration) {
                  var changes = {},
                  bound = 0.2;
                  if (previousReading.x !== null) {
                      changes.x = Math.abs(previousReading.x, acceleration.x);
                      changes.y = Math.abs(previousReading.y, acceleration.y);
                      changes.z = Math.abs(previousReading.z, acceleration.z);
                  }
                   
                  if (changes.x > bound && changes.y > bound && changes.z > bound) {
                    shaken();
                  }
                   
                  previousReading = {
                  x: reading.x,
                  y: reading.y,
                  z: reading.z
                  }
                   
                  }, onError, { frequency: 2000 });
            }
             
            function shaken(){
                alert(«Shaken»);
            }
             
            // Error
            function onError() {
                alert(‘onError!’);
            }
             
            </script>
    </head>
    <body>
    </body>
</html>

Я обнаружил, что предел 0.2 был довольно хорошим, но вы можете попробовать увеличить его после тестирования. Теперь мы рассмотрели, что может быть достигнуто с помощью данных акселерометра и как их получить, поэтому давайте посмотрим на камеру.


Камера, вероятно, является одной из наиболее часто используемых функций на смартфонах сегодня, особенно с разрешением камеры на большинстве телефонов, быстро догоняющим к более стандартным версиям «наведи и снимай». К счастью, PhoneGap предоставляет нам довольно простой способ захвата изображений с камеры устройства и быстрого включения этих изображений в наше приложение.

Метод, который мы собираемся использовать, — camera.getPicture() и точно так же, как акселерометр, он camera.getPicture() почти так же и принимает три параметра. Сигнатуры метода выглядят примерно так: navigator.camera.getPicture( cameraSuccess, cameraError, [ cameraOptions ] ) . Как вы увидите, при работе с камерой устройства нужно учитывать гораздо больше параметров, чем при работе с акселерометром.

Необязательные параметры, через которые вы можете пройти:

  • quality
  • destinationType
  • sourceType
  • allowEdit
  • encodingType
  • targetWidth
  • targetHeight

Как вы уже могли догадаться, quality — это качество, при котором изображение сохраняется, оно принимает число от 0 до 100. Переменная destinationType — это формат возвращаемого изображения. DATA_URL — это строка в кодировке base64, а FILE_URI — фактический URI изображения (jpeg / png). Параметр sourceType — это место, где вы хотите получить исходное изображение, которое может быть из PHOTOLIBRARY , CAMERA или SAVEDPHOTOALBUM . Опция allowEdit позволяет редактировать изображение перед его сохранением. EncodingType определяет кодировку возвращаемого изображения при использовании FILE_URI , из которого вы можете использовать JPEG или PNG . targetWidth и targetHeight — это то, к чему будет масштабироваться изображение с сохранением соотношения сторон. Наконец, есть MediaType который работает только при выборе SAVEDPHOTOALBUM и где вы можете определить, что пользователь может выбрать из PICTURE , VIDEO или ALLMEDIA .

Итак, давайте начнем нашу камеру. Сначала у нас будет кнопка, которая при нажатии запускает нашу камеру. Затем, когда фотография будет сделана, мы вернем изображение base64, закодированное в виде эскиза. Исходный код выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html>
    <head>
        <title>Capture Photo</title>
         
        <script type=»text/javascript» charset=»utf-8″ src=»PhoneGap.js»></script>
        <script type=»text/javascript» charset=»utf-8″>
 
            var pictureSource,
                destinationType
             
            document.addEventListener(«deviceready»,loaded,false);
             
            function loaded() {
                pictureSource=navigator.camera.PictureSourceType;
                destinationType=navigator.camera.DestinationType;
            }
             
            function getPhoto(imageData) {
                var smallImage = document.getElementById(‘smallImage’);
                 
                 
                smallImage.style.display = ‘block’;
                 
                 
                smallImage.src = «data:image/jpeg;base64,» + imageData;
            }
             
            function capturePhoto() {
                navigator.camera.getPicture(getPhoto, onFail, { quality: 50 });
            }
            
             
            function onFail(message) {
                alert(‘Failed because: ‘ + message);
            }
             
            </script>
    </head>
    <body>
        <button onclick=»capturePhoto();»>Capture Photo</button> <br>
        <img style=»display:none;width:60px;height:60px;»
    </body>
</html>

Как и прежде, мы ждем загрузки PhoneGap. Когда загрузка завершена, мы можем установить параметры для destinationType и sourceType , по умолчанию они установлены в CAMERA и DATA_URL . Когда кнопка нажата, мы capturePhoto функцию capturePhoto . После успеха capturePhoto запускает нашу функцию getPhoto . Наша функция получает данные изображения в указанном нами формате, и мы можем делать то, что хотим. Все, что мы на самом деле делаем, — это определяем элемент HTML и помещаем наши данные в источник этого элемента.

Запустите и протестируйте свой код на своем устройстве, и после того, как вы сфотографировали и протестировали, у вас должно получиться что-то похожее на приведенное ниже:

PhoneGap с нуля

Также возможно редактировать фотографию после захвата, все, что нам нужно сделать, это пройти через параметр allowEdit : true в настройках после того, как фотография была сделана. Он переместится на экран редактирования, где вы сможете увеличить и обрезать фотографию. Мы можем использовать следующий код при захвате изображения:

1
navigator.camera.getPicture(getPhoto, onFail, { allowEdit: true });

Стоит отметить некоторые allowEdit опции allowEdit . В настоящее время это работает только в iOS и игнорируется в Blackberry, Android, Palm и Windows 7.

Если бы мы хотели получить фотографию из фотоальбома или другого хранилища (например, localalstorage), мы бы использовали pictureSource.PHOTOLIBRARY .

Это в значительной степени основы, которые нам нужны, чтобы начать работать с камерой в PhoneGap. Поиграйте с ним и опробуйте некоторые вещи с разными качествами изображения, типами и размерами.


Возможно, мы захотим сохранить фотографию, сделанную где-нибудь, кроме фотоальбома на устройстве. На самом деле, это очень вероятно. Мы, вероятно, также хотим хранить другую информацию. Существует несколько способов использования хранилища устройства, один из которых — использование WebSQL, другой — использование WebStorage — оба в соответствии с определениями W3C. Вы также можете отправить данные на удаленный сервер, если хотите использовать их в облачном приложении (Instagr.am), или вы можете пойти дальше и использовать Lawnchair или PersistenceJS.

,

Я лично предпочитаю метод WebStorage и для этого проекта он идеально подходит.

Мы можем использовать WebStorage со следующим синтаксисом:

1
2
3
4
5
6
7
8
//Store the data
window.localStorage.setItem(«key», «value»);
//retrieve the data
var value = window.localStorage.getItem(«key»);
// value is now equal to «value»
 
// remove the value
window.localStorage.removeItem(«key»);

Благодаря этому базовому синтаксису у нас есть возможность хранить закодированное в base64 изображение в локальном хранилище и извлекать его, когда это необходимо.


Геолокация предоставляет информацию о местонахождении устройства. Многие устройства уже могут использовать возможность браузера использовать API Geolocation, и если вы используете реализацию PhoneGap, она использует это, если доступно.

Геолокация PhoneGap имеет 3 метода: getCurrentPosition , watchPosition и clearWatch . Метод getCurrentPosition возвращает текущее местоположение устройства с объектом позиции, который содержит свойства для:

  • широта
  • долгота
  • высота над уровнем моря
  • точность
  • altitudeAccuracy
  • заголовок
  • скорость

Базовое использование функциональности Geolocation должно выглядеть довольно знакомым:

1
navigator.geolocation.getCurrentPosition(success, error);

И тогда мы можем сделать что-то вроде следующего:

Ваш полный код должен выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html>
    <head>
        <title>Geolocation</title>
         
        <script type=»text/javascript» charset=»utf-8″ src=»PhoneGap.js»></script>
        <script type=»text/javascript» charset=»utf-8″>
             
            document.addEventListener(«deviceready», loaded, false);
             
            function loaded() {
                navigator.geolocation.getCurrentPosition(success, error);
            }
             
            function success(position) {
                var element = document.getElementById(‘geolocation’);
                element.innerHTML = ‘Latitude: ‘ + position.coords.latitude + ‘<br />’ +
                ‘Longitude: ‘ + position.coords.longitude + ‘<br />’ +
                ‘Altitude: ‘ + position.coords.altitude + ‘<br />’ +
                ‘Accuracy: ‘ + position.coords.accuracy + ‘<br />’ +
                ‘Altitude Accuracy: ‘ + position.coords.altitudeAccuracy + ‘<br />’ +
                ‘Heading: ‘ + position.coords.heading + ‘<br />’ +
                ‘Speed: ‘ + position.coords.speed + ‘<br />’ +
                ‘Timestamp: ‘ + new Date(position.timestamp) + ‘<br />’;
            }
             
            function error(error) {
                alert(error.message);
            }
             
            </script>
    </head>
    <body>
        <p id=»geolocation»>Finding geolocation…</p>
    </body>
</html>

Это даст вам информацию о положении в тот момент, когда сработает функция success . Если мы хотим постоянно следить за геолокацией устройства, мы используем метод navigator.geolocation.watchPosition вместо navigator.geolocation.getCurrentPosition , передавая ему частоту, на которой мы хотели бы обновить. Наш код должен выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html>
    <head>
        <title>Geolocation</title>
         
        <script type=»text/javascript» charset=»utf-8″ src=»PhoneGap.js»></script>
        <script type=»text/javascript» charset=»utf-8″>
             
            document.addEventListener(«deviceready», loaded, false);
             
            var watchID = null;
             
            function loaded() {
                watchID = navigator.geolocation.watchPosition(success, error, { frequency: 3000 });
            }
             
             
            function success(position) {
                var element = document.getElementById(‘geolocation’);
                element.innerHTML = ‘Latitude: ‘ + position.coords.latitude + ‘<br />’ +
                ‘Longitude: ‘ + position.coords.longitude + ‘<br />’ +
                ‘Altitude: ‘ + position.coords.altitude + ‘<br />’ +
                ‘Accuracy: ‘ + position.coords.accuracy + ‘<br />’ +
                ‘Altitude Accuracy: ‘ + position.coords.altitudeAccuracy + ‘<br />’ +
                ‘Heading: ‘ + position.coords.heading + ‘<br />’ +
                ‘Speed: ‘ + position.coords.speed + ‘<br />’ +
                ‘Timestamp: ‘ + new Date(position.timestamp) + ‘<br />’ +
                ‘<hr>’ + element.innerHTML;
            }
             
            function error(error) {
                alert(error.message);
            }
             
            </script>
    </head>
    <body>
        <p id=»geolocation»>Finding geolocation…</p>
    </body>
</html>

Если вы запустите свое приложение сейчас, вы должны получить приложение, которое выглядит так:

PhoneGap с нуля

Как и акселерометр, у геолокации также есть метод clearWatch для прекращения clearWatch изменений, который вы можете использовать со следующим кодом:

1
navigator.geolocation.clearWatch(watchID);

Теперь у нас есть знания по использованию API геолокации в PhoneGap для нашего приложения. Мы можем просто захотеть записать наше местоположение в любое время и сохранить его локально или удаленно, мы также можем захотеть записать наше движение со временем и сохранить его. Что бы мы ни хотели с этим сделать, теперь мы знаем, как получить эту информацию.


Помимо функций, которые PhoneGap предлагает из коробки, для PhoneGap имеется множество плагинов для таких вещей, как средство выбора даты, средство загрузки файлов и Paypal. Поскольку мы не будем использовать какие-либо плагины в этом приложении, рассмотрение использования и установки плагинов выходит за рамки этой серии, но вы должны знать, какие опции у вас есть при работе с PhoneGap, поэтому обязательно ознакомьтесь с GitHub проект для плагинов и вики для получения информации о том, как с ними работать. Если вы хотите увидеть отдельное руководство по использованию плагинов PhoneGap и даже написанию своих собственных, обязательно сообщите нам об этом в комментариях!


Хотя мы еще не начали разработку приложения, мы теперь работаем с PhoneGap, можем тестировать на устройстве и симуляторе, хорошо понимаем, как работают API PhoneGap, и как мы можем использовать API в приложении. В следующей части мы начнем создавать Sculder, наш пример приложения!