Show QR code when clicking on profile image

This commit is contained in:
Christian Basler 2017-04-18 16:38:45 +02:00
parent 26fca259bc
commit 911dfa7a27
3 changed files with 112 additions and 59 deletions

View File

@ -20,13 +20,11 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -39,29 +37,14 @@ import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.util.Drawables;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.exception.ApplicationException;
import ch.dissem.bitmessage.wif.WifExporter;
import static android.graphics.Color.BLACK;
import static android.graphics.Color.WHITE;
import static android.util.Base64.URL_SAFE;
/**
* A fragment representing a single Message detail screen.
@ -70,7 +53,6 @@ import static android.util.Base64.URL_SAFE;
* on handsets.
*/
public class AddressDetailFragment extends Fragment {
private static final Logger LOG = LoggerFactory.getLogger(AddressDetailFragment.class);
/**
* The fragment argument representing the item ID that this fragment
* represents.
@ -78,8 +60,6 @@ public class AddressDetailFragment extends Fragment {
public static final String ARG_ITEM = "item";
public static final String EXPORT_POSTFIX = ".keys.dat";
private static final int QR_CODE_SIZE = 350;
/**
* The content this fragment is presenting.
*/
@ -263,50 +243,12 @@ public class AddressDetailFragment extends Fragment {
// QR code
ImageView qrCode = (ImageView) rootView.findViewById(R.id.qr_code);
qrCode.setImageBitmap(qrCode(item));
qrCode.setImageBitmap(Drawables.qrCode(item));
}
return rootView;
}
Bitmap qrCode(BitmessageAddress address) {
StringBuilder link = new StringBuilder("bitmessage:");
link.append(address.getAddress());
if (address.getAlias() != null) {
link.append("?label=").append(address.getAlias());
}
if (address.getPubkey() != null) {
link.append(address.getAlias() == null ? '?' : '&');
ByteArrayOutputStream pubkey = new ByteArrayOutputStream();
try {
address.getPubkey().writeUnencrypted(pubkey);
} catch (IOException e) {
throw new ApplicationException(e);
}
link.append("pubkey=").append(Base64.encodeToString(pubkey.toByteArray(), URL_SAFE));
}
BitMatrix result;
try {
result = new MultiFormatWriter().encode(link.toString(),
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null);
} catch (WriterException e) {
LOG.error(e.getMessage(), e);
return null;
}
int w = result.getWidth();
int h = result.getHeight();
int[] pixels = new int[w * h];
for (int y = 0; y < h; y++) {
int offset = y * w;
for (int x = 0; x < w; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, QR_CODE_SIZE, 0, 0, w, h);
return bitmap;
}
@Override
public void onPause() {
if (item != null) {

View File

@ -16,16 +16,23 @@
package ch.dissem.apps.abit;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
@ -61,6 +68,7 @@ import ch.dissem.apps.abit.repository.AndroidMessageRepository;
import ch.dissem.apps.abit.service.BitmessageService;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.synchronization.SyncAdapter;
import ch.dissem.apps.abit.util.Drawables;
import ch.dissem.apps.abit.util.Labels;
import ch.dissem.apps.abit.util.Preferences;
import ch.dissem.bitmessage.BitmessageContext;
@ -230,6 +238,50 @@ public class MainActivity extends AppCompatActivity
.withActivity(this)
.withHeaderBackground(R.drawable.header)
.withProfiles(profiles)
.withOnAccountHeaderProfileImageListener(new AccountHeader.OnAccountHeaderProfileImageListener() {
@Override
public boolean onProfileImageClick(View view, IProfile profile, boolean current) {
if (current) {
// Show QR code in modal dialog
final Dialog dialog = new Dialog(MainActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageBitmap(Drawables.qrCode(Singleton.getIdentity(MainActivity.this)));
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.addContentView(imageView, new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
Window window = dialog.getWindow();
if (window != null) {
Display display = window.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int dim = size.x < size.y ? size.x : size.y;
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(window.getAttributes());
lp.width = dim;
lp.height = dim;
window.setAttributes(lp);
}
dialog.show();
return true;
}
return false;
}
@Override
public boolean onProfileImageLongClick(View view, IProfile iProfile, boolean b) {
return false;
}
})
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean current) {

View File

@ -19,19 +19,40 @@ package ch.dissem.apps.abit.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.Base64;
import android.view.Menu;
import android.view.MenuItem;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.typeface.IIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import ch.dissem.apps.abit.Identicon;
import ch.dissem.apps.abit.R;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.exception.ApplicationException;
import static android.graphics.Color.BLACK;
import static android.graphics.Color.WHITE;
import static android.util.Base64.URL_SAFE;
/**
* Some helper methods to work with drawables.
*/
public class Drawables {
private static final Logger LOG = LoggerFactory.getLogger(Drawables.class);
private static final int QR_CODE_SIZE = 350;
public static MenuItem addIcon(Context ctx, Menu menu, int menuItem, IIcon icon) {
MenuItem item = menu.findItem(menuItem);
item.setIcon(new IconicsDrawable(ctx, icon).colorRes(R.color.colorPrimaryDarkText).actionBar());
@ -49,4 +70,42 @@ public class Drawables {
identicon.draw(canvas);
return bitmap;
}
public static Bitmap qrCode(BitmessageAddress address) {
StringBuilder link = new StringBuilder("bitmessage:");
link.append(address.getAddress());
if (address.getAlias() != null) {
link.append("?label=").append(address.getAlias());
}
if (address.getPubkey() != null) {
link.append(address.getAlias() == null ? '?' : '&');
ByteArrayOutputStream pubkey = new ByteArrayOutputStream();
try {
address.getPubkey().writeUnencrypted(pubkey);
} catch (IOException e) {
throw new ApplicationException(e);
}
link.append("pubkey=").append(Base64.encodeToString(pubkey.toByteArray(), URL_SAFE));
}
BitMatrix result;
try {
result = new MultiFormatWriter().encode(link.toString(),
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null);
} catch (WriterException e) {
LOG.error(e.getMessage(), e);
return null;
}
int w = result.getWidth();
int h = result.getHeight();
int[] pixels = new int[w * h];
for (int y = 0; y < h; y++) {
int offset = y * w;
for (int x = 0; x < w; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, QR_CODE_SIZE, 0, 0, w, h);
return bitmap;
}
}