Fix Wi-Fi QR code decode fail
ZXing generate QR code with default encoding ISO-8859-1,
the generated QR code is wrong encoded if there is a
character outside of the charset.
Generate QR code of UTF-8 encoding.
Bug: 131851854
Test: manual
Change-Id: I96a5e72a978c654b62d89b3b11dd3016bf0ee1df
diff --git a/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java b/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java
index 08fcb10..d9682d2 100644
--- a/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java
+++ b/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java
@@ -20,10 +20,16 @@
import android.graphics.Color;
import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
public final class QrCodeGenerator {
/**
* Generates a barcode image with {@code contents}.
@@ -34,8 +40,13 @@
*/
public static Bitmap encodeQrCode(String contents, int size)
throws WriterException, IllegalArgumentException {
+ final Map<EncodeHintType, Object> hints = new HashMap<>();
+ if (!isIso88591(contents)) {
+ hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
+ }
+
final BitMatrix qrBits = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,
- size, size);
+ size, size, hints);
final Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565);
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
@@ -44,4 +55,9 @@
}
return bitmap;
}
+
+ private static boolean isIso88591(String contents) {
+ CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
+ return encoder.canEncode(contents);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
index bd2ce1e..3f67137 100644
--- a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
@@ -128,4 +128,23 @@
assertThat(mQrCode).isEqualTo(googleUrl);
}
+
+ @Test
+ public void testDecode_unicodePictureCaptured_QrCodeCorrectValue() {
+ final String unicodeTest = "中文測試";
+
+ try {
+ final Bitmap bmp = QrCodeGenerator.encodeQrCode(unicodeTest, 320);
+ final int[] intArray = new int[bmp.getWidth() * bmp.getHeight()];
+ bmp.getPixels(intArray, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());
+ LuminanceSource source = new RGBLuminanceSource(bmp.getWidth(), bmp.getHeight(),
+ intArray);
+ final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ mCamera.decodeImage(bitmap);
+ bmp.recycle();
+ } catch (WriterException e) {
+ }
+
+ assertThat(mQrCode).isEqualTo(unicodeTest);
+ }
}