unfinishd qr code implemenation. thanks to @emdete

iNPUTmice created

Change summary

build.gradle                                                           |  2 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java       | 96 
src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java | 25 
src/main/res/menu/editaccount.xml                                      |  8 
src/main/res/menu/start_conversation.xml                               | 16 
src/main/res/values/strings.xml                                        |  3 
6 files changed, 132 insertions(+), 18 deletions(-)

Detailed changes

build.gradle 🔗

@@ -34,6 +34,8 @@ dependencies {
 	compile 'com.android.support:support-v13:19.1.0'
 	compile 'org.bouncycastle:bcprov-jdk15on:1.50'
 	compile 'net.java:otr4j:0.21'
+	compile 'com.google.zxing:core:3.1.0'
+	compile 'com.google.zxing:android-integration:3.1.0'
 }
 
 android {

src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java 🔗

@@ -1,23 +1,44 @@
 package eu.siacs.conversations.ui;
 
+import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Point;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.TextWatcher;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AutoCompleteTextView;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.EditText;
 import android.widget.ImageButton;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.widget.Toast;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+import com.google.zxing.qrcode.QRCodeWriter;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import java.util.Hashtable;
+
+import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
@@ -173,13 +194,13 @@ public class EditAccountActivity extends XmppActivity {
 
 		@Override
 		public void onTextChanged(CharSequence s, int start, int before,
-				int count) {
+								  int count) {
 			updateSaveButton();
 		}
 
 		@Override
 		public void beforeTextChanged(CharSequence s, int start, int count,
-				int after) {
+									  int after) {
 
 		}
 
@@ -216,9 +237,45 @@ public class EditAccountActivity extends XmppActivity {
 		} else {
 			return (!mAccount.getJid().equals(mAccountJid.getText().toString()))
 					|| (!mAccount.getPassword().equals(
-							mPassword.getText().toString()) || mAccount
-							.isOptionSet(Account.OPTION_REGISTER) != mRegisterNew
-							.isChecked());
+					mPassword.getText().toString()) || mAccount
+					.isOptionSet(Account.OPTION_REGISTER) != mRegisterNew
+					.isChecked());
+		}
+	}
+
+	protected void showQrCode() {
+		Point size = new Point();
+		getWindowManager().getDefaultDisplay().getSize(size);
+		final int width = (size.x < size.y ? size.x : size.y);
+		String jid = mAccount.getJid();
+		Bitmap bitmap = createQrCodeBitmap("xmpp:" + jid, width);
+		ImageView view = new ImageView(this);
+		view.setImageBitmap(bitmap);
+		AlertDialog.Builder builder = new AlertDialog.Builder(this);
+		builder.setView(view);
+		builder.create().show();
+	}
+
+	protected Bitmap createQrCodeBitmap(String input, int size) {
+		try {
+			final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter();
+			final Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
+			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
+			final BitMatrix result = QR_CODE_WRITER.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.TRANSPARENT;
+				}
+			}
+			final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+			bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+			return bitmap;
+		} catch (final WriterException e) {
+			return null;
 		}
 	}
 
@@ -257,7 +314,7 @@ public class EditAccountActivity extends XmppActivity {
 		return (!this.mAccount.getJid().equals(
 				this.mAccountJid.getText().toString()))
 				|| (!this.mAccount.getPassword().equals(
-						this.mPassword.getText().toString()));
+				this.mPassword.getText().toString()));
 	}
 
 	@Override
@@ -287,7 +344,7 @@ public class EditAccountActivity extends XmppActivity {
 
 					@Override
 					public void onCheckedChanged(CompoundButton buttonView,
-							boolean isChecked) {
+												 boolean isChecked) {
 						if (isChecked) {
 							mPasswordConfirm.setVisibility(View.VISIBLE);
 						} else {
@@ -298,6 +355,27 @@ public class EditAccountActivity extends XmppActivity {
 				});
 	}
 
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		super.onCreateOptionsMenu(menu);
+		getMenuInflater().inflate(R.menu.editaccount, menu);
+		MenuItem showQrCode = menu.findItem(R.id.action_show_qr_code);
+		if (mAccount == null) {
+			showQrCode.setVisible(false);
+		}
+		return true;
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+		switch (item.getItemId()) {
+			case R.id.action_show_qr_code:
+				showQrCode();
+				return true;
+		}
+		return super.onOptionsItemSelected(item);
+	}
+
 	@Override
 	protected void onStart() {
 		super.onStart();
@@ -387,7 +465,7 @@ public class EditAccountActivity extends XmppActivity {
 							@Override
 							public void onClick(View v) {
 
-								if (copyTextToClipboard(fingerprint,R.string.otr_fingerprint)) {
+								if (copyTextToClipboard(fingerprint, R.string.otr_fingerprint)) {
 									Toast.makeText(
 											EditAccountActivity.this,
 											R.string.toast_message_otr_fingerprint,

src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java 🔗

@@ -24,6 +24,7 @@ import android.support.v13.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.text.Editable;
 import android.text.TextWatcher;
+import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.KeyEvent;
@@ -40,6 +41,11 @@ import android.widget.CheckBox;
 import android.widget.EditText;
 import android.widget.ListView;
 import android.widget.Spinner;
+
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
+import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Bookmark;
@@ -491,10 +497,13 @@ public class StartConversationActivity extends XmppActivity {
 		switch (item.getItemId()) {
 		case R.id.action_create_contact:
 			showCreateContactDialog(null);
-			break;
+			return true;
 		case R.id.action_join_conference:
 			showJoinConferenceDialog();
-			break;
+			return true;
+		case R.id.action_scan_qr_code:
+			new IntentIntegrator(this).initiateScan();
+			return true;
 		}
 		return super.onOptionsItemSelected(item);
 	}
@@ -508,6 +517,18 @@ public class StartConversationActivity extends XmppActivity {
 		return super.onKeyUp(keyCode, event);
 	}
 
+	@Override
+	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+		if ((requestCode & 0xFFFF) == IntentIntegrator.REQUEST_CODE) {
+			IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+			if (scanResult != null && scanResult.getFormatName() != null) {
+				String data = scanResult.getContents();
+				Log.d(Config.LOGTAG, data);
+			}
+		}
+		super.onActivityResult(requestCode,requestCode,intent);
+	}
+
 	@Override
 	protected void onBackendConnected() {
 		xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate);

src/main/res/menu/editaccount.xml 🔗

@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/action_show_qr_code"
+        android:title="@string/show_qr_code"
+        android:showAsAction="never" />
+
+</menu>

src/main/res/menu/start_conversation.xml 🔗

@@ -1,31 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item
         android:id="@+id/action_search"
         android:actionLayout="@layout/actionview_search"
         android:icon="@drawable/ic_action_search"
         android:showAsAction="collapseActionView|always"
-        android:title="@string/search"/>
+        android:title="@string/search" />
     <item
         android:id="@+id/action_create_contact"
         android:icon="@drawable/ic_action_add_person"
         android:showAsAction="always"
-        android:title="@string/create_contact"/>
+        android:title="@string/create_contact" />
     <item
         android:id="@+id/action_join_conference"
         android:icon="@drawable/ic_action_add_group"
         android:showAsAction="always"
-        android:title="@string/join_conference"/>
+        android:title="@string/join_conference" />
+    <item
+        android:id="@+id/action_scan_qr_code"
+        android:showAsAction="never"
+        android:title="@string/scan_qr_code" />
     <item
         android:id="@+id/action_accounts"
         android:orderInCategory="90"
         android:showAsAction="never"
-        android:title="@string/action_accounts"/>
+        android:title="@string/action_accounts" />
     <item
         android:id="@+id/action_settings"
         android:orderInCategory="100"
         android:showAsAction="never"
-        android:title="@string/action_settings"/>
+        android:title="@string/action_settings" />
 
 </menu>

src/main/res/values/strings.xml 🔗

@@ -282,5 +282,6 @@
     <string name="url_copied_to_clipboard">URL copied to clipboard</string>
     <string name="message_copied_to_clipboard">Message copied to clipboard</string>
     <string name="image_transmission_failed">Image transmission failed</string>
-
+    <string name="scan_qr_code">Scan QR code</string>
+    <string name="show_qr_code">Show QR code</string>
 </resources>