Added subscription syncing
This commit is contained in:
parent
e29d117942
commit
c5f848ead5
|
@ -143,6 +143,11 @@
|
||||||
android:enabled="true">
|
android:enabled="true">
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".service.GpodnetSyncService"
|
||||||
|
android:enabled="true">
|
||||||
|
</service>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.PreferenceActivity"
|
android:name=".activity.PreferenceActivity"
|
||||||
android:configChanges="keyboardHidden|orientation"
|
android:configChanges="keyboardHidden|orientation"
|
||||||
|
@ -377,6 +382,7 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
<receiver android:name=".receiver.ConnectivityActionReceiver">
|
<receiver android:name=".receiver.ConnectivityActionReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
||||||
|
|
|
@ -17,5 +17,7 @@
|
||||||
<item name="skip_episode_item" type="id"/>
|
<item name="skip_episode_item" type="id"/>
|
||||||
<item name="image_disk_cache_key" type="id"/>
|
<item name="image_disk_cache_key" type="id"/>
|
||||||
<item name="imageloader_key" type="id"/>
|
<item name="imageloader_key" type="id"/>
|
||||||
|
<item name="notification_gpodnet_sync_error" type="id"/>
|
||||||
|
<item name="notification_gpodnet_sync_autherror" type="id"/>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -195,6 +195,8 @@
|
||||||
<string name="pref_update_interval_hours_manual">Manual</string>
|
<string name="pref_update_interval_hours_manual">Manual</string>
|
||||||
<string name="pref_gpodnet_authenticate_title">Login</string>
|
<string name="pref_gpodnet_authenticate_title">Login</string>
|
||||||
<string name="pref_gpodnet_authenticate_sum">Login with your gpodder.net account in order to sync your subscriptions.</string>
|
<string name="pref_gpodnet_authenticate_sum">Login with your gpodder.net account in order to sync your subscriptions.</string>
|
||||||
|
<string name="pref_gpodnet_logout_title">Logout</string>
|
||||||
|
<string name="pref_gpodnet_logout_toast">Logout was successful</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- Search -->
|
<!-- Search -->
|
||||||
|
@ -268,6 +270,11 @@
|
||||||
<string name="gpodnetauth_finish_butsyncnow">Start sync now</string>
|
<string name="gpodnetauth_finish_butsyncnow">Start sync now</string>
|
||||||
<string name="gpodnetauth_finish_butgomainscreen">Go to main screen</string>
|
<string name="gpodnetauth_finish_butgomainscreen">Go to main screen</string>
|
||||||
|
|
||||||
|
<string name="gpodnetsync_auth_error_title">gpodder.net authentication error</string>
|
||||||
|
<string name="gpodnetsync_auth_error_descr">Wrong username or password</string>
|
||||||
|
<string name="gpodnetsync_error_title">gpodder.net sync error</string>
|
||||||
|
<string name="gpodnetsync_error_descr">An error occurred during syncing:\u0020</string>
|
||||||
|
|
||||||
<!-- Directory chooser -->
|
<!-- Directory chooser -->
|
||||||
<string name="selected_folder_label">Selected folder:</string>
|
<string name="selected_folder_label">Selected folder:</string>
|
||||||
<string name="create_folder_label">Create folder</string>
|
<string name="create_folder_label">Create folder</string>
|
||||||
|
|
|
@ -92,6 +92,9 @@
|
||||||
android:summary="@string/pref_gpodnet_authenticate_sum">
|
android:summary="@string/pref_gpodnet_authenticate_sum">
|
||||||
<intent android:action=".activity.gpoddernet.GpodnetAuthenticationActivity"/>
|
<intent android:action=".activity.gpoddernet.GpodnetAuthenticationActivity"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
<Preference
|
||||||
|
android:key="pref_gpodnet_logout"
|
||||||
|
android:title="@string/pref_gpodnet_logout_title"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
|
@ -21,10 +21,12 @@ import android.util.Log;
|
||||||
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.widget.Toast;
|
||||||
import de.danoeh.antennapod.AppConfig;
|
import de.danoeh.antennapod.AppConfig;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.asynctask.FlattrClickWorker;
|
import de.danoeh.antennapod.asynctask.FlattrClickWorker;
|
||||||
import de.danoeh.antennapod.asynctask.OpmlExportWorker;
|
import de.danoeh.antennapod.asynctask.OpmlExportWorker;
|
||||||
|
import de.danoeh.antennapod.preferences.GpodnetPreferences;
|
||||||
import de.danoeh.antennapod.preferences.UserPreferences;
|
import de.danoeh.antennapod.preferences.UserPreferences;
|
||||||
import de.danoeh.antennapod.util.flattr.FlattrUtils;
|
import de.danoeh.antennapod.util.flattr.FlattrUtils;
|
||||||
|
|
||||||
|
@ -41,6 +43,8 @@ public class PreferenceActivity extends android.preference.PreferenceActivity {
|
||||||
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";
|
||||||
|
private static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
|
||||||
|
private static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
|
||||||
|
|
||||||
private CheckBoxPreference[] selectedNetworks;
|
private CheckBoxPreference[] selectedNetworks;
|
||||||
|
|
||||||
|
@ -156,11 +160,29 @@ public class PreferenceActivity extends android.preference.PreferenceActivity {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
findPreference(PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
GpodnetPreferences.logout();
|
||||||
|
Toast toast = Toast.makeText(PreferenceActivity.this, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT);
|
||||||
|
toast.show();
|
||||||
|
updateGpodnetPreferenceScreen();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateGpodnetPreferenceScreen();
|
||||||
buildUpdateIntervalPreference();
|
buildUpdateIntervalPreference();
|
||||||
buildAutodownloadSelectedNetworsPreference();
|
buildAutodownloadSelectedNetworsPreference();
|
||||||
setSelectedNetworksEnabled(UserPreferences
|
setSelectedNetworksEnabled(UserPreferences
|
||||||
.isEnableAutodownloadWifiFilter());
|
.isEnableAutodownloadWifiFilter());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateGpodnetPreferenceScreen() {
|
||||||
|
final boolean loggedIn = GpodnetPreferences.loggedIn();
|
||||||
|
findPreference(PREF_GPODNET_LOGIN).setEnabled(!loggedIn);
|
||||||
|
findPreference(PREF_GPODNET_LOGOUT).setEnabled(loggedIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildUpdateIntervalPreference() {
|
private void buildUpdateIntervalPreference() {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import de.danoeh.antennapod.gpoddernet.GpodnetServiceException;
|
||||||
import de.danoeh.antennapod.gpoddernet.model.GpodnetDevice;
|
import de.danoeh.antennapod.gpoddernet.model.GpodnetDevice;
|
||||||
import de.danoeh.antennapod.preferences.GpodnetPreferences;
|
import de.danoeh.antennapod.preferences.GpodnetPreferences;
|
||||||
import de.danoeh.antennapod.preferences.UserPreferences;
|
import de.danoeh.antennapod.preferences.UserPreferences;
|
||||||
|
import de.danoeh.antennapod.service.GpodnetSyncService;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -280,13 +281,19 @@ public class GpodnetAuthenticationActivity extends ActionBarActivity {
|
||||||
final Button sync = (Button) view.findViewById(R.id.butSyncNow);
|
final Button sync = (Button) view.findViewById(R.id.butSyncNow);
|
||||||
final Button back = (Button) view.findViewById(R.id.butGoMainscreen);
|
final Button back = (Button) view.findViewById(R.id.butGoMainscreen);
|
||||||
|
|
||||||
|
sync.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
GpodnetSyncService.sendSyncIntent(GpodnetAuthenticationActivity.this);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
back.setOnClickListener(new View.OnClickListener() {
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class);
|
Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,17 @@ public class GpodnetPreferences {
|
||||||
public static final String PREF_GPODNET_PASSWORD = "de.danoeh.antennapod.preferences.gpoddernet.password";
|
public static final String PREF_GPODNET_PASSWORD = "de.danoeh.antennapod.preferences.gpoddernet.password";
|
||||||
public static final String PREF_GPODNET_DEVICEID = "de.danoeh.antennapod.preferences.gpoddernet.deviceID";
|
public static final String PREF_GPODNET_DEVICEID = "de.danoeh.antennapod.preferences.gpoddernet.deviceID";
|
||||||
|
|
||||||
|
public static final String PREF_LAST_SYNC_TIMESTAMP = "de.danoeh.antennapod.preferences.gpoddernet.last_sync_timestamp";
|
||||||
|
|
||||||
private static String username;
|
private static String username;
|
||||||
private static String password;
|
private static String password;
|
||||||
private static String deviceID;
|
private static String deviceID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last value returned by getSubscriptionChanges call. Will be used for all subsequent calls of getSubscriptionChanges.
|
||||||
|
*/
|
||||||
|
private static long lastSyncTimestamp;
|
||||||
|
|
||||||
private static boolean preferencesLoaded = false;
|
private static boolean preferencesLoaded = false;
|
||||||
|
|
||||||
private static SharedPreferences getPreferences() {
|
private static SharedPreferences getPreferences() {
|
||||||
|
@ -32,7 +39,7 @@ public class GpodnetPreferences {
|
||||||
username = prefs.getString(PREF_GPODNET_USERNAME, null);
|
username = prefs.getString(PREF_GPODNET_USERNAME, null);
|
||||||
password = prefs.getString(PREF_GPODNET_PASSWORD, null);
|
password = prefs.getString(PREF_GPODNET_PASSWORD, null);
|
||||||
deviceID = prefs.getString(PREF_GPODNET_DEVICEID, null);
|
deviceID = prefs.getString(PREF_GPODNET_DEVICEID, null);
|
||||||
|
lastSyncTimestamp = prefs.getLong(PREF_LAST_SYNC_TIMESTAMP, 0);
|
||||||
preferencesLoaded = true;
|
preferencesLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +50,11 @@ public class GpodnetPreferences {
|
||||||
editor.commit();
|
editor.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writePreference(String key, long value) {
|
||||||
|
SharedPreferences.Editor editor = getPreferences().edit();
|
||||||
|
editor.putLong(key, value);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
public static String getUsername() {
|
public static String getUsername() {
|
||||||
ensurePreferencesLoaded();
|
ensurePreferencesLoaded();
|
||||||
|
@ -73,4 +85,29 @@ public class GpodnetPreferences {
|
||||||
GpodnetPreferences.deviceID = deviceID;
|
GpodnetPreferences.deviceID = deviceID;
|
||||||
writePreference(PREF_GPODNET_DEVICEID, deviceID);
|
writePreference(PREF_GPODNET_DEVICEID, deviceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getLastSyncTimestamp() {
|
||||||
|
ensurePreferencesLoaded();
|
||||||
|
return lastSyncTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLastSyncTimestamp(long lastSyncTimestamp) {
|
||||||
|
GpodnetPreferences.lastSyncTimestamp = lastSyncTimestamp;
|
||||||
|
writePreference(PREF_LAST_SYNC_TIMESTAMP, lastSyncTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if device ID, username and password have a non-null value
|
||||||
|
*/
|
||||||
|
public static boolean loggedIn() {
|
||||||
|
ensurePreferencesLoaded();
|
||||||
|
return deviceID != null && username != null && password != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void logout() {
|
||||||
|
setUsername(null);
|
||||||
|
setPassword(null);
|
||||||
|
setDeviceID(null);
|
||||||
|
setLastSyncTimestamp(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
package de.danoeh.antennapod.service;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
import de.danoeh.antennapod.AppConfig;
|
||||||
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.feed.Feed;
|
||||||
|
import de.danoeh.antennapod.gpoddernet.GpodnetService;
|
||||||
|
import de.danoeh.antennapod.gpoddernet.GpodnetServiceAuthenticationException;
|
||||||
|
import de.danoeh.antennapod.gpoddernet.GpodnetServiceException;
|
||||||
|
import de.danoeh.antennapod.gpoddernet.model.GpodnetSubscriptionChange;
|
||||||
|
import de.danoeh.antennapod.preferences.GpodnetPreferences;
|
||||||
|
import de.danoeh.antennapod.storage.DBReader;
|
||||||
|
import de.danoeh.antennapod.storage.DBTasks;
|
||||||
|
import de.danoeh.antennapod.storage.DownloadRequestException;
|
||||||
|
import de.danoeh.antennapod.storage.DownloadRequester;
|
||||||
|
import de.danoeh.antennapod.util.NetworkUtils;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronizes local subscriptions with gpodder.net service. The service should be started with an ACTION_UPLOAD_CHANGES,
|
||||||
|
* ACTION_DOWNLOAD_CHANGES or ACTION_SYNC as an action argument. This class also provides static methods for starting the GpodnetSyncService.
|
||||||
|
*/
|
||||||
|
public class GpodnetSyncService extends Service {
|
||||||
|
private static final String TAG = "GpodnetSyncService";
|
||||||
|
|
||||||
|
private static final long WAIT_INTERVAL = 5000L;
|
||||||
|
|
||||||
|
public static final String ARG_ACTION = "action";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new upload action. The service will not upload immediately, but wait for a certain amount of time in
|
||||||
|
* case any other upload requests occur.
|
||||||
|
*/
|
||||||
|
public static final String ACTION_UPLOAD_CHANGES = "de.danoeh.antennapod.intent.action.upload_changes";
|
||||||
|
/**
|
||||||
|
* Starts a new download action. The service will download all changes in the subscription list since the last sync.
|
||||||
|
* New subscriptions will be added to the database, removed subscriptions will be removed from the database
|
||||||
|
*/
|
||||||
|
public static final String ACTION_DOWNLOAD_CHANGES = "de.danoeh.antennapod.intent.action.download_changes";
|
||||||
|
/**
|
||||||
|
* Starts a new upload action immediately and a new download action after that.
|
||||||
|
*/
|
||||||
|
public static final String ACTION_SYNC = "de.danoeh.antennapod.intent.action.sync";
|
||||||
|
|
||||||
|
private GpodnetService service;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
final String action = (intent != null) ? intent.getStringExtra(ARG_ACTION) : null;
|
||||||
|
if (action != null && action.equals(ACTION_UPLOAD_CHANGES)) {
|
||||||
|
Log.d(TAG, String.format("Waiting %d milliseconds before uploading changes", WAIT_INTERVAL));
|
||||||
|
|
||||||
|
uploadWaiterThread.restart();
|
||||||
|
} else if (action != null && action.equals(ACTION_DOWNLOAD_CHANGES)) {
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
downloadChanges();
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
} else if (action != null && action.equals(ACTION_SYNC)) {
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
uploadChanges();
|
||||||
|
downloadChanges();
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
return START_FLAG_REDELIVERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (AppConfig.DEBUG) Log.d(TAG, "onDestroy");
|
||||||
|
uploadWaiterThread.interrupt();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GpodnetService tryLogin() throws GpodnetServiceException {
|
||||||
|
if (service == null) {
|
||||||
|
service = new GpodnetService();
|
||||||
|
service.authenticate(GpodnetPreferences.getUsername(), GpodnetPreferences.getPassword());
|
||||||
|
}
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void downloadChanges() {
|
||||||
|
if (GpodnetPreferences.loggedIn() && NetworkUtils.networkAvailable(GpodnetSyncService.this)) {
|
||||||
|
if (AppConfig.DEBUG) Log.d(TAG, "Downloading changes");
|
||||||
|
try {
|
||||||
|
GpodnetService service = tryLogin();
|
||||||
|
GpodnetSubscriptionChange changes = service.getSubscriptionChanges(GpodnetPreferences.getUsername(), GpodnetPreferences.getDeviceID(), GpodnetPreferences.getLastSyncTimestamp());
|
||||||
|
if (AppConfig.DEBUG) Log.d(TAG, "Changes " + changes.toString());
|
||||||
|
|
||||||
|
GpodnetPreferences.setLastSyncTimestamp(changes.getTimestamp());
|
||||||
|
List<String> subscriptionList = DBReader.getFeedListDownloadUrls(GpodnetSyncService.this);
|
||||||
|
|
||||||
|
for (String downloadUrl : changes.getAdded()) {
|
||||||
|
if (!subscriptionList.contains(downloadUrl)) {
|
||||||
|
Feed feed = new Feed(downloadUrl, new Date());
|
||||||
|
DownloadRequester.getInstance().downloadFeed(GpodnetSyncService.this, feed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String downloadUrl : changes.getRemoved()) {
|
||||||
|
DBTasks.removeFeedWithDownloadUrl(GpodnetSyncService.this, downloadUrl);
|
||||||
|
}
|
||||||
|
} catch (GpodnetServiceException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
updateErrorNotification(e);
|
||||||
|
} catch (DownloadRequestException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void uploadChanges() {
|
||||||
|
if (GpodnetPreferences.loggedIn() && NetworkUtils.networkAvailable(GpodnetSyncService.this)) {
|
||||||
|
try {
|
||||||
|
if (AppConfig.DEBUG) Log.d(TAG, "Uploading subscription list");
|
||||||
|
GpodnetService service = tryLogin();
|
||||||
|
List<String> subscriptions = DBReader.getFeedListDownloadUrls(GpodnetSyncService.this);
|
||||||
|
|
||||||
|
if (AppConfig.DEBUG) Log.d(TAG, "Uploading subscriptions: " + subscriptions.toString());
|
||||||
|
|
||||||
|
service.uploadSubscriptions(GpodnetPreferences.getUsername(), GpodnetPreferences.getDeviceID(), subscriptions);
|
||||||
|
} catch (GpodnetServiceException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
updateErrorNotification(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateErrorNotification(GpodnetServiceException exception) {
|
||||||
|
if (AppConfig.DEBUG) Log.d(TAG, "Posting error notification");
|
||||||
|
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
|
||||||
|
final String title;
|
||||||
|
final String description;
|
||||||
|
final int id;
|
||||||
|
if (exception instanceof GpodnetServiceAuthenticationException) {
|
||||||
|
title = getString(R.string.gpodnetsync_auth_error_title);
|
||||||
|
description = getString(R.string.gpodnetsync_auth_error_descr);
|
||||||
|
id = R.id.notification_gpodnet_sync_autherror;
|
||||||
|
} else {
|
||||||
|
title = getString(R.string.gpodnetsync_error_title);
|
||||||
|
description = getString(R.string.gpodnetsync_error_descr) + exception.getMessage();
|
||||||
|
id = R.id.notification_gpodnet_sync_error;
|
||||||
|
}
|
||||||
|
Notification notification = builder.setContentTitle(title)
|
||||||
|
.setContentText(description)
|
||||||
|
.setSmallIcon(R.drawable.stat_notify_sync_error)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build();
|
||||||
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
nm.notify(id, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WaiterThread uploadWaiterThread = new WaiterThread(WAIT_INTERVAL) {
|
||||||
|
@Override
|
||||||
|
public void onWaitCompleted() {
|
||||||
|
uploadChanges();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private abstract class WaiterThread {
|
||||||
|
private long waitInterval;
|
||||||
|
private Thread thread;
|
||||||
|
|
||||||
|
private WaiterThread(long waitInterval) {
|
||||||
|
this.waitInterval = waitInterval;
|
||||||
|
reinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void onWaitCompleted();
|
||||||
|
|
||||||
|
public void exec() {
|
||||||
|
if (!thread.isAlive()) {
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reinit() {
|
||||||
|
if (thread != null && thread.isAlive()) {
|
||||||
|
Log.d(TAG, "Interrupting waiter thread");
|
||||||
|
thread.interrupt();
|
||||||
|
}
|
||||||
|
thread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(waitInterval);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (!isInterrupted()) {
|
||||||
|
synchronized (this) {
|
||||||
|
onWaitCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restart() {
|
||||||
|
reinit();
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void interrupt() {
|
||||||
|
if (thread != null && thread.isAlive()) {
|
||||||
|
thread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendActionDownloadIntent(Context context) {
|
||||||
|
if (GpodnetPreferences.loggedIn()) {
|
||||||
|
Intent intent = new Intent(context, GpodnetSyncService.class);
|
||||||
|
intent.putExtra(ARG_ACTION, ACTION_DOWNLOAD_CHANGES);
|
||||||
|
context.startService(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendActionUploadIntent(Context context) {
|
||||||
|
if (GpodnetPreferences.loggedIn()) {
|
||||||
|
Intent intent = new Intent(context, GpodnetSyncService.class);
|
||||||
|
intent.putExtra(ARG_ACTION, ACTION_UPLOAD_CHANGES);
|
||||||
|
context.startService(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendSyncIntent(Context context) {
|
||||||
|
if (GpodnetPreferences.loggedIn()) {
|
||||||
|
Intent intent = new Intent(context, GpodnetSyncService.class);
|
||||||
|
intent.putExtra(ARG_ACTION, ACTION_SYNC);
|
||||||
|
context.startService(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,6 +75,27 @@ public final class DBReader {
|
||||||
return feeds;
|
return feeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list with the download URLs of all feeds.
|
||||||
|
* @param context A context that is used for opening the database connection.
|
||||||
|
* @return A list of Strings with the download URLs of all feeds.
|
||||||
|
* */
|
||||||
|
public static List<String> getFeedListDownloadUrls(final Context context) {
|
||||||
|
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
adapter.open();
|
||||||
|
Cursor feeds = adapter.getFeedCursorDownloadUrls();
|
||||||
|
if (feeds.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
result.add(feeds.getString(1));
|
||||||
|
} while (feeds.moveToNext());
|
||||||
|
}
|
||||||
|
feeds.close();
|
||||||
|
adapter.close();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of 'expired Feeds', i.e. Feeds that have not been updated for a certain amount of time.
|
* Returns a list of 'expired Feeds', i.e. Feeds that have not been updated for a certain amount of time.
|
||||||
*
|
*
|
||||||
|
|
|
@ -23,6 +23,7 @@ import de.danoeh.antennapod.feed.FeedImage;
|
||||||
import de.danoeh.antennapod.feed.FeedItem;
|
import de.danoeh.antennapod.feed.FeedItem;
|
||||||
import de.danoeh.antennapod.feed.FeedMedia;
|
import de.danoeh.antennapod.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.preferences.UserPreferences;
|
import de.danoeh.antennapod.preferences.UserPreferences;
|
||||||
|
import de.danoeh.antennapod.service.GpodnetSyncService;
|
||||||
import de.danoeh.antennapod.service.PlaybackService;
|
import de.danoeh.antennapod.service.PlaybackService;
|
||||||
import de.danoeh.antennapod.service.download.DownloadStatus;
|
import de.danoeh.antennapod.service.download.DownloadStatus;
|
||||||
import de.danoeh.antennapod.util.DownloadError;
|
import de.danoeh.antennapod.util.DownloadError;
|
||||||
|
@ -39,6 +40,39 @@ public final class DBTasks {
|
||||||
private DBTasks() {
|
private DBTasks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the feed with the given download url. This method should NOT be executed on the GUI thread.
|
||||||
|
* @param context Used for accessing the db
|
||||||
|
* @param downloadUrl URL of the feed.
|
||||||
|
* */
|
||||||
|
public static void removeFeedWithDownloadUrl(Context context, String downloadUrl) {
|
||||||
|
PodDBAdapter adapter = new PodDBAdapter(context);
|
||||||
|
adapter.open();
|
||||||
|
Cursor cursor = adapter.getFeedCursorDownloadUrls();
|
||||||
|
long feedID = 0;
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
if (cursor.getString(1).equals(downloadUrl)) {
|
||||||
|
feedID = cursor.getLong(0);
|
||||||
|
}
|
||||||
|
} while (cursor.moveToNext());
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
adapter.close();
|
||||||
|
|
||||||
|
if (feedID != 0) {
|
||||||
|
try {
|
||||||
|
DBWriter.deleteFeed(context, feedID).get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "removeFeedWithDownloadUrl: Could not find feed with url: " + downloadUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts playback of a FeedMedia object's file. This method will build an Intent based on the given parameters to
|
* Starts playback of a FeedMedia object's file. This method will build an Intent based on the given parameters to
|
||||||
* start the {@link PlaybackService}.
|
* start the {@link PlaybackService}.
|
||||||
|
@ -110,6 +144,8 @@ public final class DBTasks {
|
||||||
refreshFeeds(context, DBReader.getFeedList(context));
|
refreshFeeds(context, DBReader.getFeedList(context));
|
||||||
}
|
}
|
||||||
isRefreshing.set(false);
|
isRefreshing.set(false);
|
||||||
|
|
||||||
|
GpodnetSyncService.sendSyncIntent(context);
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import android.util.Log;
|
||||||
import de.danoeh.antennapod.AppConfig;
|
import de.danoeh.antennapod.AppConfig;
|
||||||
import de.danoeh.antennapod.feed.*;
|
import de.danoeh.antennapod.feed.*;
|
||||||
import de.danoeh.antennapod.preferences.PlaybackPreferences;
|
import de.danoeh.antennapod.preferences.PlaybackPreferences;
|
||||||
|
import de.danoeh.antennapod.service.GpodnetSyncService;
|
||||||
import de.danoeh.antennapod.service.PlaybackService;
|
import de.danoeh.antennapod.service.PlaybackService;
|
||||||
import de.danoeh.antennapod.service.download.DownloadStatus;
|
import de.danoeh.antennapod.service.download.DownloadStatus;
|
||||||
import de.danoeh.antennapod.util.QueueAccess;
|
import de.danoeh.antennapod.util.QueueAccess;
|
||||||
|
@ -171,6 +172,8 @@ public class DBWriter {
|
||||||
}
|
}
|
||||||
adapter.removeFeed(feed);
|
adapter.removeFeed(feed);
|
||||||
adapter.close();
|
adapter.close();
|
||||||
|
|
||||||
|
GpodnetSyncService.sendActionUploadIntent(context);
|
||||||
EventDistributor.getInstance().sendFeedUpdateBroadcast();
|
EventDistributor.getInstance().sendFeedUpdateBroadcast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,6 +617,7 @@ public class DBWriter {
|
||||||
adapter.setCompleteFeed(feed);
|
adapter.setCompleteFeed(feed);
|
||||||
adapter.close();
|
adapter.close();
|
||||||
|
|
||||||
|
GpodnetSyncService.sendActionUploadIntent(context);
|
||||||
EventDistributor.getInstance().sendFeedUpdateBroadcast();
|
EventDistributor.getInstance().sendFeedUpdateBroadcast();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -659,6 +659,10 @@ public class PodDBAdapter {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final Cursor getFeedCursorDownloadUrls() {
|
||||||
|
return db.query(TABLE_NAME_FEEDS, new String[]{KEY_ID, KEY_DOWNLOAD_URL}, null, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public final Cursor getExpiredFeedsCursor(long expirationTime) {
|
public final Cursor getExpiredFeedsCursor(long expirationTime) {
|
||||||
Cursor c = db.query(TABLE_NAME_FEEDS, null, "?<?", new String[]{
|
Cursor c = db.query(TABLE_NAME_FEEDS, null, "?<?", new String[]{
|
||||||
KEY_LASTUPDATE, String.valueOf(System.currentTimeMillis() - expirationTime)}, null, null,
|
KEY_LASTUPDATE, String.valueOf(System.currentTimeMillis() - expirationTime)}, null, null,
|
||||||
|
|
|
@ -60,4 +60,10 @@ public class NetworkUtils {
|
||||||
Log.d(TAG, "Network for auto-dl is not available");
|
Log.d(TAG, "Network for auto-dl is not available");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean networkAvailable(Context context) {
|
||||||
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo info = cm.getActiveNetworkInfo();
|
||||||
|
return info != null && info.isConnected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue