diff --git a/News-Android-App/src/main/AndroidManifest.xml b/News-Android-App/src/main/AndroidManifest.xml index a06c0b40..dfeadf35 100644 --- a/News-Android-App/src/main/AndroidManifest.xml +++ b/News-Android-App/src/main/AndroidManifest.xml @@ -113,7 +113,9 @@ ********************************************************************** --> - + = 0) { //currently no actions for folders //String titel = dbConn.getFolderById(idFeed).getLabel(); - } + }*/ } else { String titel = dbConn.getFeedById(idFeed).getFeedTitle(); String iconurl = dbConn.getFeedById(idFeed).getFaviconUrl(); @@ -612,9 +613,9 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements { SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this); - if(mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, null) == null) + if(mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, null) == null) { StartLoginFragment(this); - else { + } else { if (!ownCloudSyncService.isSyncRunning()) { new PostDelayHandler(this).stopRunningPostDelayHandler();//Stop pending sync handler @@ -630,7 +631,6 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements } else { UpdateButtonLayout(); } - } } @@ -721,10 +721,12 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(this); long highestItemId = dbConn.getLowestRssItemIdUnread(); - Intent service = new Intent(this, DownloadImagesService.class); - service.putExtra(DownloadImagesService.LAST_ITEM_ID, highestItemId); - service.putExtra(DownloadImagesService.DOWNLOAD_MODE_STRING, DownloadImagesService.DownloadMode.PICTURES_ONLY); - startService(service); + + + Intent data = new Intent(); + data.putExtra(DownloadImagesService.LAST_ITEM_ID, highestItemId); + data.putExtra(DownloadImagesService.DOWNLOAD_MODE_STRING, DownloadImagesService.DownloadMode.PICTURES_ONLY); + DownloadImagesService.enqueueWork(this, data); break; diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/GetImageThreaded.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadImageHandler.java similarity index 73% rename from News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/GetImageThreaded.java rename to News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadImageHandler.java index 999bd7c8..f41f904d 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/GetImageThreaded.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadImageHandler.java @@ -34,37 +34,35 @@ import java.net.URL; import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished; -public class GetImageThreaded implements ImageLoadingListener +public class DownloadImageHandler implements ImageLoadingListener { private static final String TAG = "GetImageAsyncTask"; - private URL WEB_URL_TO_FILE; + private URL mImageUrl; private ImageDownloadFinished imageDownloadFinished; - private long ThreadId; private static final DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder() .cacheOnDisk(true) .build(); - public GetImageThreaded(String WEB_URL_TO_FILE, ImageDownloadFinished imgDownloadFinished, long ThreadId) { - try - { - this.WEB_URL_TO_FILE = new URL(WEB_URL_TO_FILE); - } - catch(Exception ex) - { - Log.d(TAG, "Invalid URL: " + WEB_URL_TO_FILE, ex); + public DownloadImageHandler(String imageUrl) { + try { + this.mImageUrl = new URL(imageUrl); + } catch(Exception ex) { + Log.d(TAG, "Invalid URL: " + imageUrl, ex); } - imageDownloadFinished = imgDownloadFinished; - this.ThreadId = ThreadId; - //this.imageViewReference = new WeakReference(imageView); + } - public void start() { - ImageLoader.getInstance().loadImage(WEB_URL_TO_FILE.toString(), displayImageOptions, this); - } + public void downloadSync() { + ImageLoader.getInstance().loadImageSync(mImageUrl.toString(), displayImageOptions); + } + public void downloadAsync(ImageDownloadFinished imgDownloadFinished) { + this.imageDownloadFinished = imgDownloadFinished; + ImageLoader.getInstance().loadImage(mImageUrl.toString(), displayImageOptions, this); + } @Override public void onLoadingStarted(String imageUri, View view) { @@ -89,7 +87,8 @@ public class GetImageThreaded implements ImageLoadingListener } private void NotifyDownloadFinished(Bitmap bitmap) { - if(imageDownloadFinished != null) - imageDownloadFinished.DownloadFinished(ThreadId, bitmap); + if(imageDownloadFinished != null) { + imageDownloadFinished.DownloadFinished(bitmap); + } } } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/broadcastreceiver/PodcastNotificationToggle.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/broadcastreceiver/PodcastNotificationToggle.java index afda802b..47b769a0 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/broadcastreceiver/PodcastNotificationToggle.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/broadcastreceiver/PodcastNotificationToggle.java @@ -19,7 +19,7 @@ public class PodcastNotificationToggle extends BroadcastReceiver { //TODO problem: only the headphone unplug event is triggered. Somehow the headphone plug-in event is not triggered at all.. //TODO expected: receive the headphone plug-in event and trigger the "play" event - if(intent.getAction().equals("android.media.AUDIO_BECOMING_NOISY")) { + if(intent.getAction() != null && intent.getAction().equals("android.media.AUDIO_BECOMING_NOISY")) { EventBus.getDefault().post(new TogglePlayerStateEvent(TogglePlayerStateEvent.State.Pause)); } else { EventBus.getDefault().post(new TogglePlayerStateEvent()); diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageDownloadFinished.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageDownloadFinished.java index f570f34b..b4fe6268 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageDownloadFinished.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageDownloadFinished.java @@ -25,5 +25,5 @@ package de.luhmer.owncloudnewsreader.helper; import android.graphics.Bitmap; public interface ImageDownloadFinished { - void DownloadFinished(long AsynkTaskId, Bitmap bitmap); + void DownloadFinished(Bitmap bitmap); } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationManagerNewsReader.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationManagerNewsReader.java index 6742640d..7af18094 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationManagerNewsReader.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationManagerNewsReader.java @@ -1,5 +1,6 @@ package de.luhmer.owncloudnewsreader.helper; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -10,18 +11,20 @@ import de.luhmer.owncloudnewsreader.NewsReaderListActivity; import de.luhmer.owncloudnewsreader.R; public class NotificationManagerNewsReader { + private static NotificationManagerNewsReader instance; private final int NOTIFICATION_ID = 0; + private final String CHANNEL_ID = "0"; private Context context; - public static NotificationManagerNewsReader getInstance(Context context) + public synchronized static NotificationManagerNewsReader getInstance(Context context) { if(instance == null) instance = new NotificationManagerNewsReader(context); return instance; } - public NotificationManagerNewsReader(Context context) + private NotificationManagerNewsReader(Context context) { this.context = context; //NOTIFICATION_ID = new Random().nextInt(); @@ -33,7 +36,7 @@ public class NotificationManagerNewsReader { public void ShowMessage(String title, String tickerMessage, String message) { NotificationCompat.Builder builder = - new NotificationCompat.Builder(context) + new NotificationCompat.Builder(context, "") .setSmallIcon(R.drawable.ic_notification) .setTicker(tickerMessage) .setContentTitle(title) @@ -63,6 +66,15 @@ public class NotificationManagerNewsReader { // Add as notification NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_LOW; + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance); + //mChannel.enableLights(true); + manager.createNotificationChannel(mChannel); + builder.setChannelId(CHANNEL_ID); + } + manager.notify(NOTIFICATION_ID, builder.build()); } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java index 3f540d66..24f919e5 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java @@ -21,14 +21,16 @@ package de.luhmer.owncloudnewsreader.services; -import android.app.IntentService; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.graphics.Bitmap; +import android.support.annotation.NonNull; +import android.support.v4.app.JobIntentService; import android.support.v4.app.NotificationCompat; +import android.util.Log; import android.widget.Toast; import com.nostra13.universalimageloader.core.ImageLoader; @@ -41,37 +43,48 @@ import java.util.Random; import de.greenrobot.dao.query.LazyList; import de.luhmer.owncloudnewsreader.NewsReaderListActivity; import de.luhmer.owncloudnewsreader.R; -import de.luhmer.owncloudnewsreader.async_tasks.GetImageThreaded; +import de.luhmer.owncloudnewsreader.async_tasks.DownloadImageHandler; import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm; import de.luhmer.owncloudnewsreader.database.model.Feed; import de.luhmer.owncloudnewsreader.database.model.RssItem; import de.luhmer.owncloudnewsreader.helper.FavIconHandler; -import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished; import de.luhmer.owncloudnewsreader.helper.ImageHandler; -public class DownloadImagesService extends IntentService { +public class DownloadImagesService extends JobIntentService { public static final String LAST_ITEM_ID = "LAST_ITEM_ID"; + private static final String TAG = DownloadImagesService.class.getCanonicalName(); + + public enum DownloadMode { FAVICONS_ONLY, PICTURES_ONLY, FAVICONS_AND_PICTURES } public static final String DOWNLOAD_MODE_STRING = "DOWNLOAD_MODE"; private static Random random; private int NOTIFICATION_ID = 1; - private NotificationManager notificationManager; + private NotificationManager mNotificationManager; private NotificationCompat.Builder mNotificationDownloadImages; + NotificationChannel mChannel; - private int maxCount; + private int maxCount; //private int total_size = 0; List linksToImages = new LinkedList<>(); - public DownloadImagesService() { - super(null); - } - public DownloadImagesService(String name) { - super(name); - } + /** + * Unique job/channel ID for this service. + */ + static final int JOB_ID = 1000; + static final String CHANNEL_ID = "1000"; + + /** + * Convenience method for enqueuing work in to this service. + */ + public static void enqueueWork(Context context, Intent work) { + enqueueWork(context, DownloadImagesService.class, JOB_ID, work); + } + + @Override public void onCreate() { @@ -84,23 +97,32 @@ public class DownloadImagesService extends IntentService { } catch (Exception ex) { ex.printStackTrace(); } + + + mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_LOW; + mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance); + //mChannel.enableLights(true); + mNotificationManager.createNotificationChannel(mChannel); + } } @Override public void onDestroy() { + Log.d(TAG, "onDestroy"); if(mNotificationDownloadImages != null) { if(maxCount == 0) - notificationManager.cancel(NOTIFICATION_ID); + mNotificationManager.cancel(NOTIFICATION_ID); } super.onDestroy(); } - @Override - protected void onHandleIntent(Intent intent) { + @Override + protected void onHandleWork(@NonNull Intent intent) { DownloadMode downloadMode = (DownloadMode) intent.getSerializableExtra(DOWNLOAD_MODE_STRING); - DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(this); Notification notify = BuildNotification(); @@ -119,7 +141,7 @@ public class DownloadImagesService extends IntentService { links.addAll(ImageHandler.getImageLinksFromText(body)); if(links.size() > 10000) { - notificationManager.notify(123, GetNotificationLimitImagesReached(10000)); + mNotificationManager.notify(123, GetNotificationLimitImagesReached(10000)); break; } } @@ -128,20 +150,22 @@ public class DownloadImagesService extends IntentService { maxCount = links.size(); if (maxCount > 0) { - notificationManager.notify(NOTIFICATION_ID, notify); + mNotificationManager.notify(NOTIFICATION_ID, notify); } linksToImages.addAll(links); - StartNextDownloadInQueue(); + downloadImages(); } } - private synchronized void StartNextDownloadInQueue() { + private void downloadImages() { try { - if(linksToImages.size() > 0) { + while(linksToImages.size() > 0) { String link = linksToImages.remove(0); - new GetImageThreaded(link, imgDownloadFinished, 999).start(); + new DownloadImageHandler(link).downloadSync(); + + updateNotificationProgress(); } } catch (Exception ex) { ex.printStackTrace(); @@ -149,15 +173,34 @@ public class DownloadImagesService extends IntentService { } } + private void updateNotificationProgress() { + int count = maxCount - linksToImages.size(); + if(maxCount == count) { + mNotificationManager.cancel(NOTIFICATION_ID); + //RemoveOldImages(); + } else { + mNotificationDownloadImages + .setContentText("Downloading Images for offline usage - " + (count + 1) + "/" + maxCount) + .setProgress(maxCount, count + 1, false); + + mNotificationManager.notify(NOTIFICATION_ID, mNotificationDownloadImages.build()); + } + } + private Notification GetNotificationLimitImagesReached(int limit) { Intent intentNewsReader = new Intent(this, NewsReaderListActivity.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intentNewsReader, 0); - NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this) + NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Nextcloud News") .setContentText("Only " + limit + " images can be cached at once") .setSmallIcon(R.drawable.ic_notification) .setContentIntent(pIntent); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + notifyBuilder.setChannelId(CHANNEL_ID); + } + Notification notify = notifyBuilder.build(); //Hide the notification after its selected @@ -168,14 +211,17 @@ public class DownloadImagesService extends IntentService { private Notification BuildNotification() { Intent intentNewsReader = new Intent(this, NewsReaderListActivity.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intentNewsReader, 0); - notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationDownloadImages = new NotificationCompat.Builder(this) + mNotificationDownloadImages = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(getResources().getString(R.string.app_name)) .setContentText("Downloading images for offline usage") .setSmallIcon(R.drawable.ic_notification) .setContentIntent(pIntent) .setOngoing(true); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + mNotificationDownloadImages.setChannelId(CHANNEL_ID); + } + Notification notify = mNotificationDownloadImages.build(); //Hide the notification after its selected @@ -189,24 +235,4 @@ public class DownloadImagesService extends IntentService { ImageLoader.getInstance().clearDiskCache(); } - ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() { - - @Override - public void DownloadFinished(long AsynkTaskId, Bitmap bitmap) { - int count = maxCount - linksToImages.size(); - - if(maxCount == count) { - notificationManager.cancel(NOTIFICATION_ID); - //RemoveOldImages(); - } else { - mNotificationDownloadImages - .setContentText("Downloading Images for offline usage - " + (count + 1) + "/" + maxCount) - .setProgress(maxCount, count + 1, false); - - notificationManager.notify(NOTIFICATION_ID, mNotificationDownloadImages.build()); - - StartNextDownloadInQueue(); - } - } - }; } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudSyncService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudSyncService.java index 5f19f74c..42c34d17 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudSyncService.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudSyncService.java @@ -146,13 +146,11 @@ public class OwnCloudSyncService extends Service { boolean stateSyncSuccessful; } - //Sync state of items e.g. read/unread/starred/unstarred + // Start sync private void start() { syncStopWatch = new StopWatch(); syncStopWatch.start(); - - //Delete all pinned/stored SSL Certificates /* final ArrayList aliases = Collections.list(mMTM.getCertificates()); @@ -164,15 +162,8 @@ public class OwnCloudSyncService extends Service { } }*/ - - - - final DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(OwnCloudSyncService.this); - - - Observable rssStateSync = Observable.fromPublisher( new Publisher() { @Override @@ -316,10 +307,9 @@ public class OwnCloudSyncService extends Service { } } - Intent service = new Intent(this, DownloadImagesService.class); - service.setPackage(getPackageName()); - service.putExtra(DownloadImagesService.DOWNLOAD_MODE_STRING, DownloadImagesService.DownloadMode.FAVICONS_ONLY); - startService(service); + Intent data = new Intent(); + data.putExtra(DownloadImagesService.DOWNLOAD_MODE_STRING, DownloadImagesService.DownloadMode.FAVICONS_ONLY); + DownloadImagesService.enqueueWork(OwnCloudSyncService.this, data); EventBus.getDefault().post(new SyncFinishedEvent()); } diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java index 3e7b21dc..5044b590 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java @@ -1,22 +1,19 @@ package de.luhmer.owncloudnewsreader.view; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.graphics.Bitmap; import android.media.AudioManager; -import android.media.session.MediaSessionManager; import android.os.Build; import android.support.v4.app.NotificationCompat; import android.support.v4.media.MediaMetadataCompat; -import android.support.v4.media.session.MediaControllerCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; import com.nostra13.universalimageloader.core.DisplayImageOptions; -import com.nostra13.universalimageloader.core.ImageLoader; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -43,10 +40,12 @@ public class PodcastNotification { private EventBus eventBus; private NotificationCompat.Builder notificationBuilder; private PendingIntent resultPendingIntent; + private String CHANNEL_ID = "1"; - private MediaSessionManager mManager; - public MediaSessionCompat mSession; - private MediaControllerCompat mController; + //private MediaSessionManager mManager; + private MediaSessionCompat mSession; + //private MediaControllerCompat mController; + private int lastDrawableId = -1; private final static int NOTIFICATION_ID = 1111; @@ -54,6 +53,13 @@ public class PodcastNotification { this.mContext = context; this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_LOW; + NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance); + //mChannel.enableLights(true); + this.notificationManager.createNotificationChannel(mChannel); + } + eventBus = EventBus.getDefault(); eventBus.register(this); } @@ -78,16 +84,18 @@ public class PodcastNotification { ); // Create the final Notification object. - notificationBuilder = new NotificationCompat.Builder(mContext) + notificationBuilder = new NotificationCompat.Builder(mContext, CHANNEL_ID) .setSmallIcon(R.drawable.ic_notification) .setAutoCancel(true) .setOngoing(true) .setContentIntent(resultPendingIntent); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + notificationBuilder.setChannelId(CHANNEL_ID); + } } - int lastDrawableId = -1; - @Subscribe public void onEvent(UpdatePodcastStatusEvent podcast) { if(mSession == null) @@ -216,6 +224,8 @@ public class PodcastNotification { } }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); + + //MediaControllerCompat controller = mSession.getController(); mSession.setActive(true); diff --git a/build.gradle b/build.gradle index 384b364f..005b3a49 100644 --- a/build.gradle +++ b/build.gradle @@ -14,5 +14,6 @@ allprojects { repositories { jcenter() maven { url "https://jitpack.io" } + maven { url "https://maven.google.com" } } } diff --git a/gradle.properties b/gradle.properties index 42128c31..62d65592 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,5 +19,5 @@ ANDROID_BUILD_MIN_SDK_VERSION=17 ANDROID_BUILD_TARGET_SDK_VERSION=26 -ANDROID_BUILD_TOOLS_VERSION=25.0.3 -ANDROID_BUILD_SDK_VERSION=25 \ No newline at end of file +ANDROID_BUILD_TOOLS_VERSION=26.0.2 +ANDROID_BUILD_SDK_VERSION=26 \ No newline at end of file