Merge pull request #1432 from dvalter/fix/Android-R-import-export
Fix import/export for Android R+
This commit is contained in:
commit
f1ff56b8f5
|
@ -84,8 +84,8 @@ public class DataImportExportUtils implements Constants {
|
||||||
| FLAG_HOST_MAPPING | FLAG_KEYBOARD_SHORTCUTS | FLAG_FILTERS | FLAG_TABS;
|
| FLAG_HOST_MAPPING | FLAG_KEYBOARD_SHORTCUTS | FLAG_FILTERS | FLAG_TABS;
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public static void exportData(final Context context, @NonNull final DocumentFile dst, final int flags) throws IOException {
|
public static void exportData(final Context context, @NonNull final Uri dst, final int flags) throws IOException {
|
||||||
try (OutputStream fos = context.getContentResolver().openOutputStream(dst.getUri());
|
try (OutputStream fos = context.getContentResolver().openOutputStream(dst);
|
||||||
ZipOutputStream zos = new ZipOutputStream(fos)) {
|
ZipOutputStream zos = new ZipOutputStream(fos)) {
|
||||||
if (hasFlag(flags, FLAG_PREFERENCES)) {
|
if (hasFlag(flags, FLAG_PREFERENCES)) {
|
||||||
exportSharedPreferencesData(zos, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES,
|
exportSharedPreferencesData(zos, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES,
|
||||||
|
@ -199,9 +199,9 @@ public class DataImportExportUtils implements Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void importData(final Context context, final DocumentFile src, final int flags) throws IOException {
|
public static void importData(final Context context, final Uri src, final int flags) throws IOException {
|
||||||
if (src == null) throw new FileNotFoundException();
|
if (src == null) throw new FileNotFoundException();
|
||||||
try (InputStream inputStream = context.getContentResolver().openInputStream(src.getUri());
|
try (InputStream inputStream = context.getContentResolver().openInputStream(src);
|
||||||
ZipInputStream zipInputStream = new ZipInputStream(inputStream)
|
ZipInputStream zipInputStream = new ZipInputStream(inputStream)
|
||||||
) {
|
) {
|
||||||
ZipEntry entry;
|
ZipEntry entry;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.net.Uri
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.DocumentsContract
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
@ -17,7 +18,6 @@ import org.mariotaku.twidere.fragment.DataExportImportTypeSelectorDialogFragment
|
||||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment
|
import org.mariotaku.twidere.fragment.ProgressDialogFragment
|
||||||
import org.mariotaku.twidere.util.DataImportExportUtils
|
import org.mariotaku.twidere.util.DataImportExportUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -67,12 +67,7 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (task == null || task!!.status != AsyncTask.Status.RUNNING) {
|
if (task == null || task!!.status != AsyncTask.Status.RUNNING) {
|
||||||
val folder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
task = ExportSettingsTask(this, path, flags)
|
||||||
DocumentFile.fromTreeUri(this, path)
|
|
||||||
} else {
|
|
||||||
DocumentFile.fromFile(File(path.path))
|
|
||||||
}
|
|
||||||
task = ExportSettingsTask(this, folder, flags)
|
|
||||||
task!!.execute()
|
task!!.execute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,30 +80,53 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val intent = Intent(this, FileSelectorActivity::class.java)
|
val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
intent.action = IntentConstants.INTENT_ACTION_PICK_DIRECTORY
|
val i = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
|
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
|
||||||
|
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||||
|
i
|
||||||
|
} else {
|
||||||
|
val i = Intent(this, FileSelectorActivity::class.java)
|
||||||
|
i.action = IntentConstants.INTENT_ACTION_PICK_DIRECTORY
|
||||||
|
i
|
||||||
|
}
|
||||||
startActivityForResult(intent, REQUEST_PICK_DIRECTORY)
|
startActivityForResult(intent, REQUEST_PICK_DIRECTORY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ExportSettingsTask(
|
internal class ExportSettingsTask(
|
||||||
private val activity: DataExportActivity,
|
private val activity: DataExportActivity,
|
||||||
private val folder: DocumentFile?,
|
private val folderUri: Uri?,
|
||||||
private val flags: Int
|
private val flags: Int
|
||||||
) : AsyncTask<Any, Any, Boolean>() {
|
) : AsyncTask<Any, Any, Boolean>() {
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Any): Boolean? {
|
override fun doInBackground(vararg params: Any): Boolean? {
|
||||||
if (folder == null || !folder.isDirectory) return false
|
if (folderUri == null) return false
|
||||||
val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US)
|
val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US)
|
||||||
val fileName = String.format("Twidere_Settings_%s.zip", sdf.format(Date()))
|
val fileName = String.format("Twidere_Settings_%s.zip", sdf.format(Date()))
|
||||||
val file = folder.findFile(fileName) ?: folder.createFile("application/zip", fileName)
|
|
||||||
?: return false
|
|
||||||
// val file = File(folder, fileName)
|
// val file = File(folder, fileName)
|
||||||
// file.delete()
|
// file.delete()
|
||||||
return try {
|
return try {
|
||||||
DataImportExportUtils.exportData(activity, file, flags)
|
val createdDocumentUri = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
val docId = DocumentsContract.getTreeDocumentId(folderUri)
|
||||||
|
val dirUri = DocumentsContract.buildDocumentUriUsingTree(folderUri, docId)
|
||||||
|
DocumentsContract.createDocument(
|
||||||
|
activity.contentResolver,
|
||||||
|
dirUri,
|
||||||
|
"application/zip",
|
||||||
|
fileName)
|
||||||
|
} else {
|
||||||
|
val folder = DocumentFile.fromFile(File(folderUri.path!!))
|
||||||
|
val file = folder.findFile(fileName)
|
||||||
|
?: folder.createFile("application/zip", fileName) ?: return false
|
||||||
|
file.uri
|
||||||
|
})
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
DataImportExportUtils.exportData(activity, createdDocumentUri, flags)
|
||||||
true
|
true
|
||||||
} catch (e: IOException) {
|
} catch (e: Throwable) {
|
||||||
Log.w(LOGTAG, e)
|
Log.w(LOGTAG, e)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,12 +76,7 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (importSettingsTask == null || importSettingsTask!!.status != AsyncTask.Status.RUNNING) {
|
if (importSettingsTask == null || importSettingsTask!!.status != AsyncTask.Status.RUNNING) {
|
||||||
val file = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
importSettingsTask = ImportSettingsTask(this, path, flags)
|
||||||
DocumentFile.fromSingleUri(this, path)
|
|
||||||
} else {
|
|
||||||
DocumentFile.fromFile(File(path.path))
|
|
||||||
}
|
|
||||||
importSettingsTask = ImportSettingsTask(this, file, flags)
|
|
||||||
importSettingsTask!!.execute()
|
importSettingsTask!!.execute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,25 +89,28 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val intent = Intent(this, FileSelectorActivity::class.java)
|
val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
intent.action = INTENT_ACTION_PICK_FILE
|
val i = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||||
|
i.type = "*/*"
|
||||||
|
i
|
||||||
|
} else {
|
||||||
|
val i = Intent(this, FileSelectorActivity::class.java)
|
||||||
|
i.action = INTENT_ACTION_PICK_FILE
|
||||||
|
i
|
||||||
|
}
|
||||||
startActivityForResult(intent, REQUEST_PICK_FILE)
|
startActivityForResult(intent, REQUEST_PICK_FILE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ImportSettingsTask(
|
internal class ImportSettingsTask(
|
||||||
private val activity: DataImportActivity,
|
private val activity: DataImportActivity,
|
||||||
private val file: DocumentFile?,
|
private val uri: Uri?,
|
||||||
private val flags: Int
|
private val flags: Int
|
||||||
) : AsyncTask<Any, Any, Boolean>() {
|
) : AsyncTask<Any, Any, Boolean>() {
|
||||||
|
|
||||||
override fun doInBackground(vararg params: Any): Boolean? {
|
override fun doInBackground(vararg params: Any): Boolean? {
|
||||||
if (file == null) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (!file.isFile) return false
|
|
||||||
return try {
|
return try {
|
||||||
DataImportExportUtils.importData(activity, file, flags)
|
DataImportExportUtils.importData(activity, uri, flags)
|
||||||
true
|
true
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.w(LOGTAG, e)
|
Log.w(LOGTAG, e)
|
||||||
|
|
Loading…
Reference in New Issue