2012-06-16 13 views
7

के साथ मैं एक एंड्रॉइड ऐप विकसित कर रहा हूं, और मुझे ज़ेडएक्सिंग ऐप से उत्पन्न क्यूआरकोड में बाइट्स सरणी को एन्कोड और डीकोड करने की आवश्यकता है। मेरी समस्या यह है कि मेरा संदेश डीकोडेड जेनरेट बाइट सरणी से बिल्कुल मेल नहीं खाता है।एन्कोडिंग और डिकोडिंग बाइट [] ZXing

: मैं एक QRCode incrementing अनुक्रमित युक्त एक बाइट सरणी के आधार पर, यानी

input = [0, 1, 2, ..., 124, 125, 126, 127, -128, -127,... -3, -2, -1, 0, 1, 2, ...] 

और QRCode में संदेश एन्कोडिंग और प्रत्युत्तर तरफ इसे डीकोड के बाद, मैं निम्नलिखित बाइट सरणी उत्पादन प्राप्त बनाने की कोशिश की

output = [0, 1, 2, ..., 124, 125, 126, 127, 63, 63,... 63, 63, 63, 0, 1, 2, ...] 

सभी "नकारात्मक" बाइट मान ASCII char 63: '?' में बदल दिए गए हैं प्रश्न चिह्न अक्षर। मुझे लगता है कि एन्कोडिंग वर्णमाला के साथ कुछ गलत हो रहा है, लेकिन चूंकि मैं आईएसओ -885 9 -1 का उपयोग कर रहा हूं, जो हर किसी को इस तरह के मुद्दे का समाधान करने का दावा करता है (other topic treating the same kind of issue या here), मुझे नहीं लगता कि मेरी गलती कहां है , या अगर मैं एन्कोडिंग या डिकोडिंग के अस्थिरता के दौरान एक कदम छोड़ रहा हूं। यहाँ कोड है कि मैं किसी दिए गए बाइट सरणी एन्कोड करने के लिए निष्पादित है:

String text = ""; 
byte[] res = new byte[272]; 
for (int i = 0; i < res.length; i++) { 
    res[i] = (byte) (i%256); 
} 
try { 
    text = new String(res, "ISO8859_1"); 
} catch (UnsupportedEncodingException e) { 
    // TODO 
} 
Intent intent = new Intent(Intents.Encode.ACTION); 
Intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 
intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT); 
intent.putExtra(Intents.Encode.FORMAT, "ISO8859_1"); 
intent.putExtra(Intents.Encode.DATA, text); 
intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString()); 

boolean useVCard = intent.getBooleanExtra(USE_VCARD_KEY, false); 
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(activity, intent, dimension, useVCard); 
Bitmap bitmap = qrCodeEncoder.encodeAsBitmap(); 

और एक QRCode डिकोड करने के लिए, मैं निम्नलिखित आशय

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.qrcodeDecoding); 

    Intent intent = new Intent(Intents.Scan.ACTION); 
    intent.putExtra(Intents.Scan.MODE, Intents.Scan.QR_CODE_MODE); 
    startActivityForResult(intent, 0); 
} 

भेजने और इंतजार परिणाम के लिए:

@Override 
protected void onActivityResult(int request, int result, Intent data) 
{ 
    if(request == 0) 
    { 
     //action 
     if(result == RESULT_OK) 
     { 
      String res = data.getStringExtra(Intents.Scan.RESULT); 
      byte[] dat = null; 

      try{ 
        dat = res.getBytes("ISO8859_1"); 
      } catch(UnsopportedEncodingException e) { 
        //TODO 
      } 
     } 
     else if(result == RESULT_CANCELED) 
     { 
      //TODO 
     } 
    } 

} 

क्या आप कृपया मुझे बता सकते हैं कि मेरी गलतियों कहां हैं, या मुझे कहां देखना चाहिए?

आप एक बहुत,

फ़्रैंक

+0

बस "चारों ओर खेलना" (मुझे इसके बारे में कोई जानकारी नहीं है) क्या होता है यदि आप यूटीएफ -8 का उपयोग उदाहरण के लिए एन्कोडिंग के रूप में करते हैं? – Ixx

+0

यूटीएफ -8 निश्चित रूप से काम नहीं करेगा। शुरू करने के लिए प्रत्येक बाइट अनुक्रम एक वैध यूटीएफ -8 अनुक्रम नहीं है। तो इस तरह से अधिकांश इनपुट से एक स्ट्रिंग प्राप्त करना भी संभव नहीं है। –

उत्तर

2

आप सोच रहे है कि आप armouring किसी तरह का उपयोग किए बिना एक मान्य स्ट्रिंग में मनमाने ढंग से बाइनरी डेटा बदल सकते हैं की गलती कर रहे धन्यवाद। यह काम नहीं करता है। बाइनरी -> टेक्स्ट -> बाइनरी किसी भी मानक चरित्र सेट/एन्कोडिंग का उपयोग करके हानिकारक है। (संकेत: यूटीएफ -8 का उपयोग या तो काम नहीं करेगा।)

आपको बेस 64 एन्कोडिंग या हेक्साडेसिमल एन्कोडिंग जैसे कुछ का उपयोग करना चाहिए ताकि यह सुनिश्चित किया जा सके कि बाइनरी डेटा उलझन में नहीं आता है।

+1

मैं समग्र भावना से सहमत हूं; हालांकि जावा में इस उद्देश्य के लिए आईएसओ -8559-1 काम करता है। –

+0

@StephenC आपके कार्यान्वयन में बेस 64 एन्कोडिंग का उपयोग करके बहुत बहुत धन्यवाद, समस्या हल हो गई! – franckysnow

+1

@ सेनऑवेन मैं आपके साथ सहमत हूं, एन्कोडिंग और डिकोडिंग बाइट [] स्ट्रिंग आईएसओ -885 9 -1 और इसके विपरीत काम करता हूं। समस्या ZXing परत पर स्थित हो सकती है। हालांकि, बेस 64 ने मामले को हल किया। – franckysnow

1

संकल्पनात्मक रूप से, क्यूआर कोड पाठ को एन्कोड करते हैं, बाइट्स नहीं। बेशक वे बाइट्स की एक श्रृंखला में इनपुट का अनुवाद करते हैं, हालांकि यह कॉलर के लिए अपारदर्शी है। आप सही हैं, जैसा कि होता है, सही एन्कोडिंग चुनने से आप बाइट्स को छीन ले सकते हैं, और आईएसओ -885 9 -1 सही विकल्प है। यह वास्तव में काम करता है। क्योंकि यह> = 128 के लिए वर्ण को परिभाषित नहीं करता, और UTF-8 निश्चित रूप से

काम करने के लिए नहीं जा रहा है यहां मुद्दा यह शायद अपने कोड है

ASCII संभव नहीं है। मुझे यकीन नहीं है कि आप यहां क्या प्रयास कर रहे हैं ... ऐसा लगता है कि आप Intent कहीं (बारकोड स्कैनर के लिए) भेजने के लिए सेट अप कर रहे हैं लेकिन फिर आप नहीं करते हैं, आप बस Intent बना रहे हैं और इसे भेज रहे हैं प्रोजेक्ट से कॉपी किए गए कुछ कोड? मुझे लगता है कि आप Intent पर अतिरिक्त सेटिंग कैसे स्थापित कर रहे हैं, इस बारे में कुछ गलत हो गया है।

यदि आप इसे अपने ऐप में कर रहे हैं तो यह बहुत आसान होना चाहिए। बस QRCodeEncoder.encodeAsBitmap() का पुन: उपयोग करें और बाकी के बाकी को हटा दें।

+0

'QRCodeEncoder' का एकमात्र कन्स्ट्रक्टर तर्क 'QRCodeEncoder (गतिविधि गतिविधि, इरादा इरादा, int आयाम, बूलियन useVCard) के लिए तर्क लेता है। और चूंकि कोई सेटटर विधियां नहीं हैं, इसलिए यह मेरे लिए अपील की गई कि यह जाने का एकमात्र तरीका था। यदि आप अतिरिक्त के साथ "गलत" क्या हो सकता है, इसके बारे में थोड़ा और विशिष्ट हो सकता है? ऐसा लगता है कि बेस 64 एन्कोडिंग और पास करने के बाद 'QRCodeEncoder' के लिए एक ISO8859-1 स्ट्रिंग ने चाल बनाई। धन्यवाद! – franckysnow

+0

मेरा मतलब है कि आपको कक्षा की बिल्कुल आवश्यकता नहीं है - बस मैंने जिस विधि को इंगित किया है उसकी प्रतिलिपि बनाएँ। 'एंड्रॉइड /' में कोड लाइब्रेरी के रूप में नहीं है; यह हमारा ऐप है। मुख्य समस्या यह है कि आप यहां कुछ अनावश्यक कर रहे हैं - एक 'इरादा' सुनना जब आपने जवाब देने के लिए कोई नहीं भेजा था। कुंजी के लिए javadoc पढ़ें - 'FORMAT' वर्ण एन्कोडिंग के साथ कुछ भी नहीं है और आप इसे दो बार सेट करते हैं। –

4

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

एन्कोडिंग:

public void showQRCode(Activity activity, byte[] data){ 
    Intent intent = new Intent("com.google.zxing.client.android.ENCODE"); 
    intent.putExtra("ENCODE_TYPE", "TEXT_TYPE"); 
    intent.putExtra("ENCODE_SHOW_CONTENTS", false); 
    intent.putExtra("ENCODE_DATA", new String(data, "ISO-8859-1")); 
    activity.startActivity(intent); 
} 

प्रारंभ स्कैनिंग:

public static void startQRCodeScan(Activity activity){ 
    Intent intent = new Intent(com.google.zxing.client.android.SCAN); 
    intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); 
    intent.putExtra("CHARACTER_SET", "ISO-8859-1"); 
    activity.startActivityForResult(intent, 0); 
} 

स्कैन परिणाम हैंडलर:

public void onActivityResult(int requestCode, int resultCode, Intent intent) { 
    byte[] result = intent.getStringExtra("SCAN_RESULT").getBytes("ISO-8859-1"); 
    ... 
} 

मैं के लिए आशय डेटा में ISO-8859-1 करने के लिए CHARACTER_SET की स्थापना नहीं लगता है स्कैन शुरू करना वह बिंदु है जिसने मूल प्रश्न का कोड विफल कर दिया। मुझे इसे खोदने में काफी समय लगा क्योंकि मैंने इसे कहीं भी स्पष्ट रूप से पोस्ट नहीं देखा है और लैटिन 1 एन्कोडिंग Xzing में क्यूआर कोड के लिए मानक एन्कोडिंग है। विशेष रूप से मुश्किल यह तथ्य है कि Xzing ऑनलाइन डिकोडर http://zxing.org/w/decode.jspx CHARACTER_SET को भी सेट नहीं करता है ताकि जेनरेट क्यूआर कोड इस साइट पर डीकोड किए जाने पर दोषपूर्ण दिखता हो।