Initial stab on NFC support
parent
d0bbdc5eb6
commit
3ea0ec1f9f
|
|
@ -2,7 +2,7 @@ TEMPLATE = lib
|
||||||
TARGET = service
|
TARGET = service
|
||||||
CONFIG += dll
|
CONFIG += dll
|
||||||
QT += core androidextras
|
QT += core androidextras
|
||||||
QT += network qml quick quickcontrols2 svg websockets bluetooth charts
|
QT += network qml quick quickcontrols2 svg websockets bluetooth charts nfc
|
||||||
|
|
||||||
include(../config.pri)
|
include(../config.pri)
|
||||||
include(../android_openssl/openssl.pri)
|
include(../android_openssl/openssl.pri)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QtQml>
|
#include <QtQml>
|
||||||
#include <QtAndroid>
|
#include <QtAndroid>
|
||||||
#include <QAndroidJniObject>
|
#include <QAndroidJniObject>
|
||||||
|
#include <QNdefNfcUriRecord>
|
||||||
|
|
||||||
QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||||
{
|
{
|
||||||
|
|
@ -26,26 +27,31 @@ DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QAp
|
||||||
setApplicationName("nymea-app");
|
setApplicationName("nymea-app");
|
||||||
setOrganizationName("nymea");
|
setOrganizationName("nymea");
|
||||||
|
|
||||||
|
QNearFieldManager *manager = new QNearFieldManager(this);
|
||||||
|
int ret = manager->registerNdefMessageHandler(this, SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*)));
|
||||||
|
qDebug() << "*** NFC registered" << ret;
|
||||||
|
|
||||||
QString nymeaId = QtAndroid::androidActivity().callObjectMethod<jstring>("nymeaId").toString();
|
QString nymeaId = QtAndroid::androidActivity().callObjectMethod<jstring>("nymeaId").toString();
|
||||||
QString thingId = QtAndroid::androidActivity().callObjectMethod<jstring>("thingId").toString();
|
QString thingId = QtAndroid::androidActivity().callObjectMethod<jstring>("thingId").toString();
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
NymeaDiscovery *discovery = new NymeaDiscovery(this);
|
m_discovery = new NymeaDiscovery(this);
|
||||||
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
|
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
|
||||||
discovery->setAwsClient(AWSClient::instance());
|
m_discovery->setAwsClient(AWSClient::instance());
|
||||||
NymeaHost *host = discovery->nymeaHosts()->find(nymeaId);
|
NymeaHost *host = m_discovery->nymeaHosts()->find(nymeaId);
|
||||||
|
|
||||||
if (!host) {
|
if (nymeaId.isEmpty() && !host) {
|
||||||
qWarning() << "No such nymea host:" << nymeaId;
|
qWarning() << "No such nymea host:" << nymeaId;
|
||||||
// TODO: We could wait here until the discovery finds it... But it really should be cached already...
|
// TODO: We could wait here until the discovery finds it... But it really should be cached already...
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine *m_engine = new Engine(this);
|
m_engine = new Engine(this);
|
||||||
|
|
||||||
|
m_engine->jsonRpcClient()->connectToHost(host);
|
||||||
|
|
||||||
qDebug() << "Connecting to:" << host;
|
qDebug() << "Connecting to:" << host;
|
||||||
m_engine->jsonRpcClient()->connectToHost(host);
|
|
||||||
|
|
||||||
qDebug() << "Creating QML view";
|
qDebug() << "Creating QML view";
|
||||||
QQmlApplicationEngine *qmlEngine = new QQmlApplicationEngine(this);
|
QQmlApplicationEngine *qmlEngine = new QQmlApplicationEngine(this);
|
||||||
|
|
@ -64,3 +70,32 @@ DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QAp
|
||||||
qmlEngine->load(QUrl(QLatin1String("qrc:/Main.qml")));
|
qmlEngine->load(QUrl(QLatin1String("qrc:/Main.qml")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceControlApplication::handleNdefMessage(QNdefMessage message, QNearFieldTarget *target)
|
||||||
|
{
|
||||||
|
qDebug() << "************* NFC message!" << message.toByteArray() << target;
|
||||||
|
foreach (const QNdefRecord &record, message) {
|
||||||
|
QNdefNfcUriRecord uriRecord(record);
|
||||||
|
qDebug() << "record" << uriRecord.uri();
|
||||||
|
QUrl url = uriRecord.uri();
|
||||||
|
QUuid nymeaId = QUuid(url.host().split('.').first());
|
||||||
|
QUuid thingId = QUuid(url.host().split('.').last());
|
||||||
|
QList<QPair<QString, QString>> queryItems = QUrlQuery(url.query()).queryItems();
|
||||||
|
for (int i = 0; i < queryItems.count(); i++) {
|
||||||
|
QUuid stateTypeId = queryItems.at(i).first;
|
||||||
|
QVariant value = queryItems.at(i).second;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NymeaHost *host = m_discovery->nymeaHosts()->find(nymeaId);
|
||||||
|
m_engine->jsonRpcClient()->connectToHost(host);
|
||||||
|
qmlEngine->rootContext()->setContextProperty("controlledThingId", thingId);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceControlApplication::createView()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@
|
||||||
#define DEVICECONTROLAPPLICATION_H
|
#define DEVICECONTROLAPPLICATION_H
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QNearFieldManager>
|
||||||
|
#include <QNdefMessage>
|
||||||
|
|
||||||
|
#include "connection/discovery/nymeadiscovery.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
class DeviceControlApplication : public QApplication
|
class DeviceControlApplication : public QApplication
|
||||||
{
|
{
|
||||||
|
|
@ -9,6 +14,15 @@ class DeviceControlApplication : public QApplication
|
||||||
public:
|
public:
|
||||||
explicit DeviceControlApplication(int argc, char *argv[]);
|
explicit DeviceControlApplication(int argc, char *argv[]);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleNdefMessage(QNdefMessage message,QNearFieldTarget* target);
|
||||||
|
|
||||||
|
void createView();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NymeaDiscovery *m_discovery = nullptr;
|
||||||
|
Engine *m_engine = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICECONTROLAPPLICATION_H
|
#endif // DEVICECONTROLAPPLICATION_H
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
#define NYMEAAPPSERVICE_H
|
#define NYMEAAPPSERVICE_H
|
||||||
|
|
||||||
#include <QAndroidService>
|
#include <QAndroidService>
|
||||||
|
#include <QNearFieldManager>
|
||||||
|
#include <QNdefMessage>
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,5 +236,6 @@
|
||||||
<file>ui/images/connections/nm-signal-100-secure.svg</file>
|
<file>ui/images/connections/nm-signal-100-secure.svg</file>
|
||||||
<file>ui/images/connections/bluetooth.svg</file>
|
<file>ui/images/connections/bluetooth.svg</file>
|
||||||
<file>ui/images/connections/network-wired-disabled.svg</file>
|
<file>ui/images/connections/network-wired-disabled.svg</file>
|
||||||
|
<file>ui/images/nfc.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
#include "pushnotifications.h"
|
#include "pushnotifications.h"
|
||||||
#include "applogcontroller.h"
|
#include "applogcontroller.h"
|
||||||
#include "ruletemplates/messages.h"
|
#include "ruletemplates/messages.h"
|
||||||
|
#include "nfchelper.h"
|
||||||
|
|
||||||
QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||||
{
|
{
|
||||||
|
|
@ -124,6 +125,7 @@ int main(int argc, char *argv[])
|
||||||
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
||||||
|
|
||||||
qmlRegisterSingletonType<PlatformHelper>("Nymea", 1, 0, "PlatformHelper", platformHelperProvider);
|
qmlRegisterSingletonType<PlatformHelper>("Nymea", 1, 0, "PlatformHelper", platformHelperProvider);
|
||||||
|
qmlRegisterType<NfcHelper>("Nymea", 1, 0, "NfcHelper");
|
||||||
|
|
||||||
PushNotifications::instance()->connectClient();
|
PushNotifications::instance()->connectClient();
|
||||||
qmlRegisterSingletonType<PushNotifications>("Nymea", 1, 0, "PushNotifications", PushNotifications::pushNotificationsProvider);
|
qmlRegisterSingletonType<PushNotifications>("Nymea", 1, 0, "PushNotifications", PushNotifications::pushNotificationsProvider);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include "nfchelper.h"
|
||||||
|
#include "types/deviceclass.h"
|
||||||
|
#include "types/statetype.h"
|
||||||
|
|
||||||
|
#include <QNearFieldManager>
|
||||||
|
#include <QNdefMessage>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QNdefNfcUriRecord>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
|
||||||
|
NfcHelper::NfcHelper(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
m_manager = new QNearFieldManager(this);
|
||||||
|
connect(m_manager, &QNearFieldManager::targetDetected, this, &NfcHelper::targetDetected);
|
||||||
|
connect(m_manager, &QNearFieldManager::targetLost, this, &NfcHelper::targetLost);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NfcHelper::busy() const
|
||||||
|
{
|
||||||
|
return m_busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NfcHelper::writeThingStates(Engine *engine, Device *thing)
|
||||||
|
{
|
||||||
|
if (m_busy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl url;
|
||||||
|
url.setScheme("nymea");
|
||||||
|
url.setHost(engine->jsonRpcClient()->currentHost()->uuid().toString().remove(QRegExp("[{}]")) + "." + thing->id().toString().remove(QRegExp("[{}]")));
|
||||||
|
QUrlQuery query;
|
||||||
|
for (int i = 0; i < thing->thingClass()->stateTypes()->rowCount(); i++) {
|
||||||
|
StateType *stateType = thing->thingClass()->stateTypes()->get(i);
|
||||||
|
ActionType *actionType = thing->thingClass()->actionTypes()->getActionType(stateType->id());
|
||||||
|
if (!actionType) {
|
||||||
|
continue; // Read only state
|
||||||
|
}
|
||||||
|
QVariant currentValue = thing->states()->getState(stateType->id())->value();
|
||||||
|
query.addQueryItem(stateType->id().toString().remove(QRegExp("[{}]")), currentValue.toString());
|
||||||
|
}
|
||||||
|
url.setQuery(query);
|
||||||
|
qDebug() << "writing message" << url;
|
||||||
|
|
||||||
|
QNdefNfcUriRecord record;
|
||||||
|
record.setUri(url);
|
||||||
|
QNdefMessage message;
|
||||||
|
message.append(record);
|
||||||
|
|
||||||
|
m_currentMessage = message;
|
||||||
|
m_manager->startTargetDetection();
|
||||||
|
m_busy = true;
|
||||||
|
emit busyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NfcHelper::targetDetected(QNearFieldTarget *target)
|
||||||
|
{
|
||||||
|
connect(target, &QNearFieldTarget::ndefMessagesWritten, this, &NfcHelper::ndefMessageWritten);
|
||||||
|
connect(target, &QNearFieldTarget::error, this, &NfcHelper::targetError);
|
||||||
|
|
||||||
|
|
||||||
|
QNearFieldTarget::RequestId m_request = target->writeNdefMessages(QList<QNdefMessage>() << m_currentMessage);
|
||||||
|
if (!m_request.isValid()) {
|
||||||
|
qDebug() << "Error writing tag";
|
||||||
|
//targetError(QNearFieldTarget::NdefWriteError, m_request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NfcHelper::targetLost(QNearFieldTarget *target)
|
||||||
|
{
|
||||||
|
qDebug() << "Target lost" << target;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NfcHelper::ndefMessageWritten()
|
||||||
|
{
|
||||||
|
qDebug() << "NDEF message written";
|
||||||
|
m_manager->stopTargetDetection();
|
||||||
|
m_busy = false;
|
||||||
|
emit busyChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NfcHelper::targetError()
|
||||||
|
{
|
||||||
|
qDebug() << "Target error";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef NFCHELPER_H
|
||||||
|
#define NFCHELPER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QNearFieldManager>
|
||||||
|
#include <QNdefMessage>
|
||||||
|
|
||||||
|
#include "types/device.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
class NfcHelper : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NfcHelper(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
bool busy() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void writeThingStates(Engine *engine, Device *thing);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void busyChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void targetDetected(QNearFieldTarget *target);
|
||||||
|
void targetLost(QNearFieldTarget *target);
|
||||||
|
|
||||||
|
void ndefMessageWritten();
|
||||||
|
void targetError();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNearFieldManager *m_manager = nullptr;
|
||||||
|
bool m_busy = false;
|
||||||
|
|
||||||
|
QNdefMessage m_currentMessage;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NFCHELPER_H
|
||||||
|
|
@ -2,7 +2,7 @@ TEMPLATE=app
|
||||||
TARGET=nymea-app
|
TARGET=nymea-app
|
||||||
include(../config.pri)
|
include(../config.pri)
|
||||||
|
|
||||||
QT += network qml quick quickcontrols2 svg websockets bluetooth charts gui-private
|
QT += network qml quick quickcontrols2 svg websockets bluetooth charts gui-private nfc
|
||||||
|
|
||||||
INCLUDEPATH += $$top_srcdir/libnymea-app
|
INCLUDEPATH += $$top_srcdir/libnymea-app
|
||||||
LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app
|
LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app
|
||||||
|
|
@ -14,6 +14,7 @@ PRE_TARGETDEPS += ../libnymea-app
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
mainmenumodel.h \
|
mainmenumodel.h \
|
||||||
|
nfchelper.h \
|
||||||
platformintegration/generic/raspberrypihelper.h \
|
platformintegration/generic/raspberrypihelper.h \
|
||||||
stylecontroller.h \
|
stylecontroller.h \
|
||||||
pushnotifications.h \
|
pushnotifications.h \
|
||||||
|
|
@ -24,6 +25,7 @@ HEADERS += \
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
mainmenumodel.cpp \
|
mainmenumodel.cpp \
|
||||||
|
nfchelper.cpp \
|
||||||
platformintegration/generic/raspberrypihelper.cpp \
|
platformintegration/generic/raspberrypihelper.cpp \
|
||||||
stylecontroller.cpp \
|
stylecontroller.cpp \
|
||||||
pushnotifications.cpp \
|
pushnotifications.cpp \
|
||||||
|
|
@ -162,3 +164,5 @@ BR=$$BRANDING
|
||||||
|
|
||||||
target.path = /usr/bin
|
target.path = /usr/bin
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|
||||||
|
ANDROID_ABIS = armeabi-v7a arm64-v8a
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ Page {
|
||||||
thingMenu.addItem(menuEntryComponent.createObject(thingMenu, {text: qsTr("Logs"), iconSource: "../images/logs.svg", functionName: "openDeviceLogPage"}))
|
thingMenu.addItem(menuEntryComponent.createObject(thingMenu, {text: qsTr("Logs"), iconSource: "../images/logs.svg", functionName: "openDeviceLogPage"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (engine.jsonRpcClient.ensureServerVersion(1.6)) {
|
if (engine.jsonRpcClient.ensureServerVersion("1.6")) {
|
||||||
thingMenu.addItem(menuEntryComponent.createObject(thingMenu,
|
thingMenu.addItem(menuEntryComponent.createObject(thingMenu,
|
||||||
{
|
{
|
||||||
text: Qt.binding(function() { return favoritesProxy.count === 0 ? qsTr("Mark as favorite") : qsTr("Remove from favorites")}),
|
text: Qt.binding(function() { return favoritesProxy.count === 0 ? qsTr("Mark as favorite") : qsTr("Remove from favorites")}),
|
||||||
|
|
@ -111,6 +111,14 @@ Page {
|
||||||
functionName: "addToGroup"
|
functionName: "addToGroup"
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thingMenu.addItem(menuEntryComponent.createObject(thingMenu,
|
||||||
|
{
|
||||||
|
text: qsTr("Write NFC tag"),
|
||||||
|
iconSource: "../images/nfc.svg",
|
||||||
|
functionName: "writeNfcTag"
|
||||||
|
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
function openDeviceMagicPage() {
|
function openDeviceMagicPage() {
|
||||||
pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device})
|
pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device})
|
||||||
|
|
@ -138,6 +146,14 @@ Page {
|
||||||
pageStack.push(Qt.resolvedUrl("DeviceLogPage.qml"), {device: root.device });
|
pageStack.push(Qt.resolvedUrl("DeviceLogPage.qml"), {device: root.device });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NfcHelper {
|
||||||
|
id: nfcHelper
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeNfcTag() {
|
||||||
|
nfcHelper.writeThingStates(engine, root.thing)
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: menuEntryComponent
|
id: menuEntryComponent
|
||||||
IconMenuItem {
|
IconMenuItem {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
id="svg4874"
|
||||||
|
height="96"
|
||||||
|
viewBox="0 0 96 96.000001"
|
||||||
|
width="96"
|
||||||
|
version="1.1"
|
||||||
|
sodipodi:docname="nfc.svg"
|
||||||
|
inkscape:version="1.0.1 (1.0.1+r73)">
|
||||||
|
<path
|
||||||
|
id="path884"
|
||||||
|
style="color:#000000;fill:none"
|
||||||
|
d="M 30.00026,1.073013 V -94.92699 h 96 V 1.073013 Z" />
|
||||||
|
<path
|
||||||
|
id="path886"
|
||||||
|
style="color:#000000;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#808080;fill-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
|
||||||
|
d="m 42.041184,59.03214 21.92185,21.147163 c 2.283959,1.18636 3.037486,-1.033283 -0.0035,-5.561123 L 42.236652,53.66296 M 68.001221,84.147015 V 20.14502 c 0,-2.63041 -0.23782,-4.7121 -0.89648,-6.4668 -0.65866,-1.75461 -1.85,-3.15961 -3.3555,-3.9902 -3.011,-1.6613 -6.6918,-1.4848 -11.725,-1.543 h -0.01172 l -0.03472,4.0001 h 0.02344 c 5.0383,0.0588 8.3519,0.23688 9.8164,1.0449 0.73364,0.40478 1.1508,0.85491 1.541,1.8945 0.39025,1.0396 0.64258,2.691 0.64258,5.0606 v 60.072038 z"
|
||||||
|
sodipodi:nodetypes="cccccsccccccscscc" />
|
||||||
|
<defs
|
||||||
|
id="defs9" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1380"
|
||||||
|
inkscape:window-height="873"
|
||||||
|
id="namedview7"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="2.1413287"
|
||||||
|
inkscape:cx="32.892399"
|
||||||
|
inkscape:cy="42.615368"
|
||||||
|
inkscape:window-x="60"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4874">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid834" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata4879">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(67.856999,-78.504993)">
|
||||||
|
<rect
|
||||||
|
id="rect4782"
|
||||||
|
style="color:#000000;fill:none"
|
||||||
|
transform="rotate(90)"
|
||||||
|
height="96"
|
||||||
|
width="96"
|
||||||
|
y="-28.143"
|
||||||
|
x="78.504997" />
|
||||||
|
<path
|
||||||
|
id="path4643"
|
||||||
|
style="color:#000000;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#808080;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
|
||||||
|
d="m -43.869,86.504 -0.01172,0.002 c -5.0328,0.05818 -8.7136,-0.12027 -11.725,1.541 -1.5055,0.83064 -2.6968,2.2356 -3.3555,3.9902 -0.65866,1.7547 -0.89648,3.8364 -0.89648,6.4668 v 56.002 c 0,2.6304 0.23782,4.7121 0.89648,6.4668 0.65866,1.7546 1.85,3.1596 3.3555,3.9902 3.011,1.6613 6.6918,1.4848 11.725,1.543 H -43.869 4.154 4.165719 c 5.0328,-0.0582 8.7136,0.11832 11.725,-1.543 1.5055,-0.83064 2.6968,-2.2356 3.3555,-3.9902 0.65866,-1.7547 0.89648,-3.8364 0.89648,-6.4668 V 98.504 c 0,-2.6304 -0.23782,-4.7121 -0.89648,-6.4668 -0.66,-1.759 -1.851,-3.163 -3.356,-3.994 -3.011,-1.661 -6.6922,-1.483 -11.725,-1.541 L 4.1535,86.5002 h -48.023 z m 0.01172,4 h 48 c 5.0383,0.05877 8.3519,0.23688 9.8164,1.0449 0.73364,0.40478 1.1527,0.85491 1.543,1.8945 0.39025,1.0396 0.64062,2.691 0.64062,5.0605 v 56.002 c 0,2.3696 -0.25037,4.0209 -0.64062,5.0606 -0.39025,1.0396 -0.80933,1.4898 -1.543,1.8945 -1.4645,0.80804 -4.7782,0.98616 -9.8164,1.0449 h -47.977 -0.02344 c -5.0383,-0.0588 -8.3519,-0.23688 -9.8164,-1.0449 -0.73364,-0.40478 -1.1508,-0.85491 -1.541,-1.8945 -0.39025,-1.0396 -0.64258,-2.691 -0.64258,-5.0606 v -56.002 c 0,-2.3696 0.25232,-4.0209 0.64258,-5.0605 0.39025,-1.0396 0.80738,-1.4898 1.541,-1.8945 1.4645,-0.80804 4.7782,-0.98616 9.8164,-1.0449 z" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g868"
|
||||||
|
transform="translate(87.856999,-78.504993)">
|
||||||
|
<path
|
||||||
|
id="rect864"
|
||||||
|
style="color:#000000;fill:none"
|
||||||
|
transform="rotate(90)"
|
||||||
|
d="M 78.504997,-28.143 H 174.505 v 96 H 78.504997 Z" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
id="path892"
|
||||||
|
style="color:#000000;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#808080;fill-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
|
||||||
|
d="M 54.001221,37.259895 32.079371,16.112732 c -2.283959,-1.18636 -3.037486,1.033283 0.0035,5.561123 l 21.722882,20.95522 M 28.041184,12.14502 v 64.001995 c 0,2.63041 0.23782,4.7121 0.89648,6.4668 0.65866,1.75461 1.85,3.15961 3.3555,3.9902 3.011,1.6613 6.6918,1.4848 11.725,1.543 h 0.01172 l 0.03472,-4.0001 h -0.02344 c -5.0383,-0.0588 -8.3519,-0.23688 -9.8164,-1.0449 -0.73364,-0.40478 -1.1508,-0.85491 -1.541,-1.8945 -0.39025,-1.0396 -0.64258,-2.691 -0.64258,-5.0606 V 16.074877 Z"
|
||||||
|
sodipodi:nodetypes="cccccsccccccscscc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.0 KiB |
|
|
@ -64,6 +64,11 @@
|
||||||
|
|
||||||
|
|
||||||
<activity android:process=":qt_controlsActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="io.guh.nymeaapp.NymeaAppControlsActivity" android:label="nymea:app" android:screenOrientation="unspecified" android:launchMode="standard">
|
<activity android:process=":qt_controlsActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="io.guh.nymeaapp.NymeaAppControlsActivity" android:label="nymea:app" android:screenOrientation="unspecified" android:launchMode="standard">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<data android:scheme="nymea"/>
|
||||||
|
</intent-filter>
|
||||||
<meta-data android:name="android.app.lib_name" android:value="service"/>
|
<meta-data android:name="android.app.lib_name" android:value="service"/>
|
||||||
<meta-data android:name="android.app.arguments" android:value="--controlActivity"/>
|
<meta-data android:name="android.app.arguments" android:value="--controlActivity"/>
|
||||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||||
|
|
@ -95,6 +100,11 @@
|
||||||
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
|
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
|
||||||
|
|
||||||
<service android:process=":qt_service" android:name="io.guh.nymeaapp.NymeaAppService">
|
<service android:process=":qt_service" android:name="io.guh.nymeaapp.NymeaAppService">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<data android:scheme="xbmc"/>
|
||||||
|
</intent-filter>
|
||||||
<meta-data android:name="android.app.lib_name" android:value="service"/>
|
<meta-data android:name="android.app.lib_name" android:value="service"/>
|
||||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||||
|
|
@ -145,4 +155,5 @@
|
||||||
Remove the comment if you do not require these default features. -->
|
Remove the comment if you do not require these default features. -->
|
||||||
<!-- %%INSERT_FEATURES -->
|
<!-- %%INSERT_FEATURES -->
|
||||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ import android.telephony.TelephonyManager;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.nfc.NfcAdapter;
|
||||||
|
import android.nfc.NdefMessage;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
// An activity spawned by android device controls on demand.
|
// An activity spawned by android device controls on demand.
|
||||||
|
|
||||||
|
|
@ -48,4 +51,22 @@ public class NymeaAppControlsActivity extends org.qtproject.qt5.android.bindings
|
||||||
v.vibrate(duration);
|
v.vibrate(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
Log.d(TAG, "*************** New intent");
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
|
||||||
|
Parcelable[] rawMessages =
|
||||||
|
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
|
||||||
|
if (rawMessages != null) {
|
||||||
|
NdefMessage[] messages = new NdefMessage[rawMessages.length];
|
||||||
|
for (int i = 0; i < rawMessages.length; i++) {
|
||||||
|
messages[i] = (NdefMessage) rawMessages[i];
|
||||||
|
Log.d(TAG, messages[i].toString());
|
||||||
|
}
|
||||||
|
// Process the messages array.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue