Processing:Библиотеки/Processing for Android/Руководства/Циферблаты: различия между версиями
Myagkij (обсуждение | вклад) Нет описания правки |
Нет описания правки |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 4: | Строка 4: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=Циферблаты<ref>[https://android.processing.org/tutorials/watchfaces/index.html android.processing.org - Watch Faces]</ref>= | =Циферблаты<ref>[https://android.processing.org/tutorials/watchfaces/index.html android.processing.org - Watch Faces]</ref>= | ||
Строка 26: | Строка 26: | ||
Давайте создадим максимально простой циферблат, который будет просто показывать время при помощи текста. Структура этого скетча проста: | Давайте создадим максимально простой циферблат, который будет просто показывать время при помощи текста. Структура этого скетча проста: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
void setup() { | void setup() { | ||
fullScreen(); | fullScreen(); | ||
Строка 53: | Строка 53: | ||
Мы можем генерировать паттерны и фигуры, меняющиеся по мере истечения определенного времени – часов, минут и секунд. В коде ниже мы постепенно закрашиваем экран черным цветом слева направо по мере того, как время течет от одной полуночи к другой. Мы также можем нажать на экран, добавив на еще «непоглощенную» часть экрана точку, которая исчезнет, если до нее в течение дня доберется эта неумолимо двигающаяся черная «пелена времени». | Мы можем генерировать паттерны и фигуры, меняющиеся по мере истечения определенного времени – часов, минут и секунд. В коде ниже мы постепенно закрашиваем экран черным цветом слева направо по мере того, как время течет от одной полуночи к другой. Мы также можем нажать на экран, добавив на еще «непоглощенную» часть экрана точку, которая исчезнет, если до нее в течение дня доберется эта неумолимо двигающаяся черная «пелена времени». | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
ArrayList<PVector> dots; | ArrayList<PVector> dots; | ||
int totalMin = 24 * 60; | int totalMin = 24 * 60; | ||
Строка 104: | Строка 104: | ||
Импортировав классы Vibrator и Context, инициализируем в блоке setup() экземпляр класса Vibrator: | Импортировав классы Vibrator и Context, инициализируем в блоке setup() экземпляр класса Vibrator: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
import android.os.Vibrator; | import android.os.Vibrator; | ||
import android.content.Context; | import android.content.Context; | ||
Строка 123: | Строка 123: | ||
Метод vibrator() позволяет нам задать вибрацию на определенное время (в миллисекундах). Делаем вибрацию длиной в полсекунды: | Метод vibrator() позволяет нам задать вибрацию на определенное время (в миллисекундах). Делаем вибрацию длиной в полсекунды: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
for (int i = dots.size()-1; i >= 0; i--) { | for (int i = dots.size()-1; i >= 0; i--) { | ||
PVector d = dots.get(i); | PVector d = dots.get(i); | ||
Строка 137: | Строка 137: | ||
Большинство устройств Android, включая смарт-часы, оснащены [https://developer.android.com/guide/topics/sensors/sensors_motion.html#sensors-motion-stepcounter шагомером], доступ к которому можно получить тем же способом, которым мы пользовались в предыдущих руководствах для доступа к данным других датчиков. «Скелет» этого скетча будет выглядеть следующим образом: | Большинство устройств Android, включая смарт-часы, оснащены [https://developer.android.com/guide/topics/sensors/sensors_motion.html#sensors-motion-stepcounter шагомером], доступ к которому можно получить тем же способом, которым мы пользовались в предыдущих руководствах для доступа к данным других датчиков. «Скелет» этого скетча будет выглядеть следующим образом: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
import android.content.Context; | import android.content.Context; | ||
import android.hardware.Sensor; | import android.hardware.Sensor; | ||
Строка 182: | Строка 182: | ||
В этом коде мы задаем менеджера, датчик и слушателя так же, как и в предыдущих похожих скетчах-примерах. Значение, хранящее в себе данные о насчитанных шагах – это event.values[0], которое мы можем сохранить в нашу собственную переменную. | В этом коде мы задаем менеджера, датчик и слушателя так же, как и в предыдущих похожих скетчах-примерах. Значение, хранящее в себе данные о насчитанных шагах – это event.values[0], которое мы можем сохранить в нашу собственную переменную. | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
int offset = -1; | int offset = -1; | ||
int steps; | int steps; | ||
Строка 199: | Строка 199: | ||
Наконец, мы можем добавить в блок setup() инициализацию шрифта, а затем воспользоваться данными о посчитанных шагах в блоке draw(). К примеру, ниже они просто печатаются как текст: | Наконец, мы можем добавить в блок setup() инициализацию шрифта, а затем воспользоваться данными о посчитанных шагах в блоке draw(). К примеру, ниже они просто печатаются как текст: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
void setup() { | void setup() { | ||
fullScreen(); | fullScreen(); | ||
Строка 251: | Строка 251: | ||
|Высота логотипа издателя для schemaNewsArticle=45 | |Высота логотипа издателя для schemaNewsArticle=45 | ||
}} | }} | ||
{{Навигационная таблица/ | {{Навигационная таблица/Портал/Processing}} |
Текущая версия от 11:56, 20 мая 2023
Содержание | Среда разработки Processing | Справочник языка Processing | Библиотеки | Примеры | Режимы программирования |
Циферблаты[1]
В этом руководстве рассказывается, как использовать режим программирования Android для разработки интерактивных циферблатов.
Циферблаты
Операционная система Android Wear позволяет создавать кастомные циферблаты для смарт-часов, которые, используя возможности дисплея и интерактивные функции этих устройств, могут показывать время каким-либо нестандартным образом. Кроме того, вы можете считывать данные датчиков тела (шагомеров, пульсометров и т.д.), чтобы визуализировать физическую активность пользователя. Разработка циферблатов, впрочем, требует определенных опыта и знаний – из-за ограничений этих устройств, связанных с размером экрана и максимальным зарядом батареи. Руководства Google по созданию циферблатов можно почитать тут.
Подготовка
Во-первых, разработка циферблатов требует двух устройств – смарт-часов и смартфона, который будет служить «мостиком» между компьютером, на котором запущен Processing, и смарт-часами. Для этого вам нужно настроить в устройствах отладку через Bluetooth, и о том, как это сделать, можно почитать тут. Разобравшись с этим, кликните в PDE на Android > Watch Face.
После того, как вы настроите отладку Bluetooth и выберите в PDE опцию Watch Face, смарт-часов в списке подключенных устройств по-прежнему не будет. Это нормально, потому что циферблаты не устанавливаются в смарт-часы напрямую – сначала они устанавливаются на телефон, с которым сопряжены смарт-часы, а затем через Bluetooth автоматически копируются на смарт-часы.
Создание очень простого циферблата
Давайте создадим максимально простой циферблат, который будет просто показывать время при помощи текста. Структура этого скетча проста:
void setup() {
fullScreen();
frameRate(1);
textFont(createFont("SansSerif", 30 * displayDensity));
fill(255);
}
void draw() {
background(0);
translate(0, +wearInsets().bottom/2);
if (!wearAmbient()) {
String str = hour() + ":" + minute() + ":" + second();
float w = textWidth(str);
text(str, (width - w)/2, height/2 + 24);
}
}
В этом коде есть несколько любопытных вещей. Во-первых, это частота кадров в размере «1», поскольку текст будет меняться только раз в секунду и обновлять его чаще нет никакого смысла (тем более, что это будет расходовать заряд батареи). Кроме того, циферблат будет нарисован, только если встроенная функция wearAmbient() вернет false. Причина в том, что если она вернет true, то это значит, что человек, носящий эти смарт-часы, на них не смотрит, в результате чего они переключаются в режим ожидания (англ. «ambient mode»), чтобы сэкономить заряд батареи. В режиме ожидания дисплей обновляется только раз в минуту, и рекомендуется, чтобы большая часть экрана была черной и показывала только упрощенную версию циферблата.
Кроме того, мы используем в этом коде функцию wearInsets(), чтобы получить данные о вставках на экране. В частности, нижняя вставка позволяет правильно отцентрировать графику скетча на циферблатах с «подбородком» в нижней части экрана (вроде Moto 360) и в результате весь кадр, чтобы получить правильную отцентровку, сдвигается вниз на половину этого значения. Есть еще одна важная встроенная переменная, которую мы здесь не используем – это isRound, которая сообщает форму циферблата (т.е. квадратную или круглую). Полный список встроенных переменных для циферблатов смотрите в справочнике библиотеки Android for Processing.
Время показа
Мы можем генерировать паттерны и фигуры, меняющиеся по мере истечения определенного времени – часов, минут и секунд. В коде ниже мы постепенно закрашиваем экран черным цветом слева направо по мере того, как время течет от одной полуночи к другой. Мы также можем нажать на экран, добавив на еще «непоглощенную» часть экрана точку, которая исчезнет, если до нее в течение дня доберется эта неумолимо двигающаяся черная «пелена времени».
ArrayList<PVector> dots;
int totalMin = 24 * 60;
void setup() {
fullScreen();
frameRate(1);
dots = new ArrayList<PVector>();
}
void draw() {
int time = hour() * 60 + minute();
if (time == 0) dots.clear();
float x = map(time, 0, totalMin, 0, width);
if (wearAmbient()) {
background(0);
noFill();
stroke(255);
line(x, 0, x, height);
for (PVector d: dots) {
ellipse(d.x, d.y, 10, 10);
}
} else {
background(255);
fill(0);
noStroke();
rect(0, 0, x, height);
for (PVector d: dots) {
ellipse(d.x, d.y, 10, 10);
}
}
for (int i = dots.size()-1; i >= 0; i--) {
PVector d = dots.get(i);
if (d.x < x) {
dots.remove(i);
}
}
}
void mousePressed() {
dots.add(new PVector(mouseX, mouseY));
}
Теперь давайте сделаем так, чтобы смарт-часы вибрировали с каждым разом, когда черная «пелена» поглощает добавленную пользователем точку! Чтобы получить доступ к вибрирующему механизму в смарт-часах, вам нужно включить соответствующее разрешение. Для этого в среде разработки Processing нужно нажать на Android > Sketch Permissions, а затем поставить галочку у опции VIBRATE.
Импортировав классы Vibrator и Context, инициализируем в блоке setup() экземпляр класса Vibrator:
import android.os.Vibrator;
import android.content.Context;
ArrayList<PVector> dots;
int totalMin = 24 * 60;
Vibrator vibrator;
void setup() {
fullScreen();
frameRate(1);
dots = new ArrayList<PVector>();
Context context = getContext();
vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
}
Метод vibrator() позволяет нам задать вибрацию на определенное время (в миллисекундах). Делаем вибрацию длиной в полсекунды:
for (int i = dots.size()-1; i >= 0; i--) {
PVector d = dots.get(i);
if (d.x < x) {
dots.remove(i);
vibrator.vibrate(500);
}
}
Счетчик шагов
Большинство устройств Android, включая смарт-часы, оснащены шагомером, доступ к которому можно получить тем же способом, которым мы пользовались в предыдущих руководствах для доступа к данным других датчиков. «Скелет» этого скетча будет выглядеть следующим образом:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
SensorManager manager;
Sensor sensor;
SensorListener listener;
void setup() {
fullScreen();
frameRate(1);
Context context = getContext();
manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensor = manager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
listener = new SensorListener();
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
void draw() {
}
public void resume() {
if (manager != null) {
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
public void pause() {
if (manager != null) {
manager.unregisterListener(listener);
}
}
class SensorListener implements SensorEventListener {
public void onSensorChanged(SensorEvent event) { }
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
}
В этом коде мы задаем менеджера, датчик и слушателя так же, как и в предыдущих похожих скетчах-примерах. Значение, хранящее в себе данные о насчитанных шагах – это event.values[0], которое мы можем сохранить в нашу собственную переменную.
int offset = -1;
int steps;
...
class SensorListener implements SensorEventListener {
public void onSensorChanged(SensorEvent event) {
if (offset == -1) offset = (int)event.values[0];
steps = (int)event.values[0] - offset;
}
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
}
Наконец, мы можем добавить в блок setup() инициализацию шрифта, а затем воспользоваться данными о посчитанных шагах в блоке draw(). К примеру, ниже они просто печатаются как текст:
void setup() {
fullScreen();
frameRate(1);
textFont(createFont("SansSerif", 30 * displayDensity));
textAlign(CENTER, CENTER);
fill(255);
Context context = getContext();
manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensor = manager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
listener = new SensorListener();
manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
void draw() {
background(0);
translate(0, +wearInsets().bottom/2);
if (!wearAmbient()) {
String str = steps + " steps";
float w = textWidth(str);
text(str, 0, 0, width, height);
}
}
Вы, возможно, захотите сохранить данные о посчитанных шагах, чтобы отслеживать профиль активности пользователя. В языке Processing есть несколько функций для сохранения и загрузки данных в циферблат – к примеру, saveStrings() и loadStrings(). Впрочем, вам также нужно удостовериться, что у вас включено разрешение WRITE_EXTERNAL_STORAGE.
Примечание: Если вы имеете дело с опасным разрешением (вроде WRITE_EXTERNAL_STORAGE), то его запрос в коде нужно сделать явно – как объясняется в этом руководстве. После этого вам также надо дать соответствующее разрешение в самом устройстве – либо через уведомление, которое будет запущено циферблатом, либо перейдя в настройки разрешений для циферблата (о том, как это сделать, можно прочесть тут).
См.также
Внешние ссылки
Примеры на Processing | |
---|---|
Основы |
|
Продвинутые графические эффекты |
|
Примеры из сторонних библиотек |