use utf-8 in barcodes
This commit is contained in:
		
							parent
							
								
									0f97b44e9f
								
							
						
					
					
						commit
						b682aeb252
					
				| @ -35,174 +35,175 @@ import rocks.xmpp.addr.Jid; | ||||
| 
 | ||||
| public class BarcodeProvider extends ContentProvider implements ServiceConnection { | ||||
| 
 | ||||
|     private static final String AUTHORITY = ".barcodes"; | ||||
| 	private static final String AUTHORITY = ".barcodes"; | ||||
| 
 | ||||
|     private final Object lock = new Object(); | ||||
| 	private final Object lock = new Object(); | ||||
| 
 | ||||
|     private XmppConnectionService mXmppConnectionService; | ||||
|     private boolean mBindingInProcess = false; | ||||
| 	private XmppConnectionService mXmppConnectionService; | ||||
| 	private boolean mBindingInProcess = false; | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean onCreate() { | ||||
|         File barcodeDirectory = new File(getContext().getCacheDir().getAbsolutePath() + "/barcodes/"); | ||||
|         if (barcodeDirectory.exists() && barcodeDirectory.isDirectory()) { | ||||
|             for (File file : barcodeDirectory.listFiles()) { | ||||
|                 if (file.isFile() && !file.isHidden()) { | ||||
|                     Log.d(Config.LOGTAG, "deleting old barcode file " + file.getAbsolutePath()); | ||||
|                     file.delete(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 	public static Uri getUriForAccount(Context context, Account account) { | ||||
| 		final String packageId = context.getPackageName(); | ||||
| 		return Uri.parse("content://" + packageId + AUTHORITY + "/" + account.getJid().asBareJid() + ".png"); | ||||
| 	} | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { | ||||
|         return null; | ||||
|     } | ||||
| 	public static Bitmap create2dBarcodeBitmap(String input, int size) { | ||||
| 		try { | ||||
| 			final QRCodeWriter barcodeWriter = new QRCodeWriter(); | ||||
| 			final Hashtable<EncodeHintType, Object> hints = new Hashtable<>(); | ||||
| 			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); | ||||
| 			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); | ||||
| 			final BitMatrix result = barcodeWriter.encode(input, BarcodeFormat.QR_CODE, size, size, hints); | ||||
| 			final int width = result.getWidth(); | ||||
| 			final int height = result.getHeight(); | ||||
| 			final int[] pixels = new int[width * height]; | ||||
| 			for (int y = 0; y < height; y++) { | ||||
| 				final int offset = y * width; | ||||
| 				for (int x = 0; x < width; x++) { | ||||
| 					pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE; | ||||
| 				} | ||||
| 			} | ||||
| 			final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); | ||||
| 			bitmap.setPixels(pixels, 0, width, 0, 0, width, height); | ||||
| 			return bitmap; | ||||
| 		} catch (final Exception e) { | ||||
| 			e.printStackTrace(); | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public String getType(Uri uri) { | ||||
|         return "image/png"; | ||||
|     } | ||||
| 	@Override | ||||
| 	public boolean onCreate() { | ||||
| 		File barcodeDirectory = new File(getContext().getCacheDir().getAbsolutePath() + "/barcodes/"); | ||||
| 		if (barcodeDirectory.exists() && barcodeDirectory.isDirectory()) { | ||||
| 			for (File file : barcodeDirectory.listFiles()) { | ||||
| 				if (file.isFile() && !file.isHidden()) { | ||||
| 					Log.d(Config.LOGTAG, "deleting old barcode file " + file.getAbsolutePath()); | ||||
| 					file.delete(); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Uri insert(Uri uri, ContentValues values) { | ||||
|         return null; | ||||
|     } | ||||
| 	@Nullable | ||||
| 	@Override | ||||
| 	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public int delete(Uri uri, String selection, String[] selectionArgs) { | ||||
|         return 0; | ||||
|     } | ||||
| 	@Nullable | ||||
| 	@Override | ||||
| 	public String getType(Uri uri) { | ||||
| 		return "image/png"; | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { | ||||
|         return 0; | ||||
|     } | ||||
| 	@Nullable | ||||
| 	@Override | ||||
| 	public Uri insert(Uri uri, ContentValues values) { | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { | ||||
|         return openFile(uri, mode, null); | ||||
|     } | ||||
| 	@Override | ||||
| 	public int delete(Uri uri, String selection, String[] selectionArgs) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal) throws FileNotFoundException { | ||||
|         Log.d(Config.LOGTAG, "opening file with uri (normal): " + uri.toString()); | ||||
|         String path = uri.getPath(); | ||||
|         if (path != null && path.endsWith(".png") && path.length() >= 5) { | ||||
|             String jid = path.substring(1).substring(0, path.length() - 4); | ||||
|             Log.d(Config.LOGTAG, "account:" + jid); | ||||
|             if (connectAndWait()) { | ||||
|                 Log.d(Config.LOGTAG, "connected to background service"); | ||||
|                 try { | ||||
|                     Account account = mXmppConnectionService.findAccountByJid(Jid.of(jid)); | ||||
|                     if (account != null) { | ||||
|                         String shareableUri = account.getShareableUri(); | ||||
|                         String hash = CryptoHelper.getFingerprint(shareableUri); | ||||
|                         File file = new File(getContext().getCacheDir().getAbsolutePath() + "/barcodes/" + hash); | ||||
|                         if (!file.exists()) { | ||||
|                             file.getParentFile().mkdirs(); | ||||
|                             file.createNewFile(); | ||||
|                             Bitmap bitmap = create2dBarcodeBitmap(account.getShareableUri(), 1024); | ||||
|                             OutputStream outputStream = new FileOutputStream(file); | ||||
|                             bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); | ||||
|                             outputStream.close(); | ||||
|                             outputStream.flush(); | ||||
|                         } | ||||
|                         return ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY); | ||||
|                     } | ||||
|                 } catch (Exception e) { | ||||
|                     throw new FileNotFoundException(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         throw new FileNotFoundException(); | ||||
|     } | ||||
| 	@Override | ||||
| 	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|     private boolean connectAndWait() { | ||||
|         Intent intent = new Intent(getContext(), XmppConnectionService.class); | ||||
|         intent.setAction(this.getClass().getSimpleName()); | ||||
|         Context context = getContext(); | ||||
|         if (context != null) { | ||||
|             synchronized (this) { | ||||
|                 if (mXmppConnectionService == null && !mBindingInProcess) { | ||||
|                     Log.d(Config.LOGTAG,"calling to bind service"); | ||||
|                     context.startService(intent); | ||||
|                     context.bindService(intent, this, Context.BIND_AUTO_CREATE); | ||||
|                     this.mBindingInProcess = true; | ||||
|                 } | ||||
|             } | ||||
|             try { | ||||
|                 waitForService(); | ||||
|                 return true; | ||||
|             } catch (InterruptedException e) { | ||||
|                 return false; | ||||
|             } | ||||
|         } else { | ||||
|             Log.d(Config.LOGTAG, "context was null"); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 	@Override | ||||
| 	public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { | ||||
| 		return openFile(uri, mode, null); | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public void onServiceConnected(ComponentName name, IBinder service) { | ||||
|         synchronized (this) { | ||||
|             XmppConnectionService.XmppConnectionBinder binder = (XmppConnectionService.XmppConnectionBinder) service; | ||||
|             mXmppConnectionService = binder.getService(); | ||||
|             mBindingInProcess = false; | ||||
|             synchronized (this.lock) { | ||||
|                 lock.notifyAll(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 	@Override | ||||
| 	public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal) throws FileNotFoundException { | ||||
| 		Log.d(Config.LOGTAG, "opening file with uri (normal): " + uri.toString()); | ||||
| 		String path = uri.getPath(); | ||||
| 		if (path != null && path.endsWith(".png") && path.length() >= 5) { | ||||
| 			String jid = path.substring(1).substring(0, path.length() - 4); | ||||
| 			Log.d(Config.LOGTAG, "account:" + jid); | ||||
| 			if (connectAndWait()) { | ||||
| 				Log.d(Config.LOGTAG, "connected to background service"); | ||||
| 				try { | ||||
| 					Account account = mXmppConnectionService.findAccountByJid(Jid.of(jid)); | ||||
| 					if (account != null) { | ||||
| 						String shareableUri = account.getShareableUri(); | ||||
| 						String hash = CryptoHelper.getFingerprint(shareableUri); | ||||
| 						File file = new File(getContext().getCacheDir().getAbsolutePath() + "/barcodes/" + hash); | ||||
| 						if (!file.exists()) { | ||||
| 							file.getParentFile().mkdirs(); | ||||
| 							file.createNewFile(); | ||||
| 							Bitmap bitmap = create2dBarcodeBitmap(account.getShareableUri(), 1024); | ||||
| 							OutputStream outputStream = new FileOutputStream(file); | ||||
| 							bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); | ||||
| 							outputStream.close(); | ||||
| 							outputStream.flush(); | ||||
| 						} | ||||
| 						return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); | ||||
| 					} | ||||
| 				} catch (Exception e) { | ||||
| 					throw new FileNotFoundException(); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		throw new FileNotFoundException(); | ||||
| 	} | ||||
| 
 | ||||
|     @Override | ||||
|     public void onServiceDisconnected(ComponentName name) { | ||||
|         synchronized (this) { | ||||
|             mXmppConnectionService = null; | ||||
|         } | ||||
|     } | ||||
| 	private boolean connectAndWait() { | ||||
| 		Intent intent = new Intent(getContext(), XmppConnectionService.class); | ||||
| 		intent.setAction(this.getClass().getSimpleName()); | ||||
| 		Context context = getContext(); | ||||
| 		if (context != null) { | ||||
| 			synchronized (this) { | ||||
| 				if (mXmppConnectionService == null && !mBindingInProcess) { | ||||
| 					Log.d(Config.LOGTAG, "calling to bind service"); | ||||
| 					context.startService(intent); | ||||
| 					context.bindService(intent, this, Context.BIND_AUTO_CREATE); | ||||
| 					this.mBindingInProcess = true; | ||||
| 				} | ||||
| 			} | ||||
| 			try { | ||||
| 				waitForService(); | ||||
| 				return true; | ||||
| 			} catch (InterruptedException e) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} else { | ||||
| 			Log.d(Config.LOGTAG, "context was null"); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|     private void waitForService() throws InterruptedException { | ||||
|         if (mXmppConnectionService == null) { | ||||
|             synchronized (this.lock) { | ||||
|                 lock.wait(); | ||||
|             } | ||||
|         } else { | ||||
|             Log.d(Config.LOGTAG,"not waiting for service because already initialized"); | ||||
|         } | ||||
|     } | ||||
| 	@Override | ||||
| 	public void onServiceConnected(ComponentName name, IBinder service) { | ||||
| 		synchronized (this) { | ||||
| 			XmppConnectionService.XmppConnectionBinder binder = (XmppConnectionService.XmppConnectionBinder) service; | ||||
| 			mXmppConnectionService = binder.getService(); | ||||
| 			mBindingInProcess = false; | ||||
| 			synchronized (this.lock) { | ||||
| 				lock.notifyAll(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|     public static Uri getUriForAccount(Context context, Account account) { | ||||
|         final String packageId = context.getPackageName(); | ||||
|         return Uri.parse("content://" + packageId + AUTHORITY + "/" + account.getJid().asBareJid() + ".png"); | ||||
|     } | ||||
| 	@Override | ||||
| 	public void onServiceDisconnected(ComponentName name) { | ||||
| 		synchronized (this) { | ||||
| 			mXmppConnectionService = null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|     public static Bitmap create2dBarcodeBitmap(String input, int size) { | ||||
|         try { | ||||
|             final QRCodeWriter barcodeWriter = new QRCodeWriter(); | ||||
|             final Hashtable<EncodeHintType, Object> hints = new Hashtable<>(); | ||||
|             hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); | ||||
|             final BitMatrix result = barcodeWriter.encode(input, BarcodeFormat.QR_CODE, size, size, hints); | ||||
|             final int width = result.getWidth(); | ||||
|             final int height = result.getHeight(); | ||||
|             final int[] pixels = new int[width * height]; | ||||
|             for (int y = 0; y < height; y++) { | ||||
|                 final int offset = y * width; | ||||
|                 for (int x = 0; x < width; x++) { | ||||
|                     pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE; | ||||
|                 } | ||||
|             } | ||||
|             final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); | ||||
|             bitmap.setPixels(pixels, 0, width, 0, 0, width, height); | ||||
|             return bitmap; | ||||
|         } catch (final Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 	private void waitForService() throws InterruptedException { | ||||
| 		if (mXmppConnectionService == null) { | ||||
| 			synchronized (this.lock) { | ||||
| 				lock.wait(); | ||||
| 			} | ||||
| 		} else { | ||||
| 			Log.d(Config.LOGTAG, "not waiting for service because already initialized"); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch