mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-08-13 15:53:53 -04:00
241 lines
9.5 KiB
Java
241 lines
9.5 KiB
Java
/*
|
|
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package org.sufficientlysecure.keychain.util;
|
|
|
|
import android.annotation.TargetApi;
|
|
import android.app.Activity;
|
|
import android.content.ActivityNotFoundException;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.database.Cursor;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Point;
|
|
import android.net.Uri;
|
|
import android.os.Build;
|
|
import android.os.Environment;
|
|
import android.os.Handler;
|
|
import android.os.Message;
|
|
import android.os.Messenger;
|
|
import android.provider.DocumentsContract;
|
|
import android.provider.OpenableColumns;
|
|
import android.support.v4.app.Fragment;
|
|
import android.support.v4.app.FragmentManager;
|
|
import android.widget.Toast;
|
|
|
|
import org.sufficientlysecure.keychain.R;
|
|
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
|
|
import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
|
|
|
|
import java.io.File;
|
|
import java.text.DecimalFormat;
|
|
|
|
public class FileHelper {
|
|
|
|
/**
|
|
* Checks if external storage is mounted if file is located on external storage
|
|
*
|
|
* @param file
|
|
* @return true if storage is mounted
|
|
*/
|
|
public static boolean isStorageMounted(String file) {
|
|
if (file.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
|
|
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Opens the preferred installed file manager on Android and shows a toast if no manager is
|
|
* installed.
|
|
*
|
|
* @param fragment
|
|
* @param last default selected Uri, not supported by all file managers
|
|
* @param mimeType can be text/plain for example
|
|
* @param requestCode requestCode used to identify the result coming back from file manager to
|
|
* onActivityResult() in your activity
|
|
*/
|
|
public static void openFile(Fragment fragment, Uri last, String mimeType, int requestCode) {
|
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
|
|
intent.setData(last);
|
|
intent.setType(mimeType);
|
|
|
|
try {
|
|
fragment.startActivityForResult(intent, requestCode);
|
|
} catch (ActivityNotFoundException e) {
|
|
// No compatible file manager was found.
|
|
Toast.makeText(fragment.getActivity(), R.string.no_filemanager_installed,
|
|
Toast.LENGTH_SHORT).show();
|
|
}
|
|
}
|
|
|
|
public static void saveFile(final FileDialogCallback callback, final FragmentManager fragmentManager,
|
|
final String title, final String message, final File defaultFile,
|
|
final String checkMsg) {
|
|
// Message is received after file is selected
|
|
Handler returnHandler = new Handler() {
|
|
@Override
|
|
public void handleMessage(Message message) {
|
|
if (message.what == FileDialogFragment.MESSAGE_OKAY) {
|
|
callback.onFileSelected(
|
|
new File(message.getData().getString(FileDialogFragment.MESSAGE_DATA_FILE)),
|
|
message.getData().getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED));
|
|
}
|
|
}
|
|
};
|
|
|
|
// Create a new Messenger for the communication back
|
|
final Messenger messenger = new Messenger(returnHandler);
|
|
|
|
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
FileDialogFragment fileDialog = FileDialogFragment.newInstance(messenger, title, message,
|
|
defaultFile, checkMsg);
|
|
|
|
fileDialog.show(fragmentManager, "fileDialog");
|
|
}
|
|
});
|
|
}
|
|
|
|
public static void saveFile(Fragment fragment, String title, String message, File defaultFile, int requestCode) {
|
|
saveFile(fragment, title, message, defaultFile, requestCode, null);
|
|
}
|
|
|
|
public static void saveFile(final Fragment fragment, String title, String message, File defaultFile,
|
|
final int requestCode, String checkMsg) {
|
|
saveFile(new FileDialogCallback() {
|
|
@Override
|
|
public void onFileSelected(File file, boolean checked) {
|
|
Intent intent = new Intent();
|
|
intent.setData(Uri.fromFile(file));
|
|
fragment.onActivityResult(requestCode, Activity.RESULT_OK, intent);
|
|
}
|
|
}, fragment.getActivity().getSupportFragmentManager(), title, message, defaultFile, checkMsg);
|
|
}
|
|
|
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
|
public static void openDocument(Fragment fragment, String mimeType, int requestCode) {
|
|
openDocument(fragment, mimeType, false, requestCode);
|
|
}
|
|
|
|
/**
|
|
* Opens the storage browser on Android 4.4 or later for opening a file
|
|
*
|
|
* @param fragment
|
|
* @param mimeType can be text/plain for example
|
|
* @param multiple allow file chooser to return multiple files
|
|
* @param requestCode used to identify the result coming back from storage browser onActivityResult() in your
|
|
*/
|
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
|
public static void openDocument(Fragment fragment, String mimeType, boolean multiple, int requestCode) {
|
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
intent.setType(mimeType);
|
|
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple);
|
|
|
|
fragment.startActivityForResult(intent, requestCode);
|
|
}
|
|
|
|
/**
|
|
* Opens the storage browser on Android 4.4 or later for saving a file
|
|
*
|
|
* @param fragment
|
|
* @param mimeType can be text/plain for example
|
|
* @param suggestedName a filename desirable for the file to be saved
|
|
* @param requestCode used to identify the result coming back from storage browser onActivityResult() in your
|
|
*/
|
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
|
public static void saveDocument(Fragment fragment, String mimeType, String suggestedName, int requestCode) {
|
|
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
intent.setType(mimeType);
|
|
intent.putExtra("android.content.extra.SHOW_ADVANCED", true); // Note: This is not documented, but works
|
|
intent.putExtra(Intent.EXTRA_TITLE, suggestedName);
|
|
fragment.startActivityForResult(intent, requestCode);
|
|
}
|
|
|
|
public static String getFilename(Context context, Uri uri) {
|
|
String filename = null;
|
|
try {
|
|
Cursor cursor = context.getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
|
|
|
|
if (cursor != null) {
|
|
if (cursor.moveToNext()) {
|
|
filename = cursor.getString(0);
|
|
}
|
|
cursor.close();
|
|
}
|
|
} catch (Exception ignored) {
|
|
// This happens in rare cases (eg: document deleted since selection) and should not cause a failure
|
|
}
|
|
if (filename == null) {
|
|
String[] split = uri.toString().split("/");
|
|
filename = split[split.length - 1];
|
|
}
|
|
return filename;
|
|
}
|
|
|
|
public static long getFileSize(Context context, Uri uri) {
|
|
return getFileSize(context, uri, -1);
|
|
}
|
|
|
|
public static long getFileSize(Context context, Uri uri, long def) {
|
|
long size = def;
|
|
try {
|
|
Cursor cursor = context.getContentResolver().query(uri, new String[]{OpenableColumns.SIZE}, null, null, null);
|
|
|
|
if (cursor != null) {
|
|
if (cursor.moveToNext()) {
|
|
size = cursor.getLong(0);
|
|
}
|
|
cursor.close();
|
|
}
|
|
} catch (Exception ignored) {
|
|
// This happens in rare cases (eg: document deleted since selection) and should not cause a failure
|
|
}
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Retrieve thumbnail of file, document api feature and thus KitKat only
|
|
*/
|
|
public static Bitmap getThumbnail(Context context, Uri uri, Point size) {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
|
return DocumentsContract.getDocumentThumbnail(context.getContentResolver(), uri, size, null);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static String readableFileSize(long size) {
|
|
if (size <= 0) return "0";
|
|
final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
|
|
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
|
|
return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
|
|
}
|
|
|
|
public static interface FileDialogCallback {
|
|
public void onFileSelected(File file, boolean checked);
|
|
}
|
|
}
|