From c3e8fb3446237dee34bf49436076a10d07e2efdf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 6 Dec 2015 18:23:59 +0100 Subject: [PATCH] request storage permission when needed on Android 6.0 --- .../http/HttpDownloadConnection.java | 2 +- .../services/AbstractConnectionManager.java | 11 ++++ .../ui/ConversationActivity.java | 56 ++++++++++++++++++- .../ui/adapter/MessageAdapter.java | 14 +---- .../xmpp/jingle/JingleConnection.java | 3 +- src/main/res/values/strings.xml | 1 + 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index f371a2551..b7bea2e13 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -182,7 +182,7 @@ public class HttpDownloadConnection implements Transferable { return; } file.setExpectedSize(size); - if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) { + if (mHttpConnectionManager.hasStoragePermission() && size <= mHttpConnectionManager.getAutoAcceptFileSize()) { HttpDownloadConnection.this.acceptedAutomatically = true; new Thread(new FileDownloader(interactive)).start(); } else { diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index 5def05dd4..a12562503 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -1,6 +1,9 @@ package eu.siacs.conversations.services; +import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.PowerManager; import android.util.Log; import android.util.Pair; @@ -51,6 +54,14 @@ public class AbstractConnectionManager { } } + public boolean hasStoragePermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return mXmppConnectionService.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + } else { + return true; + } + } + public static Pair createInputStream(DownloadableFile file, boolean gcm) throws FileNotFoundException { FileInputStream is; int size; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 6b85410b9..7129da438 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.ui; +import android.Manifest; import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.AlertDialog; @@ -10,6 +11,7 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentSender.SendIntentException; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -49,6 +51,7 @@ import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; @@ -77,6 +80,7 @@ public class ConversationActivity extends XmppActivity public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207; public static final int REQUEST_TRUST_KEYS_TEXT = 0x0208; public static final int REQUEST_TRUST_KEYS_MENU = 0x0209; + public static final int REQUEST_START_DOWNLOAD = 0x0210; public static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; public static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; public static final int ATTACHMENT_CHOICE_CHOOSE_FILE = 0x0303; @@ -93,6 +97,7 @@ public class ConversationActivity extends XmppActivity final private List mPendingFileUris = new ArrayList<>(); private Uri mPendingGeoUri = null; private boolean forbidProcessingPendings = false; + private Message mPendingDownloadableMessage = null; private boolean conversationWasSelectedByKeyboard = false; @@ -497,6 +502,11 @@ public class ConversationActivity extends XmppActivity } public void attachFile(final int attachmentChoice) { + if (attachmentChoice != ATTACHMENT_CHOICE_LOCATION) { + if (!hasStoragePermission(attachmentChoice)) { + return; + } + } switch (attachmentChoice) { case ATTACHMENT_CHOICE_LOCATION: getPreferences().edit().putString("recently_used_quick_action","location").apply(); @@ -575,7 +585,51 @@ public class ConversationActivity extends XmppActivity } } + public boolean hasStoragePermission(int attachmentChoice) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, attachmentChoice); + return false; + } else { + return true; + } + } else { + return true; + } + } + @Override + public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { + if (grantResults.length > 0) + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (requestCode == REQUEST_START_DOWNLOAD) { + if (this.mPendingDownloadableMessage != null) { + startDownloadable(this.mPendingDownloadableMessage); + } + } else { + attachFile(requestCode); + } + } else { + Toast.makeText(this,R.string.no_storage_permission,Toast.LENGTH_SHORT).show(); + } + } + + public void startDownloadable(Message message) { + if (!hasStoragePermission(ConversationActivity.REQUEST_START_DOWNLOAD)) { + this.mPendingDownloadableMessage = message; + return; + } + Transferable transferable = message.getTransferable(); + if (transferable != null) { + if (!transferable.start()) { + Toast.makeText(this, R.string.not_connected_try_again,Toast.LENGTH_SHORT).show(); + } + } else if (message.treatAsDownloadable() != Message.Decision.NEVER) { + xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, true); + } + } + + @Override public boolean onOptionsItemSelected(final MenuItem item) { if (item.getItemId() == android.R.id.home) { showConversationsOverview(); @@ -1176,7 +1230,7 @@ public class ConversationActivity extends XmppActivity if (downloadUuid != null) { final Message message = mSelectedConversation.findMessageWithFileAndUuid(downloadUuid); if (message != null) { - mConversationFragment.messageListAdapter.startDownloadable(message); + startDownloadable(message); } } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index f9f6e672b..1d906b294 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -352,7 +352,7 @@ public class MessageAdapter extends ArrayAdapter { @Override public void onClick(View v) { - startDownloadable(message); + activity.startDownloadable(message); } }); viewHolder.download_button.setOnLongClickListener(openContextMenu); @@ -602,18 +602,6 @@ public class MessageAdapter extends ArrayAdapter { return view; } - public void startDownloadable(Message message) { - Transferable transferable = message.getTransferable(); - if (transferable != null) { - if (!transferable.start()) { - Toast.makeText(activity, R.string.not_connected_try_again, - Toast.LENGTH_SHORT).show(); - } - } else if (message.treatAsDownloadable() != Message.Decision.NEVER) { - activity.xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message, true); - } - } - public void openDownloadable(Message message) { DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if (!file.exists()) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 59b660c8c..56582f974 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -361,7 +361,8 @@ public class JingleConnection implements Transferable { message.setBody(Long.toString(size)); conversation.add(message); mXmppConnectionService.updateConversationUi(); - if (size < this.mJingleConnectionManager.getAutoAcceptFileSize()) { + if (mJingleConnectionManager.hasStoragePermission() + && size < this.mJingleConnectionManager.getAutoAcceptFileSize()) { Log.d(Config.LOGTAG, "auto accepting file from "+ packet.getFrom()); this.acceptedAutomatically = true; this.sendAccept(); diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index ffbb69ce1..780460400 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -557,4 +557,5 @@ Shared file with %s Shared image with %s + Conversations need access to external storage