passwordmanager/android/src/org/martchus/passwordmanager/Activity.java

95 lines
4.0 KiB
Java

package org.martchus.passwordmanager;
import android.content.Intent;
import android.content.ActivityNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.support.v4.provider.DocumentFile;
import java.io.FileNotFoundException;
import org.qtproject.qt5.android.bindings.QtActivity;
public class Activity extends QtActivity {
private final int REQUEST_CODE_OPEN_EXISTING_FILE = 1;
private final int REQUEST_CODE_CREATE_NEW_FILE = 2;
private final int REQUEST_CODE_SAVE_FILE_AS = 3;
/*!
* \brief Shows the native Android file dialog. Results are handled in onActivityResult().
*/
public boolean showAndroidFileDialog(boolean existing, boolean createNew) {
String action = existing ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT;
int requestCode = existing ? REQUEST_CODE_OPEN_EXISTING_FILE : (createNew ? REQUEST_CODE_CREATE_NEW_FILE : REQUEST_CODE_SAVE_FILE_AS);
Intent intent = new Intent(action);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
try {
startActivityForResult(intent, requestCode);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
/*!
* \brief Opens a native file descriptor for the specified \a contentUri (content://...) with the specified \a mode.
* \returns Returns the file descriptor or -1 on error.
* \remarks \a mode must be "r" and/or "w" for read and/or write. Appending "t" for truncate is possible as well.
*/
public int openFileDescriptorFromAndroidContentUri(String contentUri, String mode) {
try {
DocumentFile file = DocumentFile.fromSingleUri(this, Uri.parse(contentUri));
ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(file.getUri(), mode);
return fd.detachFd();
} catch (FileNotFoundException e) {
return -1;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPEN_EXISTING_FILE:
case REQUEST_CODE_CREATE_NEW_FILE:
case REQUEST_CODE_SAVE_FILE_AS:
boolean createNew = requestCode == REQUEST_CODE_CREATE_NEW_FILE;
boolean existingFile = requestCode == REQUEST_CODE_OPEN_EXISTING_FILE;
boolean saveAs = requestCode == REQUEST_CODE_SAVE_FILE_AS;
if (resultCode != RESULT_OK) {
onAndroidFileDialogRejected();
return;
}
Uri uri = data.getData();
if (uri != null) {
try {
DocumentFile file = DocumentFile.fromSingleUri(this, uri);
ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(file.getUri(), existingFile ? "r" : "wt");
onAndroidFileDialogAcceptedDescriptor(file.getUri().toString(), file.getName(), fd.detachFd(), existingFile, createNew);
} catch (FileNotFoundException e) {
onAndroidError("Failed to find selected file.");
}
return;
}
String fileName = data.getDataString();
if (fileName != null) {
onAndroidFileDialogAccepted(fileName, existingFile, createNew);
return;
}
onAndroidError("Failed to read result from Android's file dialog.");
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
public static native void onAndroidError(String message);
public static native void onAndroidFileDialogAccepted(String fileName, boolean existing, boolean createNew);
public static native void onAndroidFileDialogAcceptedDescriptor(String nativeUrl, String fileName, int fileDescriptor, boolean existing, boolean createNew);
public static native void onAndroidFileDialogRejected();
}