Qt 5.6

2015-10-26 6 views
56

का उपयोग कर एंड्रॉइड पर काम कर रहे एनएफसी को कैसे प्राप्त करें मैं क्यूटी के एनएफसी मॉड्यूल का उपयोग करके अपने एंड्रॉइड फोन पर एनएफसी टैग पढ़ने की कोशिश कर रहा हूं।Qt 5.6

इस page के अनुसार, क्यूटी संस्करण 5.6 से शुरू होने वाले एंड्रॉइड पर एनएफसी का समर्थन करेगा। यह संस्करण अभी तक जारी नहीं किया गया है, इसलिए मैंने इसे page पर दिए गए निर्देशों के बाद, स्रोत से बनाया है, और इसे Qt निर्माता में स्थापित किया है।

पहला कदम टैग/कार्ड का पता लगाने के लिए पहला कदम है और मैं वहां फंस गया हूं। मेरा टेस्ट एप्लिकेशन QNearFieldManager को तुरंत चालू करता है, यह जांचता है कि क्या एनएफसी उपलब्ध है और सिग्नल targetDetected और targetLost पर स्लॉट कनेक्ट करता है। QNearFieldManager::isAvailable विधि रिपोर्ट करता है कि एनएफसी उपलब्ध है (क्यूटी 5.5 के साथ यह नहीं था), लेकिन संकेत targetDetected/targetLost कभी नहीं निकाल दिए जाते हैं। कुछ

#include <QLabel> 
#include <QVBoxLayout> 

#include <QNearFieldManager> 
#include <QNearFieldTarget> 

#include <QDebug> 

#include "window.h" 

Window::Window(QWidget *parent) 
: QWidget(parent) 
{ 
    nfcLabel_ = new QLabel(this); 

    QVBoxLayout *mainLayout = new QVBoxLayout; 
    mainLayout->addWidget(nfcLabel_, 1); 

    setLayout(mainLayout); 

    setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); 

    setWindowTitle(tr("NFC Test")); 

    nfc_ = new QNearFieldManager(this); 
    if (nfc_->isAvailable()) { 
     nfcLabel_->setText("NFC available"); 
    } else { 
     nfcLabel_->setText("NFC not available"); 
     qWarning() << "NFC not available"; 
    } 

    nfc_->setTargetAccessModes(QNearFieldManager::NdefReadTargetAccess); // doesn't help 

    nfc_->registerNdefMessageHandler(this, SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*))); // doesn't help 

    connect(nfc_, SIGNAL(targetDetected(QNearFieldTarget*)), this, SLOT(targetDetected(QNearFieldTarget*))); 
    connect(nfc_, SIGNAL(targetLost(QNearFieldTarget*)), this, SLOT(targetLost(QNearFieldTarget*))); 

    if (!nfc_->startTargetDetection()) { 
     qWarning() << "NFC target detection could not be started"; 
    } 
} 

Window::~Window() 
{ 
    nfc_->stopTargetDetection(); 
} 

void Window::targetDetected(QNearFieldTarget * /*target*/) 
{ 
    nfcLabel_->setText("Target detected"); 
} 

void Window::targetLost(QNearFieldTarget *target) 
{ 
    nfcLabel_->setText("Target lost"); 
    target->deleteLater(); 
} 

void Window::handleNdefMessage(const QNdefMessage &/*message*/, QNearFieldTarget */*target*/) 
{ 
    qDebug() << "Ndef Message"; 
} 

मुझे याद आ जाना चाहिए ...

अद्यतन 1

ऐसा लगता है कि AndroidManifest.xml फ़ाइल में की जरूरत है:

नीचे अपने परीक्षण आवेदन के कोड है संशोधित किया जाना चाहिए। मैंने अलग-अलग चीजों की कोशिश की, लेकिन कोई भी वांछित प्रभाव उत्पन्न नहीं कर रहा है। मैं केवल आग targetDetected और targetLost घटनाओं प्राप्त कर सकते हैं जब प्रकट इस तरह को कोई लक्ष्य फिल्टर परिभाषित करता है:,

<intent-filter> 
    <action android:name="android.nfc.action.TAG_DISCOVERED"/> 
    <category android:name="android.intent.category.DEFAULT"/> 
</intent-filter> 

बहरहाल, यह भी एप्लिकेशन हर बार एक लक्ष्य स्कैन किया जाता है शुरू किया जा करने का कारण बनता भी एप्लिकेशन अगर पहले से ही चल रहा है। मुझे ऐप शुरू करने की आवश्यकता है और फिर स्कैन किए जाने वाले लक्ष्य की प्रतीक्षा करें। मैं यह कैसे हासिल कर सकता हूं?

अद्यतन 2

नीचे पूर्ण AndroidManifest.xml फ़ाइल है कि मैं करने की कोशिश की है।

<?xml version="1.0"?> 
<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> 
    <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:theme="@android:style/Theme.Holo"> 
    <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop"> 
     <intent-filter> 
     <action android:name="android.intent.action.MAIN"/> 
     <category android:name="android.intent.category.LAUNCHER"/> 
     </intent-filter> 

     <!-- Without this, the targetDetected/targetLost signals aren't fired --> 
     <intent-filter> 
     <action android:name="android.nfc.action.TAG_DISCOVERED"/> 
     <category android:name="android.intent.category.DEFAULT"/> 
     </intent-filter> 

     <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> 
     <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.qt_libs_resource_id" android:resource="@array/qt_libs"/> 
     <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/> 
     <!-- Deploy Qt libs as part of package --> 
     <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/> 
     <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/> 
     <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/> 
     <!-- Run with local libs --> 
     <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/> 
     <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/> 
     <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/> 
     <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/> 
     <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/> 
     <!-- Messages maps --> 
     <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/> 
     <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/> 
     <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/> 
     <!-- Messages maps --> 

     <!-- Splash screen --> 
     <!-- 
     <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/> 
     --> 
     <!-- Splash screen --> 

     <!-- Background running --> 
     <!-- Warning: changing this value to true may cause unexpected crashes if the 
       application still try to draw after 
       "applicationStateChanged(Qt::ApplicationSuspended)" 
       signal is sent! --> 
     <meta-data android:name="android.app.background_running" android:value="false"/> 
     <!-- Background running --> 
    </activity> 
    </application> 
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/> 
    <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> 
    <uses-feature android:name="android.hardware.nfc" android:required="true"/> 
    <uses-permission android:name="android.permission.NFC"/> 
</manifest> 
+0

क्या आपने यह सुनिश्चित करने के लिए [एंड्रॉइड दस्तावेज़] (https://developer.android.com/guide/topics/connectivity/nfc/nfc.html) जांच लिया है कि आपके पास सभी सही अनुमतियां सेट हैं? उदाहरण के लिए: '<उपयोग-अनुमति एंड्रॉइड: नाम =" android.permission।एनएफसी "/>' – jrossi

+0

हां, अनुमतियां सही ढंग से सेट की गई हैं। जैसा कि मैंने उपरोक्त वर्णित किया है, लक्ष्य की उपस्थिति लक्ष्य को आग लगती है पता लगाया गया सिग्नल, मुझे लगता है कि अगर अनुमतियां सही नहीं थीं तो ऐसा नहीं होगा। समस्या यह है कि यह भी है ऐप का एक और उदाहरण लॉन्च करता है, जो इसे क्रैश करता है। मैं एक पल में अपनी पूर्ण एंड्रॉइडमैनीफेस्ट.एक्सएमएल फाइल पोस्ट करूंगा ... – Pat

+0

क्या लॉगकट में कुछ दिलचस्प है? –

उत्तर

-3

हैलो नीचे जवाब है, मुझे पता है कि तुम देख रहे हैं इस के लिए ही करते हैं। :) सबसे पहले onCreate()

//Code in onCreate 
mNfcAdapter = NfcAdapter.getDefaultAdapter(this); 
     mPendingIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 

     // set an intent filter for all MIME data 
     IntentFilter ndefIntent = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); 
     try { 
      ndefIntent.addDataType("*/*"); 
      mIntentFilters = new IntentFilter[] { ndefIntent }; 
     } catch (Exception e) { 
      Log.fnLogToFile(strFunctionName + "-" + e.getMessage(), ErrorType.ERROR); 
      Log.createCrashReport(); 
     } 

     mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } }; 

लिखें onCreate बाहर इस onNewIntent() में यह लिख

@Override 
    public void onNewIntent(Intent intent) {   

     StackTraceElement[] arrFunctionName = Thread.currentThread().getStackTrace() ; 
     String strFunctionName = arrFunctionName[arrFunctionName.length-1].getMethodName(); 
     Log.fnLogToFile(strFunctionName + "Entered", ErrorType.INFO); 
     tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 

     String strTagData = ""; 
     // parse through all NDEF messages and their records and pick text type only 
     Parcelable[] data = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 

     if (data != null) { 
      try { 
       for (int i = 0; i < data.length; i++) {     
        NdefRecord [] recs = ((NdefMessage)data[i]).getRecords(); 
        for (int j = 0; j < recs.length; j++) { 
         if (recs[j].getTnf() == NdefRecord.TNF_WELL_KNOWN && 
           Arrays.equals(recs[j].getType(), NdefRecord.RTD_TEXT)) { 

          byte[] payload = recs[j].getPayload(); 
          String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16"; 
          int langCodeLen = payload[0] & 0077; 
          //tag data is saved in strTagData 
          strTagData += ("\n" + 
            new String(payload, langCodeLen + 1, 
              payload.length - langCodeLen - 1, textEncoding)); 
         } 
        } 
       } 
      } catch (Exception e) { 
       Log.fnLogToFile(strFunctionName + "-" + e.getMessage(), ErrorType.ERROR); 
       Log.createCrashReport(); 
       Log.e("TagDispatch", e.toString()); 
      } 

     } 
    } 

आप प्रकट

में
+2

मुझे लाइव जावा कोड दिखता है, लेकिन मुझे इसे Qt (C++) – Pat

1

strTagData में एनएफसी डेटा मिलेगा चर

अनुमति यदि आप कुछ निर्माता के एनएफसी टैग का उपयोग कर रहे हैं तो यह मोबाइल एनएफसी में भी मौजूद होना चाहिए, फिर भी यह ठीक से जोड़ देगा क्योंकि एनएफसी एन वैश्विक स्तर पर ओटी समर्थन। उदाहरण के लिए। यदि सोनी डिवाइस के अंदर एनएफसी प्रेजेंट केवल अपने निर्माण का समर्थन करेगा और ज्यादातर मामलों में यह नेक्सस जैसे अन्य उपकरणों से कनेक्ट करने में विफल रहता है। तो अपने निर्माता को खोजने और इसे जोड़ने का प्रयास करें। उम्मीद है कि यह आपकी मदद करता है ..

1

मुझे विश्वास नहीं है कि आप अपने मैनिफेस्ट में उन इच्छित फ़िल्टर चाहते हैं। उनको जोड़कर, ऑपरेटिंग सिस्टम को आपके ऐप को शुरू करने के लिए कहता है जब कोई टैग पता चला है (यही कारण है कि यह ऐसा कर रहा है)।ऐसा लगता है कि आप एनएफसी कार्यक्रमों के लिए अपने कोड में सही तरीके से पंजीकरण कर रहे हैं, इसलिए शायद यह समस्या आपके फोन में एनएफसी चिप का ब्रांड है, जिसका उपयोग आप टैग करने के लिए कर रहे हैं। यदि आपका फोन ब्रॉडकॉम एनएफसी चिप से लैस है, और आप एनएक्सपी के MIFARE क्लासिक टैग का उपयोग करने की कोशिश कर रहे हैं, तो आप मुद्दों में भाग लेंगे। एक डिस्फायर का उपयोग करना, या एनएजी टैग मदद कर सकता है।

+0

में काम करने की आवश्यकता है, मुझे नहीं लगता कि हार्डवा पुनः/फर्मवेयर मुद्दा था, क्योंकि मुझे Playstore पर एक ऐप मिला जो एक ही टैग के साथ सही तरीके से काम करता था। अफसोस की बात है कि मुझे ऐप का नाम याद नहीं आया, फोन कुछ समय पहले टूट गया था और मैंने उस फलों की कंपनी पर स्विच किया ... – Pat

1

मैंने इसे हल किया है।

कारण यह है कि QtNfc.java में जहां क्यूटी इस तथ्य के बावजूद ACTION_NDEF_DISCOVERED क्रिया (और NDEF टैग कि तकनीक के रूप में रिपोर्ट करेंगे के लिए ACTION_TECH_DISCOVERED) सरल ACTION_TAG_DISCOVERED बिना (छान कर हीNDEF टैग एनएफसी उद्देश्य यह संभालती संभालती है यह getStartIntent फक्शन में इसे संभालता है)।

लेकिन मुझे लगता है कि आप यूआईडी पढ़ने के लिए बस एक साधारण टैग स्कैन करना चाहते हैं, जैसा कि मैं करता हूं। तो तुम QtNfc.java शुरुआत में फ़िल्टर सूची में() फ़ंक्शन ACTION_TAG_DISCOVERED जोड़ने की जरूरत:

IntentFilter[] filters = new IntentFilter[3]; 
filters[0] = new IntentFilter(); 
filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED); 
filters[0].addCategory(Intent.CATEGORY_DEFAULT); 
... 

मुझे लगता है कि इसे और अधिक भी setContext में ACTION_TAG_DISCOVERED करने के लिए फिल्टर संशोधित करने के लिए सही होगा। क्यूटी निर्माता qtconnectivity में खोलने का सबसे तेज़ तरीका है। संबंधित शाखा के लिए, सही QtNfc.java, इसे बनाएं और libQt5Nfc.so को android_armv7 \ lib qt फ़ोल्डर में बदलें (QtNfc.jar और QtNfc-bundled.jar android_armv7 \ jar फ़ोल्डर में निर्माण के दौरान अद्यतन किया जाएगा)।

यही है। कामकाजी आवेदन में प्रकट करने की जरूरत नहीं है।

तरह से इस एक द्वारा:

<uses-permission android:name="android.permission.NFC"/> 

क्यूटी स्वचालित रूप से जब आप जोड़ने मॉड्यूल एनएफसी .pro को

यह एक

<uses-feature android:name="android.hardware.nfc" android:required="true"/> 

आवश्यक नहीं है मुझे लगता है। यह इसके बिना काम करता है।

लेकिन अगर आप एंड्रॉइड के ऊपरी हिस्से के रूप में एक टैग के रूप में पता चला है तो आप अपने ऐप को शुरू करने के लिए एंड्रॉइड को बताना चाहते हैं तो आप इस इरादे-फ़िल्टर को जोड़ सकते हैं। लेकिन मैं वास्तव में एंड्रॉइड जोड़ने की अनुशंसा करता हूं: हमेशा रीटेन टास्कस्टेट = "सत्य" एंड्रॉइड: एप्लिकेशन गतिविधि में लॉन्चमोड = "सिंगल इंस्टेंस" (जैसे here)।

मैं एंड्रॉइड 4.4.4 टैबलेट और एनडीएफडिटर उदाहरण के साथ यह सब परीक्षण करता हूं। यह लक्ष्य को सुरक्षित/लक्ष्य पूरी तरह से फायर करता है। सिस्टम में टैग के लिए एक और डिफ़ॉल्ट अनुप्रयोग हो सकता है (उदाहरण के लिए NFC Reader) और यह प्रत्येक टैग का पता लगाने पर खुलता है, लेकिन समय एनडीएफडिटर टैग (बटन पुनर्प्राप्त) का इंतजार नहीं कर रहा है। और निश्चित रूप से क्यूटी उदाहरण गैर-एनडीईएफ टैग के लिए "एनडीईएफ पढ़ने में त्रुटि" कहता है, लेकिन यह उन्हें पहचानता है और यूआईडी पढ़ता है। निश्चित रूप से मुझे क्या चाहिए।

मैं suggestion to Qt Jira जोड़ता हूं और patch सबमिट करता हूं।

एकमात्र चीज जिसे मैं समझ नहीं पाया - क्यों एनडीएफडिटर ने एंड्रॉइड 4.2 के साथ एक और टैबलेट पर काम किया था। हो सकता है कि यह एक हार्डवेयर पहलू है और एंड्रॉइड किसी अन्य टैबलेट पर हमेशा ACTION_NDEF_DISCOVERED का इरादा था?

+0

मेरा पैच क्यूटी 5.9.0 बीटा 1 में विलय हो गया है –

संबंधित मुद्दे