2012-06-16 50 views
7

私はAndroidアプリを開発しています.ZXingアプリで生成されたQRコードでバイト配列をエンコードしてデコードする必要があります。私の問題は、デコードされたメッセージが生成されたバイト配列と正確に一致しないことです。 Iは、増分インデックスを含むバイト配列に基づいて、QRコードを作成しようとし、すなわちZXingでbyte []をエンコードしてデコードする

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

そして、QRコードでメッセージをエンコードすると応答側でそれを復号した後、私は、次のバイト配列出力を得る:

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

"負の"バイト値はすべてASCII char 63になります。 '?'疑問符文字。 誰かがこの種の問題(other topic treating the same kind of issueまたはhere)の解決策であると主張しているISO-8859-1を使用しているため、私は間違いがどこにあるのかわかりません、または私がエンコードまたはデコードの開始中にステップをスキップしている場合。ここで 私は指定されたバイト配列をコードするために実行するコードです:

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(); 

をそして、QRコードを復号化するために、私は、次のテント

@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

UTF-8をエンコーディングとして使用するとどうなるのでしょうか? – Ixx

+0

UTF-8は確かに動作しません。すべてのバイトシーケンスが有効なUTF-8シーケンスであるとは限りません。ほとんどの入力からそのように文字列を取得することさえできません。 –

答えて

2

、あなたにたくさんありがとうございました。それは動作しません。バイナリ - >テキスト - >バイナリは、標準の文字セット/エンコーディングのいずれかを使用して損失です。 (ヒント:UTF-8を使用しても動作しません)

バイナリデータがマングルされないようにするには、base64エンコーディングや16進エンコーディングなどを使用する必要があります。

+1

私は全体的な感情に同意します。 ISO-8559-1はこの目的のためにJavaで動作します。 –

+0

@StephenC私の実装でbase64エンコーディングを使用して、問題を解決してくれてありがとう! – franckysnow

+1

@SeanOwen私はあなたに同意します。バイト[]をISO-8859-1にエンコードしてデコードし、その逆も同様です。この問題は、ZXingレイヤーにある可能性があります。しかし、base64はこの問題を解決しました。 – franckysnow

1

概念的には、QRコードはバイトではなくテキストをエンコードします。内部ではもちろん、入力を一連のバイトに変換しますが、これは呼び出し元には不透明です。正しいエンコーディングを選択すると、バイトをスニークさせることができます.ISO-8859-1は正しい選択です。それは実際には機能します。ここでの問題は、おそらくあなたのコードであることが> = 128のための文字を定義していない、とUTF-8は間違いなく

仕事に行くのではありませんので、

ASCIIはできません。私はあなたがここで何をしようとしているのかわかりません... Intentをどこかに(バーコードスキャナーに)送信するように設定しているようですが、それであなたはIntentとしていますプロジェクトからコピーしたコードですか? Intentに追加情報を設定する方法が間違っていると思います。

これはアプリ内でやっている方がずっと簡単です。ちょうどQRCodeEncoder.encodeAsBitmap()を再利用し、残りの部分を削除してください。

+0

'QRCodeEncoder'の唯一のコンストラクタは、' QRCodeEncoder(アクティビティアクティビティ、インテントインテント、intディメンション、ブール値useVCard) '引数を取ります。そして、セッターメソッドがないので、それが唯一の方法であることがわかった。あなたがエキストラで何が「間違っている」ことを少し具体的にすることができたら?それは、base64エンコーディングし、ISO8859-1文字列を 'QRCodeEncoder'に渡して、そのトリックを行ったようです。ありがとう! – franckysnow

+0

私はあなたがクラスを全く必要としないことを意味します - 私が指示した方法をコピーするだけです。 'android /'のコードはライブラリとして意図されていません。それは私たちのアプリです。主な問題は、あなたが何か不必要なことをしていることです。あなたが応答するためにそれを送信しなかったときに、「意図」を聞いています。キーのjavadocを読む - 'FORMAT'は文字エンコーディングと何も関係なく、あなたはそれを2度セットします。 –

4

私のアプリケーションの1つでは、ZXingアプリケーションで生成されたQRコードでバイト配列をエンコードしてデコードする必要がありました。バイト配列には圧縮されたテキストデータが含まれていたので、私はbase64エンコーディングを避けたかったのです。これを行うことは可能ですが、私はこれまで完全なコードスニペットを見たことがないので、ここに投稿します。

エンコード:

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のQRコードの標準エンコーディングです。特に、Xzingのオンラインデコーダhttp://zxing.org/w/decode.jspxは、このサイトでデコードされたときに生成されたQRコードが誤って見えるように、CHARACTER_SETも設定しないというのは難しいことです。

関連する問題