Import/Export activity

This commit is contained in:
ByteHamster 2017-05-28 12:17:53 +02:00
parent f9686ffba7
commit af33e4c37b
7 changed files with 235 additions and 1 deletions

View File

@ -176,6 +176,13 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/> android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
</activity> </activity>
<activity
android:name=".activity.ImportExportActivity"
android:label="@string/import_export">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="de.danoeh.antennapod.activity.PreferenceActivity"/>
</activity>
<activity <activity
android:name=".activity.OpmlImportFromPathActivity" android:name=".activity.OpmlImportFromPathActivity"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"

View File

@ -0,0 +1,183 @@
package de.danoeh.antennapod.activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.TextView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.adapter.StatisticsListAdapter;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.Converter;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
/**
* Displays the 'statistics' screen
*/
public class ImportExportActivity extends AppCompatActivity {
private static final int READ_REQUEST_CODE = 41;
private static final int READ_REQUEST_CODE_DOCUMENT = 42;
private static final String TAG = ImportExportActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayShowHomeEnabled(true);
setContentView(R.layout.import_export_activity);
//backup();
//restore();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void restore() {
if(Build.VERSION.SDK_INT >= 19) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
startActivityForResult(intent, READ_REQUEST_CODE_DOCUMENT);
} else {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "Select a File to import"), READ_REQUEST_CODE);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
File currentDB = getDatabasePath(PodDBAdapter.DATABASE_NAME);
if (requestCode == READ_REQUEST_CODE_DOCUMENT && resultCode == RESULT_OK) {
if (resultData != null) {
Uri uri = resultData.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
copyInputStreamToFile(inputStream, currentDB);
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} else if(requestCode == READ_REQUEST_CODE && resultCode == RESULT_OK) {
if (resultData != null) {
Uri uri = resultData.getData();
try {
File backupDB = new File(getPath(getBaseContext(), uri));
if (backupDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void copyInputStreamToFile(InputStream in, File file) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getPath(Context context, Uri uri) {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
}
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
private void backup() {
try {
File sd = Environment.getExternalStorageDirectory();
if (sd.canWrite()) {
File currentDB = getDatabasePath(PodDBAdapter.DATABASE_NAME);
File backupDB = new File(sd, "AntennaPodBackup.db");
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -39,6 +39,7 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import de.danoeh.antennapod.activity.ImportExportActivity;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import java.io.File; import java.io.File;
@ -95,6 +96,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private static final String PREF_OPML_EXPORT = "prefOpmlExport"; private static final String PREF_OPML_EXPORT = "prefOpmlExport";
private static final String PREF_HTML_EXPORT = "prefHtmlExport"; private static final String PREF_HTML_EXPORT = "prefHtmlExport";
private static final String STATISTICS = "statistics"; private static final String STATISTICS = "statistics";
private static final String IMPORT_EXPORT = "importExport";
private static final String PREF_ABOUT = "prefAbout"; private static final String PREF_ABOUT = "prefAbout";
private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir";
private static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings"; private static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings";
@ -191,6 +193,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
return true; return true;
} }
); );
ui.findPreference(PreferenceController.IMPORT_EXPORT).setOnPreferenceClickListener(
preference -> {
activity.startActivity(new Intent(activity, ImportExportActivity.class));
return true;
}
);
ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener( ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener(
preference -> export(new OpmlWriter())); preference -> export(new OpmlWriter()));
ui.findPreference(PreferenceController.PREF_HTML_EXPORT).setOnPreferenceClickListener( ui.findPreference(PreferenceController.PREF_HTML_EXPORT).setOnPreferenceClickListener(

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/import_export_warning"
android:gravity="center_horizontal"/>
<Button
android:text="@string/label_export"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_export"/>
<Button
android:text="@string/label_import"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_import"/>
</LinearLayout>

View File

@ -315,6 +315,9 @@
<Preference <Preference
android:key="prefHtmlExport" android:key="prefHtmlExport"
android:title="@string/html_export_label"/> android:title="@string/html_export_label"/>
<Preference
android:key="importExport"
android:title="@string/import_export"/>
<Preference <Preference
android:key="statistics" android:key="statistics"
android:title="@string/statistics_label"/> android:title="@string/statistics_label"/>

View File

@ -45,7 +45,7 @@ import de.greenrobot.event.EventBus;
public class PodDBAdapter { public class PodDBAdapter {
private static final String TAG = "PodDBAdapter"; private static final String TAG = "PodDBAdapter";
private static final String DATABASE_NAME = "Antennapod.db"; public static final String DATABASE_NAME = "Antennapod.db";
/** /**
* Maximum number of arguments for IN-operator. * Maximum number of arguments for IN-operator.

View File

@ -661,6 +661,12 @@
<string name="proxy_host_invalid_error">Host is not a valid IP address or domain</string> <string name="proxy_host_invalid_error">Host is not a valid IP address or domain</string>
<string name="proxy_port_invalid_error">Port not valid</string> <string name="proxy_port_invalid_error">Port not valid</string>
<!-- Database import/export -->
<string name="import_export">Database import/export</string>
<string name="import_export_warning">This experimental function can be used to transfer your subscriptions and played episodes to another device.\n\nExported databases can only be imported when using the same version of AntennaPod. Otherwise, this function will lead to unexpected behavior.\n\nAfter importing, episodes might be displayed as downloaded even though they are not. Just press the play button of the episodes to make AntennaPod detect this.</string>
<string name="label_import">Import</string>
<string name="label_export">Export</string>
<!-- Casting --> <!-- Casting -->
<string name="cast_media_route_menu_title">Play on&#8230;</string> <string name="cast_media_route_menu_title">Play on&#8230;</string>
<string name="cast_disconnect_label">Disconnect the cast session</string> <string name="cast_disconnect_label">Disconnect the cast session</string>