handle multiple input URIs and Intent.SEND_MULTIPLE

This commit is contained in:
Vincent Breitmoser 2015-06-18 03:10:59 +02:00
parent f978aca8e5
commit c11fef6e7c
6 changed files with 96 additions and 54 deletions

View File

@ -210,15 +210,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- Android's Send Action -->
<intent-filter android:label="@string/intent_send_decrypt">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
<data android:mimeType="message/*" />
</intent-filter>
</activity>
<activity
android:name=".ui.DecryptFilesActivity"
@ -266,13 +257,15 @@
<data android:scheme="file" />
<data android:scheme="content" />
</intent-filter>
<!-- Android's Send Action -->
<!-- Android's Send and Multi-Send Actions -->
<intent-filter android:label="@string/intent_send_decrypt">
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<!-- everything except text/* and message/* -->
<data android:mimeType="text/*" />
<data android:mimeType="message/*" />
<data android:mimeType="image/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="video/*" />

View File

@ -23,6 +23,8 @@ import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.Toast;
@ -65,56 +67,83 @@ public class DecryptFilesActivity extends BaseActivity {
* Handles all actions with this intent
*/
private void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction();
String type = intent.getType();
Uri uri = intent.getData();
if (Intent.ACTION_SEND.equals(action) && type != null) {
// When sending to Keychain Decrypt via share menu
// Binary via content provider (could also be files)
// override uri to get stream from send
uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
action = ACTION_DECRYPT_DATA;
} else if (Intent.ACTION_VIEW.equals(action)) {
// Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
// override action
action = ACTION_DECRYPT_DATA;
}
// No need to initialize fragments if we are being restored
// No need to initialize fragments if we are just being restored
if (savedInstanceState != null) {
return;
}
// Definitely need a data uri with the decrypt_data intent
if (ACTION_DECRYPT_DATA.equals(action) && uri == null) {
Toast.makeText(this, "No data to decrypt!", Toast.LENGTH_LONG).show();
setResult(Activity.RESULT_CANCELED);
finish();
ArrayList<Uri> uris = new ArrayList<>();
String action = intent.getAction();
switch (action) {
case Intent.ACTION_SEND: {
// When sending to Keychain Decrypt via share menu
// Binary via content provider (could also be files)
// override uri to get stream from send
action = ACTION_DECRYPT_DATA;
uris.add(intent.<Uri>getParcelableExtra(Intent.EXTRA_STREAM));
break;
}
case Intent.ACTION_SEND_MULTIPLE: {
action = ACTION_DECRYPT_DATA;
uris.addAll(intent.<Uri>getParcelableArrayListExtra(Intent.EXTRA_STREAM));
break;
}
case Intent.ACTION_VIEW:
// Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
action = ACTION_DECRYPT_DATA;
// fallthrough
default:
uris.add(intent.getData());
}
if (ACTION_DECRYPT_DATA.equals(action)) {
// Definitely need a data uri with the decrypt_data intent
if (uris.isEmpty()) {
Toast.makeText(this, "No data to decrypt!", Toast.LENGTH_LONG).show();
setResult(Activity.RESULT_CANCELED);
finish();
}
displayListFragment(uris);
return;
}
boolean showOpenDialog = ACTION_DECRYPT_DATA_OPEN.equals(action);
DecryptFilesInputFragment frag = DecryptFilesInputFragment.newInstance(uri, showOpenDialog);
displayInputFragment(showOpenDialog);
}
public void displayInputFragment(boolean showOpenDialog) {
DecryptFilesInputFragment frag = DecryptFilesInputFragment.newInstance(showOpenDialog);
// Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
getSupportFragmentManager().beginTransaction()
.replace(R.id.decrypt_files_fragment_container, frag)
.commit();
}
public void displayListFragment(Uri inputUri) {
public void displayListFragment(ArrayList<Uri> inputUris) {
ArrayList<Uri> uris = new ArrayList<>();
uris.add(inputUri);
DecryptFilesListFragment frag = DecryptFilesListFragment.newInstance(uris);
DecryptFilesListFragment frag = DecryptFilesListFragment.newInstance(inputUris);
getSupportFragmentManager().beginTransaction()
.replace(R.id.decrypt_files_fragment_container, frag)
.addToBackStack("list")
.commit();
FragmentManager fragMan = getSupportFragmentManager();
FragmentTransaction trans = fragMan.beginTransaction();
trans.replace(R.id.decrypt_files_fragment_container, frag);
// if there already is a fragment, allow going back to that. otherwise, we're top level!
if (fragMan.getFragments() != null && !fragMan.getFragments().isEmpty()) {
trans.addToBackStack("list");
}
trans.commit();
}

View File

@ -18,6 +18,8 @@
package org.sufficientlysecure.keychain.ui;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
@ -44,11 +46,10 @@ public class DecryptFilesInputFragment extends Fragment {
private Uri mInputUri = null;
public static DecryptFilesInputFragment newInstance(Uri uri, boolean openDirectly) {
public static DecryptFilesInputFragment newInstance(boolean openDirectly) {
DecryptFilesInputFragment frag = new DecryptFilesInputFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_URI, uri);
args.putBoolean(ARG_OPEN_DIRECTLY, openDirectly);
frag.setArguments(args);
@ -127,7 +128,10 @@ public class DecryptFilesInputFragment extends Fragment {
}
DecryptFilesActivity activity = (DecryptFilesActivity) getActivity();
activity.displayListFragment(mInputUri);
ArrayList<Uri> uris = new ArrayList<>();
uris.add(mInputUri);
activity.displayListFragment(uris);
}
@Override

View File

@ -58,6 +58,7 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
// this import NEEDS to be above the ViewModel one, or it won't compile! (as of 06/06/15)
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.StatusHolder;
import org.sufficientlysecure.keychain.ui.DecryptFilesListFragment.DecryptFilesAdapter.ViewModel;
import org.sufficientlysecure.keychain.ui.adapter.SpacesItemDecoration;
@ -187,6 +188,11 @@ public class DecryptFilesListFragment
cryptoOperation();
}
@Override
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
super.cryptoOperation(cryptoInput, false);
}
@Override
protected boolean onCryptoSetProgress(String msg, int progress, int max) {
mAdapter.setProgress(mCurrentInputUri, progress, max, msg);
@ -204,6 +210,8 @@ public class DecryptFilesListFragment
mCurrentInputUri = null;
mAdapter.addResult(uri, result, null, null, null);
cryptoOperation();
}
@Override
@ -257,6 +265,8 @@ public class DecryptFilesListFragment
mAdapter.addResult(uri, result, icon, onFileClick, onKeyClick);
cryptoOperation();
}
@Override

View File

@ -123,6 +123,14 @@ public abstract class CryptoOperationFragment <T extends Parcelable, S extends O
protected abstract T createOperationInput();
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
cryptoOperation(cryptoInput, true);
}
protected void cryptoOperation() {
cryptoOperation(new CryptoInputParcel());
}
protected void cryptoOperation(CryptoInputParcel cryptoInput, boolean showProgress) {
T operationInput = createOperationInput();
if (operationInput == null) {
@ -169,18 +177,16 @@ public abstract class CryptoOperationFragment <T extends Parcelable, S extends O
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(
getString(R.string.progress_building_key),
ProgressDialog.STYLE_HORIZONTAL, false);
if (showProgress) {
saveHandler.showProgressDialog(
getString(R.string.progress_building_key),
ProgressDialog.STYLE_HORIZONTAL, false);
}
getActivity().startService(intent);
}
protected void cryptoOperation() {
cryptoOperation(new CryptoInputParcel());
}
protected void onCryptoOperationResult(S result) {
if (result.success()) {
onCryptoOperationSuccess(result);

View File

@ -5,7 +5,7 @@
<include
android:id="@+id/toolbar_include"
layout="@layout/toolbar_result_decrypt" />
layout="@layout/toolbar_standalone_white" />
<!--
fitsSystemWindows and layout_marginTop from