diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 20be4abd4..344eb0545 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -57,17 +57,9 @@ - - - - - - - - @@ -76,13 +68,6 @@ - - - - - - - @@ -94,7 +79,20 @@ + + + + + + + + + + + accountList = new ArrayList<>(); + protected ListView accountListView; + protected AccountAdapter mAccountAdapter; + + @Override + protected void refreshUiReal() { + synchronized (this.accountList) { + accountList.clear(); + accountList.addAll(xmppConnectionService.getAccounts()); + } + ActionBar actionBar = getActionBar(); + if (actionBar != null) { + actionBar.setHomeButtonEnabled(this.accountList.size() > 0); + actionBar.setDisplayHomeAsUpEnabled(this.accountList.size() > 0); + } + mAccountAdapter.notifyDataSetChanged(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.manage_accounts); + + accountListView = (ListView) findViewById(R.id.account_list); + this.mAccountAdapter = new AccountAdapter(this, accountList, false); + accountListView.setAdapter(this.mAccountAdapter); + accountListView.setOnItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView arg0, View view, + int position, long arg3) { + final Account account = accountList.get(position); + final String body = getIntent().getStringExtra(EXTRA_BODY); + + try { + final Jid contact = Jid.fromString(getIntent().getStringExtra(EXTRA_CONTACT)); + final Conversation conversation = xmppConnectionService.findOrCreateConversation( + account, contact, false, false); + switchToConversation(conversation, body, false); + } catch (InvalidJidException e) { + // ignore error + } + + finish(); + } + }); + } + + @Override + protected void onStart() { + super.onStart(); + final int theme = findTheme(); + if (this.mTheme != theme) { + recreate(); + } + } + + @Override + void onBackendConnected() { + final int numAccounts = xmppConnectionService.getAccounts().size(); + + if (numAccounts == 1) { + final String body = getIntent().getStringExtra(EXTRA_BODY); + final Account account = xmppConnectionService.getAccounts().get(0); + + try { + final Jid contact = Jid.fromString(getIntent().getStringExtra(EXTRA_CONTACT)); + final Conversation conversation = xmppConnectionService.findOrCreateConversation( + account, contact, false, false); + switchToConversation(conversation, body, false); + } catch (InvalidJidException e) { + // ignore error + } + + finish(); + } else { + refreshUiReal(); + } + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 914ed6358..912c19712 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -2,7 +2,6 @@ package eu.siacs.conversations.ui; import android.Manifest; import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.ActionBar.TabListener; @@ -20,12 +19,8 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; -import android.nfc.NdefMessage; -import android.nfc.NdefRecord; -import android.nfc.NfcAdapter; import android.os.Build; import android.os.Bundle; -import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.Editable; @@ -55,9 +50,6 @@ import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; -import com.google.zxing.integration.android.IntentIntegrator; -import com.google.zxing.integration.android.IntentResult; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -644,7 +636,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU showCreateConferenceDialog(); return true; case R.id.action_scan_qr_code: - new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE")); + Intent intent = new Intent(this, UriHandlerActivity.class); + intent.setAction(UriHandlerActivity.ACTION_SCAN_QR_CODE); + startActivity(intent); return true; case R.id.action_hide_offline: mHideOfflineContacts = !item.isChecked(); @@ -682,20 +676,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU @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(); - Invite invite = new Invite(data); - if (xmppConnectionServiceBound) { - invite.invite(); - } else if (invite.getJid() != null) { - this.mPendingInvite = invite; - } else { - this.mPendingInvite = null; - } - } - } else if (resultCode == RESULT_OK) { + if (resultCode == RESULT_OK) { if (xmppConnectionServiceBound) { this.mPostponedActivityResult = null; if (requestCode == REQUEST_CREATE_CONFERENCE) { @@ -820,11 +801,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU setIntent(null); } - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) - Invite getInviteJellyBean(NdefRecord record) { - return new Invite(record.toUri()); - } - protected boolean handleIntent(Intent intent) { if (intent == null || intent.getAction() == null) { return false; @@ -840,27 +816,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } else { return false; } - case NfcAdapter.ACTION_NDEF_DISCOVERED: - for (Parcelable message : getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) { - if (message instanceof NdefMessage) { - for (NdefRecord record : ((NdefMessage) message).getRecords()) { - switch (record.getTnf()) { - case NdefRecord.TNF_WELL_KNOWN: - if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) { - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - return getInviteJellyBean(record).invite(); - } else { - byte[] payload = record.getPayload(); - if (payload[0] == 0) { - return new Invite(Uri.parse(new String(Arrays.copyOfRange( - payload, 1, payload.length)))).invite(); - } - } - } - } - } - } - } } return false; } @@ -876,7 +831,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU return true; } List contacts = xmppConnectionService.findContacts(invite.getJid(),invite.account); - if (invite.isMuc()) { + if (invite.isAction(XmppUri.ACTION_JOIN)) { Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid()); if (muc != null) { switchToConversation(muc,invite.getBody(),false); @@ -1202,9 +1157,5 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } return false; } - - public boolean isMuc() { - return muc; - } } } diff --git a/src/main/java/eu/siacs/conversations/ui/UriHandlerActivity.java b/src/main/java/eu/siacs/conversations/ui/UriHandlerActivity.java new file mode 100644 index 000000000..9ffa1b11f --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/UriHandlerActivity.java @@ -0,0 +1,136 @@ +package eu.siacs.conversations.ui; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.os.Build; +import android.os.Parcelable; + +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + +import java.util.Arrays; + +import eu.siacs.conversations.persistance.DatabaseBackend; +import eu.siacs.conversations.utils.XmppUri; +import eu.siacs.conversations.xmpp.jid.Jid; + +public class UriHandlerActivity extends Activity { + public static final String ACTION_SCAN_QR_CODE = "scan_qr_code"; + + @Override + public void onStart() { + super.onStart(); + handleIntent(getIntent()); + } + + @Override + public void onNewIntent(Intent intent) { + handleIntent(intent); + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + Uri getInviteJellyBean(NdefRecord record) { + return record.toUri(); + } + + private void handleUri(Uri uri) { + final Intent intent; + final XmppUri xmppUri = new XmppUri(uri); + final int numAccounts = DatabaseBackend.getInstance(this).getAccountJids().size(); + + if (numAccounts == 0) { + intent = new Intent(getApplicationContext(), WelcomeActivity.class); + startActivity(intent); + return; + } + + if (xmppUri.isAction(XmppUri.ACTION_MESSAGE)) { + final Jid jid = xmppUri.getJid(); + final String body = xmppUri.getBody(); + + if (jid != null) { + intent = new Intent(getApplicationContext(), ShareViaAccountActivity.class); + intent.putExtra(ShareViaAccountActivity.EXTRA_CONTACT, jid.toString()); + intent.putExtra(ShareViaAccountActivity.EXTRA_BODY, body); + } else { + intent = new Intent(getApplicationContext(), ShareWithActivity.class); + intent.setAction(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, body); + } + } else { + intent = new Intent(getApplicationContext(), StartConversationActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + intent.setData(uri); + } + + startActivity(intent); + } + + private void handleNfcIntent(Intent data) { + for (Parcelable message : data.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) { + if (message instanceof NdefMessage) { + for (NdefRecord record : ((NdefMessage) message).getRecords()) { + switch (record.getTnf()) { + case NdefRecord.TNF_WELL_KNOWN: + if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) { + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + handleUri(getInviteJellyBean(record)); + } else { + byte[] payload = record.getPayload(); + if (payload[0] == 0) { + Uri uri = Uri.parse(new String(Arrays.copyOfRange( + payload, 1, payload.length))); + handleUri(uri); + } + } + } + } + } + } + } + } + + private void handleIntent(Intent data) { + if (data == null) { + finish(); + return; + } + + switch (data.getAction()) { + case Intent.ACTION_VIEW: + case Intent.ACTION_SENDTO: + handleUri(data.getData()); + break; + case ACTION_SCAN_QR_CODE: + new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC", "QR_CODE")); + return; + case NfcAdapter.ACTION_NDEF_DISCOVERED: + handleNfcIntent(data); + } + + finish(); + } + + @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(); + handleUri(Uri.parse(data)); + } + } + + finish(); + super.onActivityResult(requestCode, requestCode, intent); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index d7e241798..bbcf51c9d 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -29,10 +29,18 @@ import eu.siacs.conversations.utils.UIHelper; public class AccountAdapter extends ArrayAdapter { private XmppActivity activity; + private boolean showStateButton; + + public AccountAdapter(XmppActivity activity, List objects, boolean showStateButton) { + super(activity, 0, objects); + this.activity = activity; + this.showStateButton = showStateButton; + } public AccountAdapter(XmppActivity activity, List objects) { super(activity, 0, objects); this.activity = activity; + this.showStateButton = true; } @Override @@ -68,6 +76,11 @@ public class AccountAdapter extends ArrayAdapter { final Switch tglAccountState = (Switch) view.findViewById(R.id.tgl_account_status); final boolean isDisabled = (account.getStatus() == Account.State.DISABLED); tglAccountState.setChecked(!isDisabled,false); + if (this.showStateButton) { + tglAccountState.setVisibility(View.VISIBLE); + } else { + tglAccountState.setVisibility(View.GONE); + } tglAccountState.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { diff --git a/src/main/java/eu/siacs/conversations/utils/XmppUri.java b/src/main/java/eu/siacs/conversations/utils/XmppUri.java index c20c9a4ac..ec8fd51c0 100644 --- a/src/main/java/eu/siacs/conversations/utils/XmppUri.java +++ b/src/main/java/eu/siacs/conversations/utils/XmppUri.java @@ -14,14 +14,17 @@ import eu.siacs.conversations.xmpp.jid.Jid; public class XmppUri { protected String jid; - protected boolean muc; protected List fingerprints = new ArrayList<>(); private String body; + private String action; protected boolean safeSource = true; public static final String OMEMO_URI_PARAM = "omemo-sid-"; public static final String OTR_URI_PARAM = "otr-fingerprint"; + public static final String ACTION_JOIN = "join"; + public static final String ACTION_MESSAGE = "message"; + public XmppUri(String uri) { try { parse(Uri.parse(uri)); @@ -63,11 +66,21 @@ public class XmppUri { // sample : https://conversations.im/i/foo/bar.com jid = segments.get(1) + "@" + segments.get(2); } - muc = segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0)); + if (segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0))) { + action = ACTION_JOIN; + } fingerprints = parseFingerprints(uri.getQuery(),'&'); } else if ("xmpp".equalsIgnoreCase(scheme)) { // sample: xmpp:foo@bar.com - muc = isMuc(uri.getQuery()); + + final String query = uri.getQuery(); + + if (hasAction(query, ACTION_JOIN)) { + this.action = ACTION_JOIN; + } else if (hasAction(query, ACTION_MESSAGE)) { + this.action = ACTION_MESSAGE; + } + if (uri.getAuthority() != null) { jid = uri.getAuthority(); } else { @@ -138,16 +151,24 @@ public class XmppUri { return null; } - protected boolean isMuc(String query) { + private boolean hasAction(String query, String action) { for(String pair : query == null ? new String[0] : query.split(";")) { final String[] parts = pair.split("=",2); - if (parts.length == 1 && "join".equals(parts[0])) { + if (parts.length == 1 && parts[0].equals(action)) { return true; } } return false; } + public boolean isAction(final String action) { + if (this.action == null) { + return false; + } + + return this.action.equals(action); + } + public Jid getJid() { try { return this.jid == null ? null :Jid.fromString(this.jid.toLowerCase()); diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index c43801211..1283e6182 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -20,6 +20,7 @@ Mit Unterhaltung teilen Unterhaltung beginnen Kontakt auswählen + Über Account teilen Sperrliste gerade vor einer Minute diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 5c38e9afb..7a1f12203 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -21,6 +21,7 @@ Share with Conversation Start Conversation Choose Contact + Share via account Block list just now 1 min ago