made qr code available from muc and contact details as well

This commit is contained in:
iNPUTmice 2014-11-04 12:15:14 +01:00
parent 12e2f0bdd7
commit b3582c970e
7 changed files with 190 additions and 120 deletions

View File

@ -139,6 +139,15 @@ public class ConferenceDetailsActivity extends XmppActivity {
} }
} }
@Override
protected String getShareableUri() {
if (conversation!=null) {
return "xmpp:"+conversation.getContactJid().split("/")[0]+"?join";
} else {
return super.getShareableUri();
}
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.muc_details, menu); getMenuInflater().inflate(R.menu.muc_details, menu);

View File

@ -161,6 +161,15 @@ public class ContactDetailsActivity extends XmppActivity {
} }
}; };
@Override
protected String getShareableUri() {
if (contact!=null) {
return "xmpp:"+contact.getJid();
} else {
return super.getShareableUri();
}
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

View File

@ -83,18 +83,6 @@ public class ConversationActivity extends XmppActivity implements
private Uri pendingImageUri = null; private Uri pendingImageUri = null;
private NfcAdapter.CreateNdefMessageCallback mNdefPushMessageCallback = new NfcAdapter.CreateNdefMessageCallback() {
@Override
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
Conversation conversation = getSelectedConversation();
NdefMessage msg = new NdefMessage(new NdefRecord[]{
NdefRecord.createUri("xmpp:"+conversation.getAccount().getJid()),
NdefRecord.createApplicationRecord("eu.siacs.conversations")
});
return msg;
}
};
public List<Conversation> getConversationList() { public List<Conversation> getConversationList() {
return this.conversationList; return this.conversationList;
} }
@ -122,6 +110,16 @@ public class ConversationActivity extends XmppActivity implements
} }
} }
@Override
protected String getShareableUri() {
Conversation conversation = getSelectedConversation();
if (conversation!=null) {
return "xmpp:"+conversation.getAccount().getJid();
} else {
return super.getShareableUri();
}
}
public void hideConversationsOverview() { public void hideConversationsOverview() {
if (mContentView instanceof SlidingPaneLayout) { if (mContentView instanceof SlidingPaneLayout) {
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
@ -163,9 +161,6 @@ public class ConversationActivity extends XmppActivity implements
getActionBar().setDisplayHomeAsUpEnabled(false); getActionBar().setDisplayHomeAsUpEnabled(false);
getActionBar().setHomeButtonEnabled(false); getActionBar().setHomeButtonEnabled(false);
registerNdefPushMessageCallback(this.mNdefPushMessageCallback);
this.listAdapter = new ConversationAdapter(this, conversationList); this.listAdapter = new ConversationAdapter(this, conversationList);
listView.setAdapter(this.listAdapter); listView.setAdapter(this.listAdapter);
@ -664,6 +659,18 @@ public class ConversationActivity extends XmppActivity implements
} }
} }
@Override
public void onResume() {
super.onResume();
this.registerNdefPushMessageCallback();
}
@Override
public void onPause() {
super.onPause();
this.unregisterNdefPushMessageCallback();
}
@Override @Override
protected void onStop() { protected void onStop() {
if (xmppConnectionServiceBound) { if (xmppConnectionServiceBound) {

View File

@ -41,6 +41,7 @@ import java.util.Hashtable;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
@ -243,42 +244,6 @@ public class EditAccountActivity extends XmppActivity {
} }
} }
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;
}
}
protected void updateSaveButton() { protected void updateSaveButton() {
if (mAccount != null if (mAccount != null
&& mAccount.getStatus() == Account.STATUS_CONNECTING) { && mAccount.getStatus() == Account.STATUS_CONNECTING) {
@ -317,6 +282,15 @@ public class EditAccountActivity extends XmppActivity {
this.mPassword.getText().toString())); this.mPassword.getText().toString()));
} }
@Override
protected String getShareableUri() {
if (mAccount!=null) {
return "xmpp:"+mAccount.getJid();
} else {
return super.getShareableUri();
}
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -366,16 +340,6 @@ public class EditAccountActivity extends XmppActivity {
return true; 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 @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();

View File

@ -1,7 +1,56 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
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.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
@ -16,41 +65,6 @@ import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.ExceptionHelper;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.AlertDialog.Builder;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.IntentSender.SendIntentException;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
public abstract class XmppActivity extends Activity { public abstract class XmppActivity extends Activity {
@ -187,15 +201,18 @@ public abstract class XmppActivity extends Activity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_settings: case R.id.action_settings:
startActivity(new Intent(this, SettingsActivity.class)); startActivity(new Intent(this, SettingsActivity.class));
break; break;
case R.id.action_accounts: case R.id.action_accounts:
startActivity(new Intent(this, ManageAccountActivity.class)); startActivity(new Intent(this, ManageAccountActivity.class));
break; break;
case android.R.id.home: case android.R.id.home:
finish(); finish();
break; break;
case R.id.action_show_qr_code:
showQrCode();
break;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -233,7 +250,7 @@ public abstract class XmppActivity extends Activity {
} }
public void switchToConversation(Conversation conversation, String text, public void switchToConversation(Conversation conversation, String text,
boolean newTask) { boolean newTask) {
Intent viewConversationIntent = new Intent(this, Intent viewConversationIntent = new Intent(this,
ConversationActivity.class); ConversationActivity.class);
viewConversationIntent.setAction(Intent.ACTION_VIEW); viewConversationIntent.setAction(Intent.ACTION_VIEW);
@ -282,7 +299,7 @@ public abstract class XmppActivity extends Activity {
@Override @Override
public void userInputRequried(PendingIntent pi, public void userInputRequried(PendingIntent pi,
Account account) { Account account) {
try { try {
startIntentSenderForResult(pi.getIntentSender(), startIntentSenderForResult(pi.getIntentSender(),
REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
@ -372,7 +389,7 @@ public abstract class XmppActivity extends Activity {
} }
private void warnMutalPresenceSubscription(final Conversation conversation, private void warnMutalPresenceSubscription(final Conversation conversation,
final OnPresenceSelected listener) { final OnPresenceSelected listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(conversation.getContact().getJid()); builder.setTitle(conversation.getContact().getJid());
builder.setMessage(R.string.without_mutual_presence_updates); builder.setMessage(R.string.without_mutual_presence_updates);
@ -395,13 +412,13 @@ public abstract class XmppActivity extends Activity {
} }
protected void quickPasswordEdit(String previousValue, protected void quickPasswordEdit(String previousValue,
OnValueEdited callback) { OnValueEdited callback) {
quickEdit(previousValue, callback, true); quickEdit(previousValue, callback, true);
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private void quickEdit(final String previousValue, private void quickEdit(final String previousValue,
final OnValueEdited callback, boolean password) { final OnValueEdited callback, boolean password) {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
View view = getLayoutInflater().inflate(R.layout.quickedit, null); View view = getLayoutInflater().inflate(R.layout.quickedit, null);
final EditText editor = (EditText) view.findViewById(R.id.editor); final EditText editor = (EditText) view.findViewById(R.id.editor);
@ -431,7 +448,7 @@ public abstract class XmppActivity extends Activity {
} }
public void selectPresence(final Conversation conversation, public void selectPresence(final Conversation conversation,
final OnPresenceSelected listener) { final OnPresenceSelected listener) {
Contact contact = conversation.getContact(); Contact contact = conversation.getContact();
if (!contact.showInRoster()) { if (!contact.showInRoster()) {
showAddToRosterDialog(conversation); showAddToRosterDialog(conversation);
@ -472,7 +489,7 @@ public abstract class XmppActivity extends Activity {
@Override @Override
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int which) { int which) {
presence.delete(0, presence.length()); presence.delete(0, presence.length());
presence.append(presencesArray[which]); presence.append(presencesArray[which]);
} }
@ -492,7 +509,7 @@ public abstract class XmppActivity extends Activity {
} }
protected void onActivityResult(int requestCode, int resultCode, protected void onActivityResult(int requestCode, int resultCode,
final Intent data) { final Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_INVITE_TO_CONVERSATION if (requestCode == REQUEST_INVITE_TO_CONVERSATION
&& resultCode == RESULT_OK) { && resultCode == RESULT_OK) {
@ -532,8 +549,8 @@ public abstract class XmppActivity extends Activity {
DisplayMetrics metrics = getResources().getDisplayMetrics(); DisplayMetrics metrics = getResources().getDisplayMetrics();
return ((int) (dp * metrics.density)); return ((int) (dp * metrics.density));
} }
public boolean copyTextToClipboard(String text,int labelResId) { public boolean copyTextToClipboard(String text, int labelResId) {
ClipboardManager mClipBoardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); ClipboardManager mClipBoardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
String label = getResources().getString(labelResId); String label = getResources().getString(labelResId);
if (mClipBoardManager != null) { if (mClipBoardManager != null) {
@ -544,12 +561,68 @@ public abstract class XmppActivity extends Activity {
return false; return false;
} }
protected void registerNdefPushMessageCallback(NfcAdapter.CreateNdefMessageCallback callback) { protected void registerNdefPushMessageCallback() {
if (android.os.Build.VERSION.SDK_INT >= 16) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter != null && nfcAdapter.isEnabled()) { if (nfcAdapter != null && nfcAdapter.isEnabled()) {
nfcAdapter.setNdefPushMessageCallback(callback, this); nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
@Override
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
NdefMessage msg = new NdefMessage(new NdefRecord[]{
NdefRecord.createUri(getShareableUri()),
NdefRecord.createApplicationRecord("eu.siacs.conversations")
});
return msg;
}
}, this);
} }
}
protected void unregisterNdefPushMessageCallback() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter != null && nfcAdapter.isEnabled()) {
nfcAdapter.setNdefPushMessageCallback(null,this);
}
}
protected String getShareableUri() {
return null;
}
protected void showQrCode() {
String uri = getShareableUri();
if (uri!=null) {
Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
final int width = (size.x < size.y ? size.x : size.y);
Bitmap bitmap = createQrCodeBitmap(uri, 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;
} }
} }
@ -616,7 +689,7 @@ public abstract class XmppActivity extends Activity {
} }
public static boolean cancelPotentialWork(Message message, public static boolean cancelPotentialWork(Message message,
ImageView imageView) { ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (bitmapWorkerTask != null) { if (bitmapWorkerTask != null) {
@ -645,7 +718,7 @@ public abstract class XmppActivity extends Activity {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap, public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) { BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap); super(res, bitmap);
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>( bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
bitmapWorkerTask); bitmapWorkerTask);

View File

@ -13,6 +13,10 @@
android:orderInCategory="10" android:orderInCategory="10"
android:showAsAction="always" android:showAsAction="always"
android:title="@string/action_delete_contact"/> android:title="@string/action_delete_contact"/>
<item
android:id="@+id/action_show_qr_code"
android:title="@string/show_qr_code"
android:showAsAction="never" />
<item <item
android:id="@+id/action_accounts" android:id="@+id/action_accounts"
android:orderInCategory="90" android:orderInCategory="90"

View File

@ -7,6 +7,10 @@
android:orderInCategory="10" android:orderInCategory="10"
android:showAsAction="always" android:showAsAction="always"
android:title="@string/action_edit_subject"/> android:title="@string/action_edit_subject"/>
<item
android:id="@+id/action_show_qr_code"
android:title="@string/show_qr_code"
android:showAsAction="never" />
<item <item
android:id="@+id/action_accounts" android:id="@+id/action_accounts"
android:orderInCategory="90" android:orderInCategory="90"