display geo uris as location. show 'send loction' in share menu if request location intent can be resolved
This commit is contained in:
parent
cbca92d209
commit
87a048fe6f
|
@ -8,6 +8,7 @@ import java.net.URL;
|
|||
import java.util.Arrays;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.utils.GeoHelper;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
|
||||
|
@ -49,6 +50,7 @@ public class Message extends AbstractEntity {
|
|||
public static final String RELATIVE_FILE_PATH = "relativeFilePath";
|
||||
public static final String ME_COMMAND = "/me ";
|
||||
|
||||
|
||||
public boolean markable = false;
|
||||
protected String conversationUuid;
|
||||
protected Jid counterpart;
|
||||
|
@ -368,6 +370,8 @@ public class Message extends AbstractEntity {
|
|||
this.getCounterpart() != null &&
|
||||
this.getCounterpart().equals(message.getCounterpart()) &&
|
||||
(message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) &&
|
||||
!GeoHelper.isGeoUri(message.getBody()) &&
|
||||
!GeoHelper.isGeoUri(this.body) &&
|
||||
!message.bodyContainsDownloadable() &&
|
||||
!this.bodyContainsDownloadable() &&
|
||||
!message.getBody().startsWith(ME_COMMAND) &&
|
||||
|
|
|
@ -306,6 +306,24 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
return this.mAvatarService;
|
||||
}
|
||||
|
||||
public void attachLocationToConversation(final Conversation conversation,
|
||||
final Uri uri,
|
||||
final UiCallback<Message> callback) {
|
||||
int encryption = conversation.getNextEncryption(forceEncryption());
|
||||
if (encryption == Message.ENCRYPTION_PGP) {
|
||||
encryption = Message.ENCRYPTION_DECRYPTED;
|
||||
}
|
||||
Message message = new Message(conversation,uri.toString(),encryption);
|
||||
if (conversation.getNextCounterpart() != null) {
|
||||
message.setCounterpart(conversation.getNextCounterpart());
|
||||
}
|
||||
if (encryption == Message.ENCRYPTION_DECRYPTED) {
|
||||
getPgpEngine().encrypt(message,callback);
|
||||
} else {
|
||||
callback.success(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void attachFileToConversation(final Conversation conversation,
|
||||
final Uri uri,
|
||||
final UiCallback<Message> callback) {
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Blockable;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
|
@ -63,6 +62,7 @@ public class ConversationActivity extends XmppActivity
|
|||
private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
|
||||
private static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303;
|
||||
private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0304;
|
||||
private static final int ATTACHMENT_CHOICE_LOCATION = 0x0305;
|
||||
private static final String STATE_OPEN_CONVERSATION = "state_open_conversation";
|
||||
private static final String STATE_PANEL_OPEN = "state_panel_open";
|
||||
private static final String STATE_PENDING_URI = "state_pending_uri";
|
||||
|
@ -71,6 +71,7 @@ public class ConversationActivity extends XmppActivity
|
|||
private boolean mPanelOpen = true;
|
||||
private Uri mPendingImageUri = null;
|
||||
private Uri mPendingFileUri = null;
|
||||
private Uri mPendingGeoUri = null;
|
||||
|
||||
private View mContentView;
|
||||
|
||||
|
@ -313,7 +314,6 @@ public class ConversationActivity extends XmppActivity
|
|||
menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite());
|
||||
} else {
|
||||
menuMucDetails.setVisible(false);
|
||||
final Account account = this.getSelectedConversation().getAccount();
|
||||
}
|
||||
if (this.getSelectedConversation().isMuted()) {
|
||||
menuMute.setVisible(false);
|
||||
|
@ -325,50 +325,60 @@ public class ConversationActivity extends XmppActivity
|
|||
return true;
|
||||
}
|
||||
|
||||
private void selectPresenceToAttachFile(final int attachmentChoice) {
|
||||
selectPresence(getSelectedConversation(), new OnPresenceSelected() {
|
||||
private void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) {
|
||||
if (attachmentChoice == ATTACHMENT_CHOICE_LOCATION && encryption != Message.ENCRYPTION_OTR) {
|
||||
getSelectedConversation().setNextCounterpart(null);
|
||||
Intent intent = new Intent("eu.siacs.conversations.location.request");
|
||||
startActivityForResult(intent,attachmentChoice);
|
||||
} else {
|
||||
selectPresence(getSelectedConversation(), new OnPresenceSelected() {
|
||||
|
||||
@Override
|
||||
public void onPresenceSelected() {
|
||||
Intent intent = new Intent();
|
||||
boolean chooser = false;
|
||||
switch (attachmentChoice) {
|
||||
case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
chooser = true;
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_TAKE_PHOTO:
|
||||
mPendingImageUri = xmppConnectionService.getFileBackend().getTakePhotoUri();
|
||||
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT,mPendingImageUri);
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_CHOOSE_FILE:
|
||||
chooser = true;
|
||||
intent.setType("*/*");
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_RECORD_VOICE:
|
||||
intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
|
||||
break;
|
||||
}
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
if (chooser) {
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent,getString(R.string.perform_action_with)),
|
||||
attachmentChoice);
|
||||
} else {
|
||||
startActivityForResult(intent, attachmentChoice);
|
||||
@Override
|
||||
public void onPresenceSelected() {
|
||||
Intent intent = new Intent();
|
||||
boolean chooser = false;
|
||||
switch (attachmentChoice) {
|
||||
case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
chooser = true;
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_TAKE_PHOTO:
|
||||
mPendingImageUri = xmppConnectionService.getFileBackend().getTakePhotoUri();
|
||||
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPendingImageUri);
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_CHOOSE_FILE:
|
||||
chooser = true;
|
||||
intent.setType("*/*");
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_RECORD_VOICE:
|
||||
intent.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
|
||||
break;
|
||||
case ATTACHMENT_CHOICE_LOCATION:
|
||||
intent.setAction("eu.siacs.conversations.location.request");
|
||||
break;
|
||||
}
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
if (chooser) {
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent, getString(R.string.perform_action_with)),
|
||||
attachmentChoice);
|
||||
} else {
|
||||
startActivityForResult(intent, attachmentChoice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void attachFile(final int attachmentChoice) {
|
||||
final Conversation conversation = getSelectedConversation();
|
||||
if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
|
||||
final int encryption = conversation.getNextEncryption(forceEncryption());
|
||||
if (encryption == Message.ENCRYPTION_PGP) {
|
||||
if (hasPgp()) {
|
||||
if (conversation.getContact().getPgpKeyId() != 0) {
|
||||
xmppConnectionService.getPgpEngine().hasKey(
|
||||
|
@ -378,13 +388,12 @@ public class ConversationActivity extends XmppActivity
|
|||
@Override
|
||||
public void userInputRequried(PendingIntent pi,
|
||||
Contact contact) {
|
||||
ConversationActivity.this.runIntent(pi,
|
||||
attachmentChoice);
|
||||
ConversationActivity.this.runIntent(pi,attachmentChoice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void success(Contact contact) {
|
||||
selectPresenceToAttachFile(attachmentChoice);
|
||||
selectPresenceToAttachFile(attachmentChoice,encryption);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -406,7 +415,7 @@ public class ConversationActivity extends XmppActivity
|
|||
.setNextEncryption(Message.ENCRYPTION_NONE);
|
||||
xmppConnectionService.databaseBackend
|
||||
.updateConversation(conversation);
|
||||
selectPresenceToAttachFile(attachmentChoice);
|
||||
selectPresenceToAttachFile(attachmentChoice,Message.ENCRYPTION_NONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -414,11 +423,8 @@ public class ConversationActivity extends XmppActivity
|
|||
} else {
|
||||
showInstallPgpDialog();
|
||||
}
|
||||
} else if (getSelectedConversation().getNextEncryption(
|
||||
forceEncryption()) == Message.ENCRYPTION_NONE) {
|
||||
selectPresenceToAttachFile(attachmentChoice);
|
||||
} else {
|
||||
selectPresenceToAttachFile(attachmentChoice);
|
||||
selectPresenceToAttachFile(attachmentChoice,encryption);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,6 +532,9 @@ public class ConversationActivity extends XmppActivity
|
|||
if (new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION).resolveActivity(getPackageManager()) == null) {
|
||||
attachFilePopup.getMenu().findItem(R.id.attach_record_voice).setVisible(false);
|
||||
}
|
||||
if (new Intent("eu.siacs.conversations.location.request").resolveActivity(getPackageManager()) == null) {
|
||||
attachFilePopup.getMenu().findItem(R.id.attach_location).setVisible(false);
|
||||
}
|
||||
attachFilePopup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
|
||||
@Override
|
||||
|
@ -543,6 +552,9 @@ public class ConversationActivity extends XmppActivity
|
|||
case R.id.attach_record_voice:
|
||||
attachFile(ATTACHMENT_CHOICE_RECORD_VOICE);
|
||||
break;
|
||||
case R.id.attach_location:
|
||||
attachFile(ATTACHMENT_CHOICE_LOCATION);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -809,6 +821,7 @@ public class ConversationActivity extends XmppActivity
|
|||
showConversationsOverview();
|
||||
mPendingImageUri = null;
|
||||
mPendingFileUri = null;
|
||||
mPendingGeoUri = null;
|
||||
setSelectedConversation(conversationList.get(0));
|
||||
this.mConversationFragment.reInit(getSelectedConversation());
|
||||
}
|
||||
|
@ -819,6 +832,9 @@ public class ConversationActivity extends XmppActivity
|
|||
} else if (mPendingFileUri != null) {
|
||||
attachFileToConversation(getSelectedConversation(),mPendingFileUri);
|
||||
mPendingFileUri = null;
|
||||
} else if (mPendingGeoUri != null) {
|
||||
attachLocationToConversation(getSelectedConversation(),mPendingGeoUri);
|
||||
mPendingGeoUri = null;
|
||||
}
|
||||
ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
|
||||
setIntent(new Intent());
|
||||
|
@ -897,6 +913,14 @@ public class ConversationActivity extends XmppActivity
|
|||
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
||||
intent.setData(mPendingImageUri);
|
||||
sendBroadcast(intent);
|
||||
} else if (requestCode == ATTACHMENT_CHOICE_LOCATION) {
|
||||
double latitude = data.getDoubleExtra("latitude",0);
|
||||
double longitude = data.getDoubleExtra("longitude",0);
|
||||
this.mPendingGeoUri = Uri.parse("geo:"+String.valueOf(latitude)+","+String.valueOf(longitude));
|
||||
if (xmppConnectionServiceBound) {
|
||||
attachLocationToConversation(getSelectedConversation(), mPendingGeoUri);
|
||||
this.mPendingGeoUri = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
|
||||
|
@ -905,6 +929,26 @@ public class ConversationActivity extends XmppActivity
|
|||
}
|
||||
}
|
||||
|
||||
private void attachLocationToConversation(Conversation conversation, Uri uri) {
|
||||
xmppConnectionService.attachLocationToConversation(conversation,uri, new UiCallback<Message>() {
|
||||
|
||||
@Override
|
||||
public void success(Message message) {
|
||||
xmppConnectionService.sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(int errorCode, Message object) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userInputRequried(PendingIntent pi, Message object) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void attachFileToConversation(Conversation conversation, Uri uri) {
|
||||
prepareFileToast = Toast.makeText(getApplicationContext(),
|
||||
getText(R.string.preparing_file), Toast.LENGTH_LONG);
|
||||
|
|
|
@ -34,6 +34,7 @@ import eu.siacs.conversations.entities.DownloadableFile;
|
|||
import eu.siacs.conversations.entities.Message;
|
||||
import eu.siacs.conversations.entities.Message.ImageParams;
|
||||
import eu.siacs.conversations.ui.ConversationActivity;
|
||||
import eu.siacs.conversations.utils.GeoHelper;
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
|
||||
public class MessageAdapter extends ArrayAdapter<Message> {
|
||||
|
@ -299,6 +300,21 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
|||
viewHolder.download_button.setOnLongClickListener(openContextMenu);
|
||||
}
|
||||
|
||||
private void displayLocationMessage(ViewHolder viewHolder, final Message message) {
|
||||
viewHolder.image.setVisibility(View.GONE);
|
||||
viewHolder.messageBody.setVisibility(View.GONE);
|
||||
viewHolder.download_button.setVisibility(View.VISIBLE);
|
||||
viewHolder.download_button.setText(R.string.show_location);
|
||||
viewHolder.download_button.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showLocation(message);
|
||||
}
|
||||
});
|
||||
viewHolder.download_button.setOnLongClickListener(openContextMenu);
|
||||
}
|
||||
|
||||
private void displayImageMessage(ViewHolder viewHolder,
|
||||
final Message message) {
|
||||
if (viewHolder.download_button != null) {
|
||||
|
@ -509,7 +525,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
|||
} else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
|
||||
displayDecryptionFailed(viewHolder);
|
||||
} else {
|
||||
displayTextMessage(viewHolder, message);
|
||||
if (GeoHelper.isGeoUri(message.getBody())) {
|
||||
displayLocationMessage(viewHolder,message);
|
||||
} else {
|
||||
displayTextMessage(viewHolder, message);
|
||||
}
|
||||
}
|
||||
|
||||
displayStatus(viewHolder, message);
|
||||
|
@ -544,6 +564,16 @@ public class MessageAdapter extends ArrayAdapter<Message> {
|
|||
}
|
||||
}
|
||||
|
||||
public void showLocation(Message message) {
|
||||
for(Intent intent : GeoHelper.createGeoIntentsFromMessage(message)) {
|
||||
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
|
||||
getContext().startActivity(intent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Toast.makeText(activity,R.string.no_application_found_to_display_location,Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
public interface OnContactPictureClicked {
|
||||
public void onContactPictureClicked(Message message);
|
||||
}
|
||||
|
|
71
src/main/java/eu/siacs/conversations/utils/GeoHelper.java
Normal file
71
src/main/java/eu/siacs/conversations/utils/GeoHelper.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.entities.Message;
|
||||
|
||||
public class GeoHelper {
|
||||
private static Pattern GEO_URI = Pattern.compile("geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static boolean isGeoUri(String body) {
|
||||
return body != null && GEO_URI.matcher(body).matches();
|
||||
}
|
||||
|
||||
public static ArrayList<Intent> createGeoIntentsFromMessage(Message message) {
|
||||
final ArrayList<Intent> intents = new ArrayList();
|
||||
Matcher matcher = GEO_URI.matcher(message.getBody());
|
||||
if (!matcher.matches()) {
|
||||
return intents;
|
||||
}
|
||||
double latitude;
|
||||
double longitude;
|
||||
try {
|
||||
latitude = Double.parseDouble(matcher.group(1));
|
||||
if (latitude > 90.0 || latitude < -90.0) {
|
||||
return intents;
|
||||
}
|
||||
longitude = Double.parseDouble(matcher.group(2));
|
||||
if (longitude > 180.0 || longitude < -180.0) {
|
||||
return intents;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
return intents;
|
||||
}
|
||||
final Conversation conversation = message.getConversation();
|
||||
String label;
|
||||
if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) {
|
||||
try {
|
||||
label = "(" + URLEncoder.encode(message.getConversation().getName(), "UTF-8") + ")";
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
label = "";
|
||||
}
|
||||
} else {
|
||||
label = "";
|
||||
}
|
||||
|
||||
Intent locationPluginIntent = new Intent("eu.siacs.conversations.location.show");
|
||||
locationPluginIntent.putExtra("latitude",latitude);
|
||||
locationPluginIntent.putExtra("longitude",longitude);
|
||||
if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) {
|
||||
locationPluginIntent.putExtra("name",conversation.getName());
|
||||
}
|
||||
intents.add(locationPluginIntent);
|
||||
|
||||
Intent geoIntent = new Intent(Intent.ACTION_VIEW);
|
||||
geoIntent.setData(Uri.parse("geo:" + String.valueOf(latitude) + "," + String.valueOf(longitude) + "?q=" + String.valueOf(latitude) + "," + String.valueOf(longitude) + label));
|
||||
intents.add(geoIntent);
|
||||
|
||||
Intent httpIntent = new Intent(Intent.ACTION_VIEW);
|
||||
httpIntent.setData(Uri.parse("https://maps.google.com/maps?q=loc:"+String.valueOf(latitude) + "," + String.valueOf(longitude) +label));
|
||||
intents.add(httpIntent);
|
||||
return intents;
|
||||
}
|
||||
}
|
|
@ -2,14 +2,21 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item
|
||||
android:id="@+id/attach_choose_picture"
|
||||
android:title="@string/attach_choose_picture"/>
|
||||
android:id="@+id/attach_location"
|
||||
android:title="@string/send_location"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/attach_record_voice"
|
||||
android:title="@string/attach_record_voice"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/attach_take_picture"
|
||||
android:title="@string/attach_take_picture"/>
|
||||
<item
|
||||
android:id="@+id/attach_record_voice"
|
||||
android:title="@string/attach_record_voice"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/attach_choose_picture"
|
||||
android:title="@string/attach_choose_picture"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/attach_choose_file"
|
||||
android:title="@string/choose_file"/>
|
||||
|
|
|
@ -449,4 +449,7 @@
|
|||
<string name="contact_has_stopped_typing">%s has stopped typing</string>
|
||||
<string name="pref_chat_states">Typing notifications</string>
|
||||
<string name="pref_chat_states_summary">Let your contact know when you are writing a new message</string>
|
||||
<string name="send_location">Send location</string>
|
||||
<string name="show_location">Show location</string>
|
||||
<string name="no_application_found_to_display_location">No application found to display location</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue