Import/Export activity
This commit is contained in:
parent
f9686ffba7
commit
af33e4c37b
@ -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"
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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(
|
||||||
|
27
app/src/main/res/layout/import_export_activity.xml
Normal file
27
app/src/main/res/layout/import_export_activity.xml
Normal 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>
|
@ -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"/>
|
||||||
|
@ -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.
|
||||||
|
@ -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…</string>
|
<string name="cast_media_route_menu_title">Play on…</string>
|
||||||
<string name="cast_disconnect_label">Disconnect the cast session</string>
|
<string name="cast_disconnect_label">Disconnect the cast session</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user