1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-01-31 17:04:59 +01:00
This commit is contained in:
Tlaster 2020-04-20 18:14:47 +08:00
parent 1ecd3acdba
commit aab797dae7
5 changed files with 201 additions and 134 deletions

View File

@ -25,6 +25,7 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.DialogInterface.OnShowListener;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -157,7 +158,7 @@ public final class DataExportImportTypeSelectorDialogFragment extends BaseDialog
final FragmentActivity a = getActivity();
final Bundle args = getArguments();
if (args == null) return;
final String path = args.getString(EXTRA_PATH);
final Uri path = args.getParcelable(EXTRA_PATH);
if (a instanceof Callback) {
((Callback) a).onPositiveButtonClicked(path, flags);
}
@ -171,7 +172,7 @@ public final class DataExportImportTypeSelectorDialogFragment extends BaseDialog
}
public interface Callback extends ISupportDialogFragmentCallback {
void onPositiveButtonClicked(String path, int flags);
void onPositiveButtonClicked(Uri path, int flags);
}
private static class Type {

View File

@ -28,12 +28,14 @@ import android.database.Cursor;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import androidx.documentfile.provider.DocumentFile;
import com.bluelinelabs.logansquare.LoganSquare;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.library.exportablepreferences.PreferencesExporter;
import org.mariotaku.library.exportablepreferences.annotation.PreferenceType;
import org.mariotaku.library.objectcursor.ObjectCursor;
@ -44,20 +46,29 @@ import org.mariotaku.twidere.model.Tab;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.osmdroid.tileprovider.modules.ZipFileArchive;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.annotation.Nonnull;
public class DataImportExportUtils implements Constants {
public static final String ENTRY_PREFERENCES = "preferences.json";
@ -79,9 +90,8 @@ public class DataImportExportUtils implements Constants {
| FLAG_HOST_MAPPING | FLAG_KEYBOARD_SHORTCUTS | FLAG_FILTERS | FLAG_TABS;
@WorkerThread
public static void exportData(final Context context, @NonNull final File dst, final int flags) throws IOException {
dst.delete();
try (FileOutputStream fos = new FileOutputStream(dst);
public static void exportData(final Context context, @NonNull final DocumentFile dst, final int flags) throws IOException {
try (OutputStream fos = context.getContentResolver().openOutputStream(dst.getUri());
ZipOutputStream zos = new ZipOutputStream(fos)) {
if (hasFlag(flags, FLAG_PREFERENCES)) {
exportSharedPreferencesData(zos, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES,
@ -161,104 +171,122 @@ public class DataImportExportUtils implements Constants {
}
@WorkerThread
public static int getImportedSettingsFlags(@NonNull final File src) throws IOException {
try (ZipFile zipFile = new ZipFile(src)) {
public static int getImportedSettingsFlags(@NonNull final Context context, @NonNull final DocumentFile src) throws IOException {
try (InputStream inputStream = context.getContentResolver().openInputStream(src.getUri());
ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
int flags = 0;
if (zipFile.getEntry(ENTRY_PREFERENCES) != null) {
List<String> entryNames = new ArrayList<>();
ZipEntry entry = null;
while ((entry = zipInputStream.getNextEntry()) != null) {
entryNames.add(entry.getName());
}
if (entryNames.contains(ENTRY_PREFERENCES)) {
flags |= FLAG_PREFERENCES;
}
if (zipFile.getEntry(ENTRY_NICKNAMES) != null) {
if (entryNames.contains(ENTRY_NICKNAMES)) {
flags |= FLAG_NICKNAMES;
}
if (zipFile.getEntry(ENTRY_USER_COLORS) != null) {
if (entryNames.contains(ENTRY_USER_COLORS)) {
flags |= FLAG_USER_COLORS;
}
if (zipFile.getEntry(ENTRY_HOST_MAPPING) != null) {
if (entryNames.contains(ENTRY_HOST_MAPPING)) {
flags |= FLAG_HOST_MAPPING;
}
if (zipFile.getEntry(ENTRY_KEYBOARD_SHORTCUTS) != null) {
if (entryNames.contains(ENTRY_KEYBOARD_SHORTCUTS)) {
flags |= FLAG_KEYBOARD_SHORTCUTS;
}
if (zipFile.getEntry(ENTRY_FILTERS) != null) {
if (entryNames.contains(ENTRY_FILTERS)) {
flags |= FLAG_FILTERS;
}
if (zipFile.getEntry(ENTRY_TABS) != null) {
if (entryNames.contains(ENTRY_TABS)) {
flags |= FLAG_TABS;
}
return flags;
}
}
public static void importData(final Context context, final File src, final int flags) throws IOException {
public static void importData(final Context context, final DocumentFile src, final int flags) throws IOException {
if (src == null) throw new FileNotFoundException();
try (ZipFile zipFile = new ZipFile(src)) {
if (hasFlag(flags, FLAG_PREFERENCES)) {
importSharedPreferencesData(zipFile, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES,
new PreferencesExporterStrategy(SharedPreferenceConstants.class));
}
if (hasFlag(flags, FLAG_NICKNAMES)) {
importSharedPreferencesData(zipFile, context, USER_NICKNAME_PREFERENCES_NAME, ENTRY_NICKNAMES,
ConvertToStringProcessStrategy.SINGLETON);
}
if (hasFlag(flags, FLAG_USER_COLORS)) {
importSharedPreferencesData(zipFile, context, USER_COLOR_PREFERENCES_NAME, ENTRY_USER_COLORS,
ConvertToIntProcessStrategy.SINGLETON);
}
if (hasFlag(flags, FLAG_HOST_MAPPING)) {
importSharedPreferencesData(zipFile, context, HOST_MAPPING_PREFERENCES_NAME, ENTRY_HOST_MAPPING,
ConvertToStringProcessStrategy.SINGLETON);
}
if (hasFlag(flags, FLAG_KEYBOARD_SHORTCUTS)) {
importSharedPreferencesData(zipFile, context, KEYBOARD_SHORTCUTS_PREFERENCES_NAME,
ENTRY_KEYBOARD_SHORTCUTS, ConvertToStringProcessStrategy.SINGLETON);
}
if (hasFlag(flags, FLAG_FILTERS)) {
importItem(context, zipFile, ENTRY_FILTERS, FiltersData.class, new ContentResolverProcessStrategy<FiltersData>() {
@Override
public boolean importItem(ContentResolver cr, FiltersData filtersData) throws IOException {
if (filtersData == null) return false;
insertBase(cr, Filters.Keywords.CONTENT_URI, filtersData.getKeywords());
insertBase(cr, Filters.Sources.CONTENT_URI, filtersData.getSources());
insertBase(cr, Filters.Links.CONTENT_URI, filtersData.getLinks());
insertUser(cr, Filters.Users.CONTENT_URI, filtersData.getUsers());
try (InputStream inputStream = context.getContentResolver().openInputStream(src.getUri());
ZipInputStream zipInputStream = new ZipInputStream(inputStream)
) {
ZipEntry entry = null;
while ((entry = zipInputStream.getNextEntry()) != null) {
StringBuilder stringBuilder = new StringBuilder();
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zipInputStream.read(buffer, 0, 1024)) >= 0) {
stringBuilder.append(new String(buffer, 0, read));
}
String data = stringBuilder.toString();
if (hasFlag(flags, FLAG_PREFERENCES)) {
importSharedPreferencesData(entry, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES,
new PreferencesExporterStrategy(SharedPreferenceConstants.class), data);
}
if (hasFlag(flags, FLAG_NICKNAMES)) {
importSharedPreferencesData(entry, context, USER_NICKNAME_PREFERENCES_NAME, ENTRY_NICKNAMES,
ConvertToStringProcessStrategy.SINGLETON, data);
}
if (hasFlag(flags, FLAG_USER_COLORS)) {
importSharedPreferencesData(entry, context, USER_COLOR_PREFERENCES_NAME, ENTRY_USER_COLORS,
ConvertToIntProcessStrategy.SINGLETON, data);
}
if (hasFlag(flags, FLAG_HOST_MAPPING)) {
importSharedPreferencesData(entry, context, HOST_MAPPING_PREFERENCES_NAME, ENTRY_HOST_MAPPING,
ConvertToStringProcessStrategy.SINGLETON, data);
}
if (hasFlag(flags, FLAG_KEYBOARD_SHORTCUTS)) {
importSharedPreferencesData(entry, context, KEYBOARD_SHORTCUTS_PREFERENCES_NAME,
ENTRY_KEYBOARD_SHORTCUTS, ConvertToStringProcessStrategy.SINGLETON, data);
}
if (hasFlag(flags, FLAG_FILTERS)) {
importItem(context, entry, ENTRY_FILTERS, FiltersData.class, data, new ContentResolverProcessStrategy<FiltersData>() {
@Override
public boolean importItem(ContentResolver cr, FiltersData filtersData) throws IOException {
if (filtersData == null) return false;
insertBase(cr, Filters.Keywords.CONTENT_URI, filtersData.getKeywords());
insertBase(cr, Filters.Sources.CONTENT_URI, filtersData.getSources());
insertBase(cr, Filters.Links.CONTENT_URI, filtersData.getLinks());
insertUser(cr, Filters.Users.CONTENT_URI, filtersData.getUsers());
return true;
}
void insertBase(ContentResolver cr, Uri uri, List<FiltersData.BaseItem> items) throws IOException {
if (items == null) return;
final ObjectCursor.ValuesCreator<FiltersData.BaseItem> baseItemCreator =
ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem.class);
List<ContentValues> values = new ArrayList<>(items.size());
for (FiltersData.BaseItem item : items) {
values.add(baseItemCreator.create(item));
}
ContentResolverUtils.bulkInsert(cr, uri, values);
}
void insertUser(ContentResolver cr, Uri uri, List<FiltersData.UserItem> items) throws IOException {
if (items == null) return;
final ObjectCursor.ValuesCreator<FiltersData.UserItem> userItemCreator =
ObjectCursor.valuesCreatorFrom(FiltersData.UserItem.class);
List<ContentValues> values = new ArrayList<>(items.size());
for (FiltersData.UserItem item : items) {
values.add(userItemCreator.create(item));
}
ContentResolverUtils.bulkInsert(cr, uri, values);
}
});
}
if (hasFlag(flags, FLAG_TABS)) {
final ObjectCursor.ValuesCreator<Tab> creator = ObjectCursor.valuesCreatorFrom(Tab.class);
importItemsList(context, entry, ENTRY_TABS, Tab.class, data, (cr, items) -> {
if (items == null) return false;
List<ContentValues> values = new ArrayList<>(items.size());
for (Tab item : items) {
values.add(creator.create(item));
}
cr.delete(Tabs.CONTENT_URI, null, null);
ContentResolverUtils.bulkInsert(cr, Tabs.CONTENT_URI, values);
return true;
}
void insertBase(ContentResolver cr, Uri uri, List<FiltersData.BaseItem> items) throws IOException {
if (items == null) return;
final ObjectCursor.ValuesCreator<FiltersData.BaseItem> baseItemCreator =
ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem.class);
List<ContentValues> values = new ArrayList<>(items.size());
for (FiltersData.BaseItem item : items) {
values.add(baseItemCreator.create(item));
}
ContentResolverUtils.bulkInsert(cr, uri, values);
}
void insertUser(ContentResolver cr, Uri uri, List<FiltersData.UserItem> items) throws IOException {
if (items == null) return;
final ObjectCursor.ValuesCreator<FiltersData.UserItem> userItemCreator =
ObjectCursor.valuesCreatorFrom(FiltersData.UserItem.class);
List<ContentValues> values = new ArrayList<>(items.size());
for (FiltersData.UserItem item : items) {
values.add(userItemCreator.create(item));
}
ContentResolverUtils.bulkInsert(cr, uri, values);
}
});
}
if (hasFlag(flags, FLAG_TABS)) {
final ObjectCursor.ValuesCreator<Tab> creator = ObjectCursor.valuesCreatorFrom(Tab.class);
importItemsList(context, zipFile, ENTRY_TABS, Tab.class, (cr, items) -> {
if (items == null) return false;
List<ContentValues> values = new ArrayList<>(items.size());
for (Tab item : items) {
values.add(creator.create(item));
}
cr.delete(Tabs.CONTENT_URI, null, null);
ContentResolverUtils.bulkInsert(cr, Tabs.CONTENT_URI, values);
return true;
});
});
}
}
}
}
@ -267,12 +295,12 @@ public class DataImportExportUtils implements Constants {
return (flags & flag) != 0;
}
private static void importSharedPreferencesData(@NonNull final ZipFile zipFile, @NonNull final Context context,
private static void importSharedPreferencesData(@NonNull final ZipEntry entry, @NonNull final Context context,
@NonNull final String preferencesName, @NonNull final String entryName,
@NonNull final SharedPreferencesProcessStrategy strategy) throws IOException {
final ZipEntry entry = zipFile.getEntry(entryName);
if (entry == null) return;
final JsonParser jsonParser = LoganSquare.JSON_FACTORY.createParser(zipFile.getInputStream(entry));
@NonNull final SharedPreferencesProcessStrategy strategy,
@NonNull final String data) throws IOException {
if (!Objects.equals(entry.getName(), entryName)) return;
final JsonParser jsonParser = LoganSquare.JSON_FACTORY.createParser(data);
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
}
@ -300,14 +328,14 @@ public class DataImportExportUtils implements Constants {
}
private static <T> void importItemsList(@NonNull final Context context,
@NonNull final ZipFile zipFile,
@NonNull final ZipEntry entry,
@NonNull final String entryName,
@NonNull final Class<T> itemCls,
@NonNull final String data,
@NonNull final ContentResolverProcessStrategy<List<T>> strategy)
throws IOException {
final ZipEntry entry = zipFile.getEntry(entryName);
if (entry == null) return;
List<T> itemsList = JsonSerializer.parseList(zipFile.getInputStream(entry), itemCls);
if (!Objects.equals(entry.getName(), entryName)) return;
List<T> itemsList = JsonSerializer.parseList(data, itemCls);
strategy.importItem(context.getContentResolver(), itemsList);
}
@ -317,19 +345,22 @@ public class DataImportExportUtils implements Constants {
@NonNull final Class<T> itemCls,
@NonNull final List<T> itemList) throws IOException {
zos.putNextEntry(new ZipEntry(entryName));
JsonSerializer.serialize(itemList, zos, itemCls);
String json = LoganSquare.serialize(itemList);
OutputStreamWriter writer = new OutputStreamWriter(zos);
writer.write(json);
writer.flush();
zos.closeEntry();
}
private static <T> void importItem(@NonNull final Context context,
@NonNull final ZipFile zipFile,
@NonNull final ZipEntry entry,
@NonNull final String entryName,
@NonNull final Class<T> itemCls,
@NonNull final String data,
@NonNull final ContentResolverProcessStrategy<T> strategy)
throws IOException {
final ZipEntry entry = zipFile.getEntry(entryName);
if (entry == null) return;
T item = JsonSerializer.parse(zipFile.getInputStream(entry), itemCls);
if (!Objects.equals(entry.getName(), entryName)) return;
T item = JsonSerializer.parse(data, itemCls);
strategy.importItem(context.getContentResolver(), item);
}
@ -339,7 +370,10 @@ public class DataImportExportUtils implements Constants {
@NonNull final Class<T> itemCls,
@NonNull final T item) throws IOException {
zos.putNextEntry(new ZipEntry(entryName));
JsonSerializer.serialize(item, zos, itemCls);
String json = LoganSquare.serialize(item);
OutputStreamWriter writer = new OutputStreamWriter(zos);
writer.write(json);
writer.flush();
zos.closeEntry();
}

View File

@ -2,10 +2,12 @@ package org.mariotaku.twidere.activity
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import android.util.Log
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.DialogFragment
import org.mariotaku.ktextension.dismissDialogFragment
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R
@ -13,7 +15,6 @@ import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.fragment.DataExportImportTypeSelectorDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.util.DataImportExportUtils
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
@ -39,10 +40,10 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
REQUEST_PICK_DIRECTORY -> {
executeAfterFragmentResumed {
if (resultCode == RESULT_OK && data != null) {
val path = data.data?.path
val path = data.data
val df = DataExportImportTypeSelectorDialogFragment()
val args = Bundle()
args.putString(EXTRA_PATH, path)
args.putParcelable(EXTRA_PATH, path)
args.putString(EXTRA_TITLE, getString(R.string.export_settings_type_dialog_title))
df.arguments = args
df.show(supportFragmentManager, "select_export_type")
@ -58,13 +59,13 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
super.onActivityResult(requestCode, resultCode, data)
}
override fun onPositiveButtonClicked(path: String?, flags: Int) {
override fun onPositiveButtonClicked(path: Uri?, flags: Int) {
if (path == null || flags == 0) {
finish()
return
}
if (task == null || task!!.status != AsyncTask.Status.RUNNING) {
task = ExportSettingsTask(this, path, flags)
task = ExportSettingsTask(this, DocumentFile.fromTreeUri(this, path), flags)
task!!.execute()
}
}
@ -85,16 +86,18 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
internal class ExportSettingsTask(
private val activity: DataExportActivity,
private val path: String?,
private val folder: DocumentFile?,
private val flags: Int
) : AsyncTask<Any, Any, Boolean>() {
override fun doInBackground(vararg params: Any): Boolean? {
if (path == null) return false
if (folder == null || !folder.isDirectory) return false
val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US)
val fileName = String.format("Twidere_Settings_%s.zip", sdf.format(Date()))
val file = File(path, fileName)
file.delete()
val file = folder.findFile(fileName) ?: folder.createFile("application/zip", fileName)
?: return false
// val file = File(folder, fileName)
// file.delete()
try {
DataImportExportUtils.exportData(activity, file, flags)
return true

View File

@ -1,17 +1,18 @@
package org.mariotaku.twidere.activity
import android.content.Intent
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import android.util.Log
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.DialogFragment
import org.mariotaku.ktextension.dismissDialogFragment
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.fragment.DataExportImportTypeSelectorDialogFragment
import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.util.DataImportExportUtils
import java.io.File
import java.io.IOException
class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFragment.Callback {
@ -37,9 +38,9 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
REQUEST_PICK_FILE -> {
resumeFragmentsRunnable = Runnable {
if (resultCode == RESULT_OK && data != null) {
val path = data.data?.path
val path = data.data!!
if (openImportTypeTask == null || openImportTypeTask!!.status != AsyncTask.Status.RUNNING) {
openImportTypeTask = OpenImportTypeTask(this@DataImportActivity, path)
openImportTypeTask = OpenImportTypeTask(this@DataImportActivity, DocumentFile.fromSingleUri(this, path))
openImportTypeTask!!.execute()
}
} else {
@ -62,13 +63,13 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
}
override fun onPositiveButtonClicked(path: String?, flags: Int) {
override fun onPositiveButtonClicked(path: Uri?, flags: Int) {
if (path == null || flags == 0) {
finish()
return
}
if (importSettingsTask == null || importSettingsTask!!.status != AsyncTask.Status.RUNNING) {
importSettingsTask = ImportSettingsTask(this, path, flags)
importSettingsTask = ImportSettingsTask(this, DocumentFile.fromSingleUri(this, path), flags)
importSettingsTask!!.execute()
}
}
@ -89,13 +90,14 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
internal class ImportSettingsTask(
private val activity: DataImportActivity,
private val path: String?,
private val file: DocumentFile?,
private val flags: Int
) : AsyncTask<Any, Any, Boolean>() {
override fun doInBackground(vararg params: Any): Boolean? {
if (path == null) return false
val file = File(path)
if (file == null) {
return false
}
if (!file.isFile) return false
try {
DataImportExportUtils.importData(activity, file, flags)
@ -131,14 +133,15 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
internal class OpenImportTypeTask(private val activity: DataImportActivity, private val path: String?) : AsyncTask<Any, Any, Int>() {
internal class OpenImportTypeTask(private val activity: DataImportActivity, private val file: DocumentFile?) : AsyncTask<Any, Any, Int>() {
override fun doInBackground(vararg params: Any): Int? {
if (path == null) return 0
val file = File(path)
if (file == null) {
return 0
}
if (!file.isFile) return 0
try {
return DataImportExportUtils.getImportedSettingsFlags(file)
return DataImportExportUtils.getImportedSettingsFlags(activity, file)
} catch (e: IOException) {
return 0
}
@ -151,7 +154,7 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
}
val df = DataExportImportTypeSelectorDialogFragment()
val args = Bundle()
args.putString(EXTRA_PATH, path)
args.putParcelable(EXTRA_PATH, file?.uri)
args.putString(EXTRA_TITLE, activity.getString(R.string.import_settings_type_dialog_title))
if (flags != null) {
args.putInt(EXTRA_FLAGS, flags)

View File

@ -24,22 +24,22 @@ import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment.getExternalStorageDirectory
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.fragment.app.DialogFragment
import android.widget.Toast
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.checkAllSelfPermissionsGranted
import org.mariotaku.ktextension.set
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.REQUEST_REQUEST_PERMISSIONS
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_PICK_DIRECTORY
import org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_PICK_FILE
import org.mariotaku.twidere.fragment.FileSelectorDialogFragment
import java.io.File
import android.Manifest.permission as AndroidPermissions
class FileSelectorActivity : BaseActivity(), FileSelectorDialogFragment.Callback {
private val PICKER_REQUEST_CODE: Int = 54837
override fun onCancelled(df: DialogFragment) {
if (!isFinishing) {
finish()
@ -101,15 +101,41 @@ class FileSelectorActivity : BaseActivity(), FileSelectorDialogFragment.Callback
finish()
}
private fun showPickFileDialog() {
val initialDirectory = intent?.data?.path?.let(::File) ?: getExternalStorageDirectory() ?: File("/")
val f = FileSelectorDialogFragment()
f.arguments = Bundle {
this[EXTRA_ACTION] = intent.action
this[EXTRA_PATH] = initialDirectory.absolutePath
this[EXTRA_FILE_EXTENSIONS] = intent.getStringArrayExtra(EXTRA_FILE_EXTENSIONS)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICKER_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
setResult(Activity.RESULT_OK, Intent().also { it.data = data.data })
finish()
} else {
if (!isFinishing) {
finish()
}
}
f.show(supportFragmentManager, "select_file")
}
private fun showPickFileDialog() {
Intent().apply {
if (intent.action == INTENT_ACTION_PICK_FILE) {
action = Intent.ACTION_GET_CONTENT
type = "*/*"
} else if (intent.action == INTENT_ACTION_PICK_DIRECTORY) {
action = Intent.ACTION_OPEN_DOCUMENT_TREE
}
}.also {
startActivityForResult(
Intent.createChooser(it, getString(R.string.pick_file)),
PICKER_REQUEST_CODE
)
}
// val initialDirectory = intent?.data?.path?.let(::File) ?: getExternalStorageDirectory() ?: File("/")
// val f = FileSelectorDialogFragment()
// f.arguments = Bundle {
// this[EXTRA_ACTION] = intent.action
// this[EXTRA_PATH] = initialDirectory.absolutePath
// this[EXTRA_FILE_EXTENSIONS] = intent.getStringArrayExtra(EXTRA_FILE_EXTENSIONS)
// }
// f.show(supportFragmentManager, "select_file")
}
}