Load and import backup files from external sources

This commit is contained in:
Pierrot 2019-03-08 09:25:56 +01:00
parent f892fd575f
commit a60d265744
5 changed files with 156 additions and 36 deletions

View file

@ -2,6 +2,7 @@ package net.pierrox.lightning_launcher.activities;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
@ -20,7 +21,6 @@ import net.pierrox.lightning_launcher.data.FileUtils;
import net.pierrox.lightning_launcher.data.Folder;
import net.pierrox.lightning_launcher.data.Item;
import net.pierrox.lightning_launcher.data.Page;
import net.pierrox.lightning_launcher.engine.LightningEngine;
import net.pierrox.lightning_launcher.data.Utils;
import net.pierrox.lightning_launcher.util.FileProvider;
import net.pierrox.lightning_launcher_extreme.R;
@ -28,6 +28,7 @@ import net.pierrox.lightning_launcher_extreme.R;
import org.json.JSONObject;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
@ -37,10 +38,12 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.OpenableColumns;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
@ -61,6 +64,8 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
private static final int DIALOG_CONFIRM_DELETE=6;
private static final int REQUEST_SELECT_PAGES_FOR_EXPORT = 1;
private static final int REQUEST_SELECT_FILE_TO_IMPORT = 2;
private static final int REQUEST_SELECT_FILE_TO_LOAD = 3;
private ListView mListView;
private TextView mEmptyView;
@ -80,7 +85,12 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
Button backup = (Button) findViewById(R.id.backup);
backup.setText(R.string.backup_t);
backup.setOnClickListener(this);
Button import_ = (Button) findViewById(R.id.import_);
import_.setText(R.string.import_t);
import_.setOnClickListener(this);
import_.setOnLongClickListener(this);
Button export = (Button) findViewById(R.id.export);
export.setText(R.string.tmpl_e_t);
export.setOnClickListener(this);
@ -162,6 +172,10 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
exportArchive(true);
break;
case R.id.import_:
selectFileToLoadOrImport(true);
break;
case R.id.export:
exportArchive(false);
break;
@ -169,9 +183,17 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
}
@Override
public boolean onLongClick(View arg0) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.pierrox.net/cmsms/applications/lightning-launcher/templates.html")));
return true;
public boolean onLongClick(View view) {
switch(view.getId()) {
case R.id.export:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.pierrox.net/cmsms/applications/lightning-launcher/templates.html")));
return true;
case R.id.import_:
selectFileToLoadOrImport(false);
return true;
}
return false;
}
@Override
@ -235,7 +257,7 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
if(mArchiveName != null || mArchiveUri != null) {
builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.br_rc);
builder.setMessage(mArchiveName==null ? mArchiveUri.getLastPathSegment() : mArchiveName);
builder.setMessage(mArchiveName==null ? getNameForUri(mArchiveUri) : mArchiveName);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
@ -362,6 +384,14 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
doExportTemplate(mArchiveName, all_pages);
}
} else if(requestCode == REQUEST_SELECT_FILE_TO_IMPORT){
if(resultCode == RESULT_OK) {
importFile(data.getData());
}
} else if(requestCode == REQUEST_SELECT_FILE_TO_LOAD){
if(resultCode == RESULT_OK) {
loadArchive(data.getData(), null);
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
@ -573,4 +603,83 @@ public class BackupRestore extends ResourceWrapperActivity implements View.OnCli
}
}
}
/**
* Request the user to pick an archive.
* @param only_load true to directly load the archive without first importing it in the LL_EXT_DIR directory.
*/
private void selectFileToLoadOrImport(boolean only_load) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, getString(R.string.import_t)), only_load ? REQUEST_SELECT_FILE_TO_LOAD : REQUEST_SELECT_FILE_TO_IMPORT);
}
@SuppressLint("StaticFieldLeak")
private void importFile(final Uri uri) {
new AsyncTask<Void, Void, File>() {
private ProgressDialog mDialog;
@Override
protected void onPreExecute() {
mDialog = new ProgressDialog(BackupRestore.this);
mDialog.setMessage(getString(R.string.importing));
mDialog.setCancelable(false);
mDialog.show();
}
@Override
protected File doInBackground(Void... voids) {
InputStream is = null;
FileOutputStream os = null;
File outFile = null;
try {
String name = getNameForUri(uri);
outFile = new File(FileUtils.LL_EXT_DIR, name);
is = getContentResolver().openInputStream(uri);
os = new FileOutputStream(outFile);
FileUtils.copyStream(is, os);
return outFile;
} catch (IOException e) {
if(outFile != null) {
outFile.delete();
}
return null;
} finally {
try { if(is != null) is.close(); } catch(IOException e) {}
try { if(os != null) os.close(); } catch(IOException e) {}
}
}
@Override
protected void onPostExecute(File outFile) {
mDialog.dismiss();
if(outFile != null) {
loadArchivesList();
loadArchive(null, outFile.getName());
} else {
Toast.makeText(BackupRestore.this, R.string.import_e, Toast.LENGTH_SHORT).show();
}
}
}.execute((Void) null);
}
private String getNameForUri(Uri uri) {
String name = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (name == null) {
name = uri.getLastPathSegment();
}
return name;
}
}

View file

@ -376,7 +376,7 @@ public class BackupRestoreTool {
try {
ZipEntry ze=new ZipEntry(to+"/"+name);
zos.putNextEntry(ze);
copy(is, zos);
FileUtils.copyStream(is, zos);
zos.closeEntry();
} finally {
try { is.close(); } catch(Exception e) {/*pass*/}
@ -512,7 +512,7 @@ public class BackupRestoreTool {
parent.mkdirs();
}
fos=new FileOutputStream(out);
copy(zis, fos);
FileUtils.copyStream(zis, fos);
} catch(IOException e) {
throw e;
} finally {
@ -547,7 +547,7 @@ public class BackupRestoreTool {
try {
File out = new File(FileUtils.LL_TMP_DIR, name.substring(l));
fos=new FileOutputStream(out);
copy(zis, fos);
FileUtils.copyStream(zis, fos);
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
}
@ -603,7 +603,7 @@ public class BackupRestoreTool {
parent.mkdirs();
}
fos=new FileOutputStream(out);
copy(zis, fos);
FileUtils.copyStream(zis, fos);
} finally {
if(fos!=null) try { fos.close(); } catch(Exception e) {}
}
@ -612,14 +612,6 @@ public class BackupRestoreTool {
return ze;
}
private static byte[] copy_buffer=new byte[4096];
private static void copy(InputStream from, OutputStream to) throws IOException {
int n;
while((n=from.read(copy_buffer))!=-1) {
to.write(copy_buffer, 0, n);
}
}
private static ZipEntry skipZipEntries(ZipInputStream zis, String prefix) throws IOException {
ZipEntry ze;
for(;;) {

View file

@ -7,28 +7,34 @@
android:gravity="center_horizontal"
android:padding="20dp">
<LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:padding="15dp">
<Button
android:id="@+id/backup"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<Button
android:layout_height="wrap_content">
<Button
android:id="@+id/backup"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/export"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"/>
android:layout_height="match_parent"/>
</LinearLayout>
<Button
android:id="@+id/import_"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:drawable/divider_horizontal_bright"/>
<ListView
android:id="@+id/archives"
android:layout_height="match_parent"

View file

@ -16,6 +16,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
public static final String WALLPAPER_DIR = "wp";
@ -45,6 +46,15 @@ public class FileUtils {
public static final File LL_TMP_DIR =new File(LL_EXT_DIR, "tmp");
public static final File LL_EXT_SCRIPT_DIR = new File(LL_EXT_DIR, "script");
private static byte[] copy_buffer=new byte[4096];
public static void copyStream(InputStream from, OutputStream to) throws IOException {
int n;
while((n=from.read(copy_buffer))!=-1) {
to.write(copy_buffer, 0, n);
}
}
public static void saveStringToFile(String what, File out) throws IOException {
FileOutputStream fos=null;
try {

View file

@ -102,13 +102,16 @@
<string name="app_killer_s">Kill apps with Lightning</string>
<string name="donate_t">Donate</string>
<string name="donate_s">Want to support Lightning?</string>
<string name="backup_t">Backup</string>
<string name="backup_t">Create a backup</string>
<string name="import_t">Load an external file</string>
<string name="import_e">Import failed!</string>
<string name="importing">Import in progress</string>
<string name="restore_t">Restore</string>
<string name="rate_t">Rate Lightning</string>
<string name="rate_s">Tell us what you think</string>
<string name="facebook_t">Lightning Launcher on Google+</string>
<string name="facebook_s">App update news, suggest a feature, or report a bug</string>
<string name="ld_t">Lightning Drawer</string>
<string name="ld_t">Lightning Drawer</string>
<string name="ld_s">A highly advanced All Apps page.</string>
<string name="customize_ll">Customize Lightning</string>
@ -633,7 +636,7 @@
<string name="tmpl_a_s">Load it from an installed APK</string>
<string name="tmpl_b_t">Browse existing templates</string>
<string name="tmpl_b_s">Get fresh new themes</string>
<string name="tmpl_e_t">Export template</string>
<string name="tmpl_e_t">Create a template</string>
<string name="tmpl_e_s">Long tap to read the tutorial</string>
<string name="tmpl_c">Select a template</string>
<string name="tmpl_e_m">Exporting…</string>