From 09741b02863b138846f3747a19dc40a3518b9aa0 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Sat, 17 Apr 2010 23:36:47 +0000 Subject: [PATCH] use OI File Manager intents to handle open/save file selection --- res/drawable/ic_launcher_folder.png | Bin 0 -> 2235 bytes res/drawable/ic_launcher_folder_small.png | Bin 0 -> 1522 bytes res/layout/file_dialog.xml | 35 ++++++++ res/values/strings.xml | 7 ++ src/org/openintents/intents/FileManager.java | 78 ++++++++++++++++++ .../thialfihar/android/apg/FileDialog.java | 73 ++++++++++++++-- .../thialfihar/android/apg/MainActivity.java | 6 +- .../android/apg/PublicKeyListActivity.java | 48 +++++++++-- .../android/apg/SecretKeyListActivity.java | 36 ++++++-- 9 files changed, 261 insertions(+), 22 deletions(-) create mode 100644 res/drawable/ic_launcher_folder.png create mode 100644 res/drawable/ic_launcher_folder_small.png create mode 100644 res/layout/file_dialog.xml create mode 100644 src/org/openintents/intents/FileManager.java diff --git a/res/drawable/ic_launcher_folder.png b/res/drawable/ic_launcher_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..ed31ba580aafcebf2601d4136f4d0fc93b6b077f GIT binary patch literal 2235 zcmV;s2t@aZP)+4b6ci8naw zyS={7+KB@c%tKY4(n4R5TB${)fItW$)Rsu7?GuPcf`pRhi9YqBqN+#`q_%1y5)#k{ z)J7zc6G9TeF;1|9@9W*zd*9*vXV3ATnVsGBI*m$2M*e-y&d!|qzW;t^71K1?|MQ{T zB5;eqH=Ka(cJkR@{@NOchlkm|y?dFWs!UOoEm6f>rBSt?+d8kXE3;SF^ySN}SS(sn zC=?hJrra|*`H;u!`FX$}=nn+^*K|$4gv-z2IUnM_laQosJxD_YZsO4mFn{^*)Tw(d zfKZI4Y2CqK@a|oq5NmC1WuZ{0*xI`5iod1hB(DD}+;hLoV?7BIFrO zRSyHGuNrXYT#l*bl@$g8lWqj!@wknE2ckjJk39TS_PgKz;W4#zlphGm=5lOpb=A6A z<>&ByJFL_m35n!xQzp)w)lvX=XI+kmgHv!h3juvcIG(-wiB zAv+ww=)+B4#Ej8%5B=o9eKRw&Y;kFctw0NuL1ZHGoE}7g*RgOSnUsP0;BsY9GWc3n zkfea@g~=WP{_NBgJ9zLZHak08ssov9_5ob@XUv0J#liZ=7b(XBTU(2>wfGuYCBn@aFBi6zP1$|kRmM+krl)XS&lwaF;li-0onS9A@;31?>OJp)j1(_Ys*5= z;EWTX%XJcPlU3_J!qm!9TCW)`E z(`}S3i4ZJM+<~c-Y;DpwlfK3tdu0Y)yMbi;mzUF4u4C(CbK<_og{{5em zER)IFdLU#tEfR@*=jzp~3%qEO!oP&9>HHxmI_6!a2RL2DNyJWquBlYCyBi8XPGa<_ zh+y?LHLhJ)X4`+)l=M10x7If3A*0r>cL+xwu(iQ z?b*}DJRXl#cLWK-hi0ofAt7ObGi5L`Fz4KqKq(@*xByXXq#KDXs=O2v>&Q^T0(1^p z&Eqg9b;t?@F`b~`Sb)~r?b@$4cenCL@aLh1bW9^X$SxQkIgvzm1nk(F5v@;_&T3T9M|ODq_rXGGeEs zB@>Bjr%#{y6!H(ghxLWS;kMzC5m+fU0nal=VY1uW+PVY*jax^KE&9=8Zf@=x?qB9E zbY1?fLSZ-OP^58-6c;al6HcU>!{Oa+ef|9uPey-#bYuX*)!WzC7YGExWRXlJ&0cu^ zxtGtJIsGQC|BSy@$=_@O^@we`9~Tc7pOB7@jvg3jVhG2Hx8FWKKR@>occHA?g8$QB zN*$I`xoZnj3J0AM#p~-vpq~4QxHH{eEZzE{`xb$3I)SeQ7y$Kg(&S@+2i5=p002ov JPDHLkV1mb;N+AFM literal 0 HcmV?d00001 diff --git a/res/drawable/ic_launcher_folder_small.png b/res/drawable/ic_launcher_folder_small.png new file mode 100644 index 0000000000000000000000000000000000000000..5df8d60f04bcd636d11402840ef9cccaf4aad404 GIT binary patch literal 1522 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOb; z5DW@B*yK0>00nYML_t(o!|j(%Y+P3r$A9PE`{w(N$JkErIH{f3b!@5>B`9eTin@Xg z5+GJ=sVae#3YMq{RTV6%Dyk|rY*fDfxvtS2|*lJkf>5iL}Hxr*UWf6 zJn!AZV%{5%$2Lt-5Sw1<>fZPC-aWtbKj(hIhvolVXRdwfp^V>n^|hR;z6e~m#*~e6A*v zJChR=KP(oDuUD(n5B?*-%dgz1OifNcTNxk!c%@Rgo6qHL8)N<3EH3pMZ7X&*v4t<=>pMw?*XU#>U2bo3+j7#F%HSF~$rTO{*mB&hBo0 zuhqH+90pL;kE-g|fH_rt=gqf%^4WX;yvNq|HUdOZM16OcX0wSkrjW^IFK4sa%Rvx) zDT*TRg1`)WETa%2{r4gOQ=^Kz{a)_{5xEXnfG>Rha|jT}F^xu(t?e!9^#(gTJM8VX zXm{FlI$gTmE=I(-Oy*dRhYcHJu+|`Asz(4+bwX7w{TQICNp=WfIix&RPU(rFh<3X} zr_-U?=tI>uH>uYfL{W4ifEa^_0d)L0fVTk!L={9vb5sXV#u!SaBBfH1$;k->5MuzS z*Xz`G>um4r&~CNqbUU=$9pX41K&a|z=iF2jMQxx1#Lj#FS6~k)^%XcUE}|R=(kDw{ zL<9whV*rZ9BBfG^nKLu^IHud}(r7eUy|sq-9udLEK3^`EuWfB@Z2)(H2PTf=dvWa7 zUg_SeVCJi?x5P%1Y<4PY=%y!i&v#sEV(4P91ysPkBs*o)M|IqMR9oWM*?63YaL>GsCuk5>6aep zx&HKue+7K={f&R{76j*Pe?F;_FBDt?un#mHfcO4Ss@f8f!U4d;C?dxya_FCA`ie+@ zHYDkh0JI&zOm({P?t6FN5aG+Ify0K6@1JON2(-Td^%pVkeHtfCrhX%pgE)?U3i3q} z#!~M_L5AUuH+&Sr81P=%-#>IDP@p+bAjyN@sp=m^*4*-^z78Q8&w=2JY zL5%rECJ4rDa<~}mbOU8ZD??yM70Lt|x}7d!gzfF^7SI5;fXI#RPPcBYeJ_{G-tk_a zpPrt+TqqXCoV8fz21}|v0ctoGhQTtK3{ezeon?1-cMqs1IS?NK`07`lYXENnKMR5& zys)(V#Ny)O;-yQMFP=Mh{+x66tP6t4%2?%8HkZx01k4?ymN5q*3(Fzv>+7vXqfrOe z69AQmI5pdJ*$jdpx3si8y?Eh5b$R(?=Yt@aFO|Ye)79$2=~Ji9T4!<2VU5K(J5bCR z!@c|WSy@@R|LvDv{1)&B;P1yOFjCTtjet(C*K4k>-rQVWy}6b^IUon*X6NQ+E?#`{ ziK|zix->U;Zr)f^4V)Vf!*C*BC=^7*H0t$tfp>uWK>R4~1u~+P1v2@3A^-T|;`Hq7 z?CFJt$7jMYoUzV5xpr&yFF$_cN3R3_N}PIh7n5U(84Y2w0ku=(|7(Dg?jQQ$g><<5 Y8^FyV#?4~7fdBvi07*qoM6N<$f={f|vj6}9 literal 0 HcmV?d00001 diff --git a/res/layout/file_dialog.xml b/res/layout/file_dialog.xml new file mode 100644 index 000000000..6804ecaba --- /dev/null +++ b/res/layout/file_dialog.xml @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 5e6bd5fba..20eb5476d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -65,5 +65,12 @@ Using clipboard content. Key saved. Set a pass phrase via the option menu first. + + OI File Manager not installed. + Open... + Open + Save As... + Save + diff --git a/src/org/openintents/intents/FileManager.java b/src/org/openintents/intents/FileManager.java new file mode 100644 index 000000000..3a5cc0d86 --- /dev/null +++ b/src/org/openintents/intents/FileManager.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 OpenIntents.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.intents; + +// Version Dec 9, 2008 + +/** + * Provides OpenIntents actions, extras, and categories used by providers. + *

+ * These specifiers extend the standard Android specifiers. + *

+ */ +public final class FileManager { + + /** + * Activity Action: Pick a file through the file manager, or let user + * specify a custom file name. Data is the current file name or file name + * suggestion. Returns a new file name as file URI in data. + * + *

+ * Constant Value: "org.openintents.action.PICK_FILE" + *

+ */ + public static final String ACTION_PICK_FILE = "org.openintents.action.PICK_FILE"; + + /** + * Activity Action: Pick a directory through the file manager, or let user + * specify a custom file name. Data is the current directory name or + * directory name suggestion. Returns a new directory name as file URI in + * data. + * + *

+ * Constant Value: "org.openintents.action.PICK_DIRECTORY" + *

+ */ + public static final String ACTION_PICK_DIRECTORY = "org.openintents.action.PICK_DIRECTORY"; + + /** + * The title to display. + * + *

+ * This is shown in the title bar of the file manager. + *

+ * + *

+ * Constant Value: "org.openintents.extra.TITLE" + *

+ */ + public static final String EXTRA_TITLE = "org.openintents.extra.TITLE"; + + /** + * The text on the button to display. + * + *

+ * Depending on the use, it makes sense to set this to "Open" or "Save". + *

+ * + *

+ * Constant Value: "org.openintents.extra.BUTTON_TEXT" + *

+ */ + public static final String EXTRA_BUTTON_TEXT = "org.openintents.extra.BUTTON_TEXT"; + +} diff --git a/src/org/thialfihar/android/apg/FileDialog.java b/src/org/thialfihar/android/apg/FileDialog.java index a1662bea4..c2e7ec4b3 100644 --- a/src/org/thialfihar/android/apg/FileDialog.java +++ b/src/org/thialfihar/android/apg/FileDialog.java @@ -16,34 +16,66 @@ package org.thialfihar.android.apg; +import org.openintents.intents.FileManager; + +import android.app.Activity; import android.app.AlertDialog; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.view.LayoutInflater; +import android.view.View; import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.Toast; public class FileDialog { + public static final int REQUEST_CODE_PICK_FILE_OR_DIRECTORY = 12345; + private static EditText mInput; + private static ImageButton mBrowse; + private static Activity mActivity; + private static String mFileManagerTitle; + private static String mFileManagerButton; public static interface OnClickListener { public void onCancelClick(); public void onOkClick(String filename); } - public static AlertDialog build(Context context, String title, String message, - String defaultFile, OnClickListener onClickListener) { - AlertDialog.Builder alert = new AlertDialog.Builder(context); + public static AlertDialog build(Activity activity, String title, String message, + String defaultFile, OnClickListener onClickListener, + String fileManagerTitle, String fileManagerButton) { + LayoutInflater inflater = + (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + AlertDialog.Builder alert = new AlertDialog.Builder(activity); alert.setTitle(title); alert.setMessage(message); - final EditText input = new EditText(context); - input.setText(defaultFile); - alert.setView(input); + View view = (View) inflater.inflate(R.layout.file_dialog, null); + + mActivity = activity; + mInput = (EditText) view.findViewById(R.id.input); + mInput.setText(defaultFile); + mBrowse = (ImageButton) view.findViewById(R.id.btn_browse); + mBrowse.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openFile(); + } + }); + mFileManagerTitle = fileManagerTitle; + mFileManagerButton = fileManagerButton; + + alert.setView(view); final OnClickListener clickListener = onClickListener; alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - clickListener.onOkClick(input.getText().toString()); + clickListener.onOkClick(mInput.getText().toString()); } }); @@ -55,4 +87,31 @@ public class FileDialog { }); return alert.create(); } + + public static void setFilename(String filename) { + if (mInput != null) { + mInput.setText(filename); + } + } + + /** + * Opens the file manager to select a file to open. + */ + private static void openFile() { + String fileName = mInput.getText().toString(); + + Intent intent = new Intent(FileManager.ACTION_PICK_FILE); + + intent.setData(Uri.parse("file://" + fileName)); + + intent.putExtra(FileManager.EXTRA_TITLE, mFileManagerTitle); + intent.putExtra(FileManager.EXTRA_BUTTON_TEXT, mFileManagerButton); + + try { + mActivity.startActivityForResult(intent, REQUEST_CODE_PICK_FILE_OR_DIRECTORY); + } catch (ActivityNotFoundException e) { + // No compatible file manager was found. + Toast.makeText(mActivity, R.string.no_filemanager_installed, Toast.LENGTH_SHORT).show(); + } + } } diff --git a/src/org/thialfihar/android/apg/MainActivity.java b/src/org/thialfihar/android/apg/MainActivity.java index 531441c1d..1c0361dec 100644 --- a/src/org/thialfihar/android/apg/MainActivity.java +++ b/src/org/thialfihar/android/apg/MainActivity.java @@ -72,6 +72,8 @@ public class MainActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.main); + Apg.initialize(this); + Button encryptMessageButton = (Button) findViewById(R.id.btn_encryptMessage); Button decryptMessageButton = (Button) findViewById(R.id.btn_decryptMessage); mAccounts = (ListView) findViewById(R.id.account_list); @@ -220,9 +222,7 @@ public class MainActivity extends Activity { SpannableString info = new SpannableString("Read the warnings!\n\n" + "Changes:\n" + - " * display signed-only mails\n" + - " * verify signed-only mails\n" + - " * bug fixes, layout fixes\n" + + " * OI File Manager support\n" + "\n" + "WARNING: be careful editing your existing keys, as they " + "WILL be stripped of certificates right now.\n" + diff --git a/src/org/thialfihar/android/apg/PublicKeyListActivity.java b/src/org/thialfihar/android/apg/PublicKeyListActivity.java index 50fe7422a..1e4dc081d 100644 --- a/src/org/thialfihar/android/apg/PublicKeyListActivity.java +++ b/src/org/thialfihar/android/apg/PublicKeyListActivity.java @@ -31,10 +31,13 @@ import android.app.ExpandableListActivity; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; +import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; @@ -72,13 +75,14 @@ public class PublicKeyListActivity extends ExpandableListActivity static final int TASK_EXPORT = 2; protected int mSelectedItem = -1; - protected String mImportFilename = null; - protected String mExportFilename = null; protected int mTask = 0; private ProgressDialog mProgressDialog = null; private Thread mRunningThread = null; + private String mImportFilename = Environment.getExternalStorageDirectory() + "/pubring.gpg"; + private String mExportFilename = Environment.getExternalStorageDirectory() + "/pubexport.asc"; + private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -301,7 +305,7 @@ public class PublicKeyListActivity extends ExpandableListActivity case DIALOG_IMPORT_KEYS: { return FileDialog.build(this, "Import Keys", "Please specify which file to import from.", - Environment.getExternalStorageDirectory() + "/pubring.gpg", + mImportFilename, new FileDialog.OnClickListener() { @Override @@ -315,7 +319,9 @@ public class PublicKeyListActivity extends ExpandableListActivity public void onCancelClick() { removeDialog(DIALOG_IMPORT_KEYS); } - }); + }, + getString(R.string.filemanager_title_open), + getString(R.string.filemanager_btn_open)); } case DIALOG_EXPORT_KEY: { @@ -335,7 +341,7 @@ public class PublicKeyListActivity extends ExpandableListActivity return FileDialog.build(this, title, "Please specify which file to export to.\n" + "WARNING! File will be overwritten if it exists.", - Environment.getExternalStorageDirectory() + "/pubexport.asc", + mExportFilename, new FileDialog.OnClickListener() { @Override @@ -349,7 +355,9 @@ public class PublicKeyListActivity extends ExpandableListActivity public void onCancelClick() { removeDialog(thisDialogId); } - }); + }, + getString(R.string.filemanager_title_save), + getString(R.string.filemanager_btn_save)); } case DIALOG_IMPORTING: { @@ -621,4 +629,32 @@ public class PublicKeyListActivity extends ExpandableListActivity return view; } } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case FileDialog.REQUEST_CODE_PICK_FILE_OR_DIRECTORY: { + if (resultCode == RESULT_OK && data != null) { + String filename = data.getDataString(); + if (filename != null) { + // Get rid of URI prefix: + if (filename.startsWith("file://")) { + filename = filename.substring(7); + } + // replace %20 and so on + filename = Uri.decode(filename); + + FileDialog.setFilename(filename); + } + + } + return; + } + + default: { + break; + } + } + super.onActivityResult(requestCode, resultCode, data); + } } diff --git a/src/org/thialfihar/android/apg/SecretKeyListActivity.java b/src/org/thialfihar/android/apg/SecretKeyListActivity.java index 1560546d7..794b30ea2 100644 --- a/src/org/thialfihar/android/apg/SecretKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SecretKeyListActivity.java @@ -32,6 +32,7 @@ import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; @@ -81,13 +82,14 @@ public class SecretKeyListActivity extends ExpandableListActivity static final int TASK_EXPORT = 2; protected int mSelectedItem = -1; - protected String mImportFilename = null; - protected String mExportFilename = null; protected int mTask = 0; private ProgressDialog mProgressDialog = null; private Thread mRunningThread = null; + private String mImportFilename = Environment.getExternalStorageDirectory() + "/secring.gpg"; + private String mExportFilename = Environment.getExternalStorageDirectory() + "/secexport.asc"; + private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -335,7 +337,7 @@ public class SecretKeyListActivity extends ExpandableListActivity case DIALOG_IMPORT_KEYS: { return FileDialog.build(this, "Import Keys", "Please specify which file to import from.", - Environment.getExternalStorageDirectory() + "/secring.gpg", + mImportFilename, new FileDialog.OnClickListener() { @Override @@ -349,7 +351,9 @@ public class SecretKeyListActivity extends ExpandableListActivity public void onCancelClick() { removeDialog(DIALOG_IMPORT_KEYS); } - }); + }, + getString(R.string.filemanager_title_open), + getString(R.string.filemanager_btn_open)); } case DIALOG_EXPORT_KEY: { @@ -370,7 +374,7 @@ public class SecretKeyListActivity extends ExpandableListActivity "Please specify which file to export to.\n" + "WARNING! You are about to export SECRET keys.\n" + "WARNING! File will be overwritten if it exists.", - Environment.getExternalStorageDirectory() + "/secexport.asc", + mExportFilename, new FileDialog.OnClickListener() { @Override @@ -384,7 +388,9 @@ public class SecretKeyListActivity extends ExpandableListActivity public void onCancelClick() { removeDialog(thisDialogId); } - }); + }, + getString(R.string.filemanager_title_save), + getString(R.string.filemanager_btn_save)); } case DIALOG_IMPORTING: { @@ -441,6 +447,24 @@ public class SecretKeyListActivity extends ExpandableListActivity break; } + case FileDialog.REQUEST_CODE_PICK_FILE_OR_DIRECTORY: { + if (resultCode == RESULT_OK && data != null) { + String filename = data.getDataString(); + if (filename != null) { + // Get rid of URI prefix: + if (filename.startsWith("file://")) { + filename = filename.substring(7); + } + // replace %20 and so on + filename = Uri.decode(filename); + + FileDialog.setFilename(filename); + } + + } + return; + } + default: break; }