Skip to content
This repository has been archived by the owner on Aug 26, 2019. It is now read-only.

use SAF import/export data in Kikat or later #362

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions app/src/main/java/com/hippo/ehviewer/EhDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

package com.hippo.ehviewer;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
Expand Down Expand Up @@ -51,6 +55,7 @@

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -650,6 +655,40 @@ public static synchronized boolean exportDB(Context context, File file) {
return false;
}

public static synchronized boolean exportDB(Context context, Uri uri) {
File dbFile = context.getDatabasePath("eh.db");
if (null == dbFile || !dbFile.isFile()) {
return false;
}
if (null == uri) {
return false;
}
InputStream is = null;
OutputStream os = null;
ContentResolver resolver = context.getContentResolver();
try {
is = new FileInputStream(dbFile);
os = resolver.openOutputStream(uri);
IOUtils.copy(is, os);
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
// Delete failed file
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
DocumentsContract.deleteDocument(resolver, uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

return false;
}

/**
* @param file The db file
* @return error string, null for no error
Expand Down Expand Up @@ -731,4 +770,104 @@ public static synchronized String importDB(Context context, File file) {
return context.getString(R.string.cant_read_the_file);
}
}

/**
* @param uri The db uri
* @return error string, null for no error
*/
public static synchronized String importDB(Context context, Uri uri) {
try {
File file = new File(context.getCacheDir().getPath()+"/import.db");

InputStream is = null;
OutputStream os = null;
ContentResolver resolver = context.getContentResolver();
try {
is = resolver.openInputStream(uri);
os = new FileOutputStream(file);
IOUtils.copy(is, os);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}

SQLiteDatabase db = SQLiteDatabase.openDatabase(
file.getPath(), null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
int newVersion = DaoMaster.SCHEMA_VERSION;
int oldVersion = db.getVersion();
if (oldVersion < newVersion) {
upgradeDB(db, oldVersion);
db.setVersion(newVersion);
} else if (oldVersion > newVersion) {
return context.getString(R.string.cant_read_the_file);
}

DaoMaster daoMaster = new DaoMaster(db);
DaoSession session = daoMaster.newSession();

// Downloads
DownloadManager manager = EhApplication.getDownloadManager(context);
List<DownloadInfo> downloadInfoList = session.getDownloadsDao().queryBuilder().list();
manager.addDownload(downloadInfoList);

// Download label
List<DownloadLabel> downloadLabelList = session.getDownloadLabelDao().queryBuilder().list();
manager.addDownloadLabel(downloadLabelList);

// Download dirname
List<DownloadDirname> downloadDirnameList = session.getDownloadDirnameDao().queryBuilder().list();
for (DownloadDirname dirname: downloadDirnameList) {
putDownloadDirname(dirname.getGid(), dirname.getDirname());
}

// History
List<HistoryInfo> historyInfoList = session.getHistoryDao().queryBuilder().list();
putHistoryInfo(historyInfoList);

// QuickSearch
List<QuickSearch> quickSearchList = session.getQuickSearchDao().queryBuilder().list();
List<QuickSearch> currentQuickSearchList = sDaoSession.getQuickSearchDao().queryBuilder().list();
for (QuickSearch quickSearch: quickSearchList) {
String name = quickSearch.name;
for (QuickSearch q: currentQuickSearchList) {
if (ObjectUtils.equal(q.name, name)) {
// The same name
name = null;
break;
}
}
if (null == name) {
continue;
}
insertQuickSearch(quickSearch);
}

// LocalFavorites
List<LocalFavoriteInfo> localFavoriteInfoList = session.getLocalFavoritesDao().queryBuilder().list();
for (LocalFavoriteInfo info: localFavoriteInfoList) {
putLocalFavorites(info);
}

// Bookmarks
// TODO

// Filter
List<Filter> filterList = session.getFilterDao().queryBuilder().list();
List<Filter> currentFilterList = sDaoSession.getFilterDao().queryBuilder().list();
for (Filter filter: filterList) {
if (!currentFilterList.contains(filter)) {
addFilter(filter);
}
}

file.delete();

return null;
} catch (Exception e) {
// Ignore
return context.getString(R.string.cant_read_the_file);
}
}
}
131 changes: 122 additions & 9 deletions app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
Expand All @@ -45,6 +48,9 @@ public class AdvancedFragment extends PreferenceFragment
private static final String KEY_EXPORT_DATA = "export_data";
private static final String KEY_IMPORT_DATA = "import_data";

private static final int READ_REQUEST_CODE = 42;
private static final int WRITE_REQUEST_CODE = 43;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -91,26 +97,99 @@ public boolean onPreferenceClick(Preference preference) {
((EhApplication) getActivity().getApplication()).clearMemoryCache();
Runtime.getRuntime().gc();
} else if (KEY_EXPORT_DATA.equals(key)) {
File dir = AppConfig.getExternalDataDir();
if (dir != null) {
File file = new File(dir, ReadableTime.getFilenamableTime(System.currentTimeMillis()) + ".db");
if (EhDB.exportDB(getActivity(), file)) {
Toast.makeText(getActivity(),
getString(R.string.settings_advanced_export_data_to, file.getPath()), Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
showExportDialog();
return true;

} else if (defaultExportData()){
return true;
}
}
Toast.makeText(getActivity(),R.string.settings_advanced_export_data_failed, Toast.LENGTH_SHORT).show();
return true;
} else if (KEY_IMPORT_DATA.equals(key)) {
importData(getActivity());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
showImportDialog();
} else {
defaulfImportData();
}

getActivity().setResult(Activity.RESULT_OK);
return true;
}
return false;
}

private static void importData(final Context context) {
private void showExportDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.settings_advanced_export_data_location));
final CharSequence[] items = new CharSequence[]{
getString(R.string.settings_advanced_data_device_storage),
getString(R.string.settings_advanced_data_document_storage)
};
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
switch (i){
case 0:
defaultExportData();
break;
case 1:
customExportData();
break;
}
}
});
builder.show();
}

private boolean defaultExportData(){
File dir = AppConfig.getExternalDataDir();
if (dir != null) {
File file = new File(dir, ReadableTime.getFilenamableTime(System.currentTimeMillis()) + ".db");
if (EhDB.exportDB(getActivity(), file)) {
Toast.makeText(getActivity(),
getString(R.string.settings_advanced_export_data_to, file.getPath()), Toast.LENGTH_SHORT).show();
return true;
}
}
return false;
}

private void customExportData(){
String filename = ReadableTime.getFilenamableTime(System.currentTimeMillis()) + ".db";
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, filename);
startActivityForResult(intent, WRITE_REQUEST_CODE);

}

private void showImportDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.settings_advanced_import_data_location));
final CharSequence[] items = new CharSequence[]{
getString(R.string.settings_advanced_data_device_storage),
getString(R.string.settings_advanced_data_document_storage)
};
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
switch (i){
case 0:
defaulfImportData();
break;
case 1:
customImportData();
break;
}
}
});
builder.show();
}

private void defaulfImportData(){
Context context = getActivity();
final File dir = AppConfig.getExternalDataDir();
if (null == dir) {
Toast.makeText(context, R.string.cant_get_data_dir, Toast.LENGTH_SHORT).show();
Expand All @@ -135,6 +214,40 @@ public void onClick(DialogInterface dialog, int which) {
}).show();
}

private void customImportData(){
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {

if (requestCode == WRITE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
if (EhDB.exportDB(getActivity(), uri)) {
Toast.makeText(getActivity(),
getString(R.string.settings_advanced_export_data_to, uri.toString()), Toast.LENGTH_SHORT).show();
}
}
}

if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
String error = EhDB.importDB(getActivity(), uri);
if (null == error) {
error = getString(R.string.settings_advanced_import_data_successfully);
}
Toast.makeText(getActivity(), error, Toast.LENGTH_SHORT).show();
}
}
}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = preference.getKey();
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@
<string name="page_menu_refresh">@string/refresh</string>
<string name="page_menu_share">@string/share</string>
<string name="page_menu_save">保存</string>
<string name="page_menu_save_to">保存到...</string>
<string name="page_menu_save_to">保存到&#8230;</string>
<string name="page_menu_add_bookmark">添加书签</string>
<string name="gallery_menu_title">菜单</string>
<string name="share_image">分享图片</string>
Expand Down Expand Up @@ -506,9 +506,13 @@
<string name="settings_advanced_export_data_summary">保存数据至外置存储器,例如下载列表,快速搜索列表</string>
<string name="settings_advanced_export_data_to">已导出数据至 %s</string>
<string name="settings_advanced_export_data_failed">导出数据失败</string>
<string name="settings_advanced_export_data_location">导出数据到&#8230;</string>
<string name="settings_advanced_import_data">导入数据</string>
<string name="settings_advanced_import_data_summary">从置存储器导入数据</string>
<string name="settings_advanced_import_data_successfully">导入数据成功</string>
<string name="settings_advanced_import_data_location">导入数据位置</string>
<string name="settings_advanced_data_device_storage">设备存储器</string>
<string name="settings_advanced_data_document_storage">文件存储</string>

<string name="settings_about">关于</string>
<string name="settings_about_author">作者</string>
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@
<string name="page_menu_refresh">@string/refresh</string>
<string name="page_menu_share">@string/share</string>
<string name="page_menu_save">Save</string>
<string name="page_menu_save_to">Save to...</string>
<string name="page_menu_save_to">Save to&#8230;</string>
<string name="page_menu_add_bookmark">Add a bookmark</string>
<string name="gallery_menu_title">Menu</string>
<string name="share_image">Share image</string>
Expand Down Expand Up @@ -549,9 +549,13 @@
<string name="settings_advanced_export_data_summary">Save data to external storage, such as download list, quick search list</string>
<string name="settings_advanced_export_data_to">Exported data to %s</string>
<string name="settings_advanced_export_data_failed">Export data failed</string>
<string name="settings_advanced_export_data_location">Export data to&#8230;</string>
<string name="settings_advanced_import_data">Import data</string>
<string name="settings_advanced_import_data_summary">Load data which saved before</string>
<string name="settings_advanced_import_data_successfully">Import data successfully</string>
<string name="settings_advanced_import_data_location">Import data from&#8230;</string>
<string name="settings_advanced_data_device_storage">Device Storage</string>
<string name="settings_advanced_data_document_storage">Document Storage</string>

<string name="settings_about">About</string>
<string name="settings_about_author">Author</string>
Expand Down