anwser to xmpp: style uris. fixed open conversations from android address book

iNPUTmice created

Change summary

AndroidManifest.xml                                            | 10 
src/eu/siacs/conversations/entities/Roster.java                | 13 
src/eu/siacs/conversations/services/XmppConnectionService.java | 21 
src/eu/siacs/conversations/ui/StartConversationActivity.java   | 82 +++
src/eu/siacs/conversations/ui/XmppActivity.java                |  1 
5 files changed, 107 insertions(+), 20 deletions(-)

Detailed changes

AndroidManifest.xml 🔗

@@ -63,6 +63,14 @@
                 <data android:scheme="imto" />
                 <data android:host="jabber" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+
+                <data android:scheme="xmpp" />
+            </intent-filter>
         </activity>
         <activity
             android:name="eu.siacs.conversations.ui.SettingsActivity"
@@ -117,4 +125,4 @@
         <activity android:name="de.duenndns.ssl.MemorizingActivity" />
     </application>
 
-</manifest>
+</manifest>

src/eu/siacs/conversations/entities/Roster.java 🔗

@@ -14,13 +14,18 @@ public class Roster {
 		this.account = account;
 	}
 
-	public boolean hasContact(String jid) {
-		String cleanJid = jid.split("/",2)[0];
-		return contacts.containsKey(cleanJid);
+	public Contact getContactAsShownInRoster(String jid) {
+		String cleanJid = jid.split("/", 2)[0];
+		Contact contact = contacts.get(cleanJid);
+		if (contact != null && contact.showInRoster()) {
+			return contact;
+		} else {
+			return null;
+		}
 	}
 
 	public Contact getContact(String jid) {
-		String cleanJid = jid.split("/",2)[0].toLowerCase(Locale.getDefault());
+		String cleanJid = jid.split("/", 2)[0].toLowerCase(Locale.getDefault());
 		if (contacts.containsKey(cleanJid)) {
 			return contacts.get(cleanJid);
 		} else {

src/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -824,7 +824,7 @@ public class XmppConnectionService extends Service {
 			}
 		});
 	}
-	
+
 	public int loadMoreMessages(Conversation conversation, long timestamp) {
 		List<Message> messages = databaseBackend.getMessages(conversation, 50,
 				timestamp);
@@ -851,8 +851,9 @@ public class XmppConnectionService extends Service {
 	public Conversation find(List<Conversation> haystack, Account account,
 			String jid) {
 		for (Conversation conversation : haystack) {
-			if ((conversation.getAccount().equals(account))
-					&& (conversation.getContactJid().split("/",2)[0].equals(jid))) {
+			if ((account == null || conversation.getAccount().equals(account))
+					&& (conversation.getContactJid().split("/", 2)[0]
+							.equals(jid))) {
 				return conversation;
 			}
 		}
@@ -1742,4 +1743,18 @@ public class XmppConnectionService extends Service {
 	public interface OnRosterUpdate {
 		public void onRosterUpdate();
 	}
+
+	public List<Contact> findContacts(String jid) {
+		ArrayList<Contact> contacts = new ArrayList<Contact>();
+		for (Account account : getAccounts()) {
+			if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+				Contact contact = account.getRoster()
+						.getContactAsShownInRoster(jid);
+				if (contact != null) {
+					contacts.add(contact);
+				}
+			}
+		}
+		return contacts;
+	}
 }

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

@@ -1,5 +1,7 @@
 package eu.siacs.conversations.ui;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -14,6 +16,8 @@ import android.app.ListFragment;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.support.v13.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
@@ -157,6 +161,8 @@ public class StartConversationActivity extends XmppActivity {
 			});
 		}
 	};
+	private MenuItem mMenuSearchView;
+	private String mInitialJid;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
@@ -308,7 +314,7 @@ public class StartConversationActivity extends XmppActivity {
 
 	}
 
-	protected void showCreateContactDialog() {
+	protected void showCreateContactDialog(String prefilledJid) {
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
 		builder.setTitle(R.string.create_contact);
 		View dialogView = getLayoutInflater().inflate(
@@ -317,7 +323,10 @@ public class StartConversationActivity extends XmppActivity {
 		final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView
 				.findViewById(R.id.jid);
 		jid.setAdapter(new KnownHostsAdapter(this,
-				android.R.layout.simple_list_item_1, mKnownHosts));
+					android.R.layout.simple_list_item_1, mKnownHosts));
+		if (prefilledJid!=null) {
+			jid.append(prefilledJid);
+		}
 		populateAccountSpinner(spinner);
 		builder.setView(dialogView);
 		builder.setNegativeButton(R.string.cancel, null);
@@ -449,9 +458,9 @@ public class StartConversationActivity extends XmppActivity {
 				.findItem(R.id.action_create_contact);
 		MenuItem menuCreateConference = (MenuItem) menu
 				.findItem(R.id.action_join_conference);
-		MenuItem menuSearchView = (MenuItem) menu.findItem(R.id.action_search);
-		menuSearchView.setOnActionExpandListener(mOnActionExpandListener);
-		View mSearchView = menuSearchView.getActionView();
+		mMenuSearchView = (MenuItem) menu.findItem(R.id.action_search);
+		mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
+		View mSearchView = mMenuSearchView.getActionView();
 		mSearchEditText = (EditText) mSearchView
 				.findViewById(R.id.search_field);
 		mSearchEditText.addTextChangedListener(mSearchTextWatcher);
@@ -460,6 +469,11 @@ public class StartConversationActivity extends XmppActivity {
 		} else {
 			menuCreateContact.setVisible(false);
 		}
+		if (mInitialJid != null) {
+			mMenuSearchView.expandActionView();
+			mSearchEditText.append(mInitialJid);
+			filter(mInitialJid);
+		}
 		return true;
 	}
 
@@ -467,7 +481,7 @@ public class StartConversationActivity extends XmppActivity {
 	public boolean onOptionsItemSelected(MenuItem item) {
 		switch (item.getItemId()) {
 		case R.id.action_create_contact:
-			showCreateContactDialog();
+			showCreateContactDialog(null);
 			break;
 		case R.id.action_join_conference:
 			showJoinConferenceDialog();
@@ -486,13 +500,8 @@ public class StartConversationActivity extends XmppActivity {
 	}
 
 	@Override
-	void onBackendConnected() {
+	protected void onBackendConnected() {
 		xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate);
-		if (mSearchEditText != null) {
-			filter(mSearchEditText.getText().toString());
-		} else {
-			filter(null);
-		}
 		this.mActivatedAccounts.clear();
 		for (Account account : xmppConnectionService.getAccounts()) {
 			if (account.getStatus() != Account.STATUS_DISABLED) {
@@ -502,6 +511,55 @@ public class StartConversationActivity extends XmppActivity {
 		this.mKnownHosts = xmppConnectionService.getKnownHosts();
 		this.mKnownConferenceHosts = xmppConnectionService
 				.getKnownConferenceHosts();
+		if (!startByIntent()) {
+			if (mSearchEditText != null) {
+				filter(mSearchEditText.getText().toString());
+			} else {
+				filter(null);
+			}
+		}
+	}
+
+	protected boolean startByIntent() {
+		if (getIntent() != null
+				&& Intent.ACTION_SENDTO.equals(getIntent().getAction())) {
+			try {
+				String jid = URLDecoder.decode(
+						getIntent().getData().getEncodedPath(), "UTF-8").split(
+						"/")[1];
+				setIntent(null);
+				return handleJid(jid);
+			} catch (UnsupportedEncodingException e) {
+				setIntent(null);
+				return false;
+			}
+		} else if (getIntent() != null && Intent.ACTION_VIEW.equals(getIntent().getAction())) {
+			Uri uri = getIntent().getData();
+			String jid = uri.getSchemeSpecificPart().split("\\?")[0];
+			return handleJid(jid);
+		}
+		return false;
+	}
+
+	private boolean handleJid(String jid) {
+		List<Contact> contacts = xmppConnectionService
+				.findContacts(jid);
+		if (contacts.size() == 0) {
+			showCreateContactDialog(jid);
+			return false;
+		} else if (contacts.size() == 1) {
+			switchToConversation(contacts.get(0));
+			return true;
+		} else {
+			if (mMenuSearchView != null) {
+				mMenuSearchView.expandActionView();
+				mSearchEditText.setText(jid);
+				filter(jid);
+			} else {
+				mInitialJid = jid;
+			}
+			return true;
+		}
 	}
 
 	protected void filter(String needle) {

src/eu/siacs/conversations/ui/XmppActivity.java 🔗

@@ -245,6 +245,7 @@ public abstract class XmppActivity extends Activity {
 					| Intent.FLAG_ACTIVITY_CLEAR_TOP);
 		}
 		startActivity(viewConversationIntent);
+		finish();
 	}
 
 	public void switchToContactDetails(Contact contact) {