Receive shared Android vault imports
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package org.julianfamily.keepassgo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public final class SharedVaultImportActivity extends Activity {
|
||||
private static final String TAG = "KeePassGOImport";
|
||||
private static final String DEFAULT_NAME = "shared-vault.kdbx";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state) {
|
||||
super.onCreate(state);
|
||||
handleIntent(getIntent());
|
||||
launchMainActivity();
|
||||
finish();
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
Uri uri = resolveSharedUri(intent);
|
||||
if (uri == null) {
|
||||
Log.i(TAG, "no shared vault URI on intent");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
persistPendingImport(uri);
|
||||
Log.i(TAG, "queued shared vault import from " + uri);
|
||||
} catch (IOException err) {
|
||||
Log.e(TAG, "failed to queue shared vault import", err);
|
||||
}
|
||||
}
|
||||
|
||||
private Uri resolveSharedUri(Intent intent) {
|
||||
if (intent == null) {
|
||||
return null;
|
||||
}
|
||||
String action = intent.getAction();
|
||||
if (Intent.ACTION_SEND.equals(action)) {
|
||||
return intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
}
|
||||
if (Intent.ACTION_VIEW.equals(action)) {
|
||||
return intent.getData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void persistPendingImport(Uri uri) throws IOException {
|
||||
File dir = new File(getFilesDir(), "keepassgo");
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
throw new IOException("failed to create " + dir.getAbsolutePath());
|
||||
}
|
||||
File pendingFile = new File(dir, "pending-shared-vault.kdbx");
|
||||
try (InputStream in = getContentResolver().openInputStream(uri)) {
|
||||
if (in == null) {
|
||||
throw new IOException("failed to open shared vault stream");
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(pendingFile, false)) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int count;
|
||||
while ((count = in.read(buffer)) >= 0) {
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File nameFile = new File(dir, "pending-shared-vault-name.txt");
|
||||
try (FileOutputStream out = new FileOutputStream(nameFile, false)) {
|
||||
out.write(resolveDisplayName(uri).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveDisplayName(Uri uri) {
|
||||
String displayName = queryDisplayName(uri);
|
||||
if (!displayName.isEmpty()) {
|
||||
return displayName;
|
||||
}
|
||||
String lastSegment = uri.getLastPathSegment();
|
||||
if (lastSegment != null && !lastSegment.trim().isEmpty()) {
|
||||
return lastSegment.trim();
|
||||
}
|
||||
return DEFAULT_NAME;
|
||||
}
|
||||
|
||||
private String queryDisplayName(Uri uri) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
int index = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||
if (index >= 0) {
|
||||
String value = cursor.getString(index);
|
||||
if (value != null) {
|
||||
return value.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException err) {
|
||||
Log.w(TAG, "failed to query display name", err);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void launchMainActivity() {
|
||||
Intent launch = new Intent();
|
||||
launch.setClassName(this, "org.gioui.GioActivity");
|
||||
startActivity(launch);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user