Skip to content

Commit c545ac4

Browse files
arihant-confluentoctacode
authored andcommitted
Offline feature improvements (#381)
* handles error in downloading for offline files * separate notifications for each complete offline file download
1 parent 6fc4298 commit c545ac4

File tree

6 files changed

+141
-30
lines changed

6 files changed

+141
-30
lines changed

src/main/java/org/amahi/anywhere/adapter/FilesFilterAdapter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ public void replaceWith(ServerShare serverShare, List<ServerFile> files) {
9494
}
9595

9696
public void removeFile(int position) {
97-
this.files.remove(position);
97+
ServerFile serverFile = filteredFiles.get(position);
98+
this.filteredFiles.remove(serverFile);
99+
this.files.remove(serverFile);
98100
notifyDataSetChanged();
99101
}
100102

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2014 Amahi
3+
*
4+
* This file is part of Amahi.
5+
*
6+
* Amahi is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Amahi is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Amahi. If not, see <http ://www.gnu.org/licenses/>.
18+
*/
19+
20+
package org.amahi.anywhere.bus;
21+
22+
public class OfflineCanceledEvent implements BusEvent {
23+
24+
private long downloadId;
25+
26+
public OfflineCanceledEvent(long downloadId) {
27+
this.downloadId = downloadId;
28+
}
29+
30+
public long getDownloadId() {
31+
return downloadId;
32+
}
33+
}

src/main/java/org/amahi/anywhere/fragment/ServerFilesFragment.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import org.amahi.anywhere.bus.BusProvider;
7171
import org.amahi.anywhere.bus.FileOpeningEvent;
7272
import org.amahi.anywhere.bus.FileOptionClickEvent;
73+
import org.amahi.anywhere.bus.OfflineCanceledEvent;
7374
import org.amahi.anywhere.bus.OfflineFileDeleteEvent;
7475
import org.amahi.anywhere.bus.ServerFileDeleteEvent;
7576
import org.amahi.anywhere.bus.ServerFileDownloadingEvent;
@@ -357,23 +358,26 @@ private void changeOfflineState(boolean enable) {
357358
}
358359

359360
private void deleteFileFromOfflineStorage() {
360-
OfflineFile offlineFile = mOfflineFileRepo.getOfflineFile(getShare().getName(), getCheckedFile().getPath(), getCheckedFile().getName());
361-
if (offlineFile.getState() == OfflineFile.DOWNLOADING) {
362-
stopDownloading(offlineFile.getDownloadId());
363-
}
364-
File file = new File(getContext().getFilesDir(), getCheckedFile().getName());
365-
if (file.exists()) {
366-
file.delete();
361+
OfflineFile offlineFile = mOfflineFileRepo.getOfflineFile(getCheckedFile().getName(), getCheckedFile().getModificationTime().getTime());
362+
if (offlineFile != null) {
363+
if (offlineFile.getState() == OfflineFile.DOWNLOADING) {
364+
stopDownloading(offlineFile.getDownloadId());
365+
}
366+
File file = new File(getContext().getFilesDir(), getCheckedFile().getName());
367+
if (file.exists()) {
368+
file.delete();
369+
}
370+
mOfflineFileRepo.delete(offlineFile);
371+
Snackbar.make(getRecyclerView(), R.string.message_offline_file_deleted, Snackbar.LENGTH_SHORT)
372+
.show();
367373
}
368-
mOfflineFileRepo.delete(offlineFile);
369-
Snackbar.make(getRecyclerView(), R.string.message_offline_file_deleted, Snackbar.LENGTH_SHORT)
370-
.show();
371374
}
372375

373-
private void stopDownloading(long downloadID) {
376+
private void stopDownloading(long downloadId) {
374377
DownloadManager dm = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
375378
if (dm != null) {
376-
dm.remove(downloadID);
379+
dm.remove(downloadId);
380+
BusProvider.getBus().post(new OfflineCanceledEvent(downloadId));
377381
}
378382
}
379383

src/main/java/org/amahi/anywhere/service/DownloadService.java

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.amahi.anywhere.service;
22

3+
import android.app.DownloadManager;
34
import android.app.Notification;
45
import android.app.NotificationManager;
56
import android.app.Service;
@@ -9,6 +10,7 @@
910
import android.net.Uri;
1011
import android.os.Build;
1112
import android.os.IBinder;
13+
import android.support.annotation.NonNull;
1214
import android.support.annotation.Nullable;
1315
import android.util.Log;
1416

@@ -18,6 +20,7 @@
1820
import org.amahi.anywhere.R;
1921
import org.amahi.anywhere.bus.BusProvider;
2022
import org.amahi.anywhere.bus.FileMovedEvent;
23+
import org.amahi.anywhere.bus.OfflineCanceledEvent;
2124
import org.amahi.anywhere.db.entities.OfflineFile;
2225
import org.amahi.anywhere.db.repositories.OfflineFileRepository;
2326
import org.amahi.anywhere.job.NetConnectivityJob;
@@ -30,13 +33,17 @@
3033
import org.amahi.anywhere.util.NetworkUtils;
3134

3235
import java.io.File;
36+
import java.util.List;
3337

3438
import javax.inject.Inject;
3539

3640
import static org.amahi.anywhere.util.Downloader.OFFLINE_PATH;
3741

3842
public class DownloadService extends Service implements Downloader.DownloadCallbacks {
3943

44+
private static final int NOTIFICATION_OFFLINE_ID = 101;
45+
private static final int NOTIFICATION_ERROR_ID = 101;
46+
4047
@Inject
4148
ServerClient serverClient;
4249

@@ -113,7 +120,7 @@ public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
113120
scheduleNetworkConnectivityJob();
114121
}
115122

116-
return START_NOT_STICKY;
123+
return START_STICKY;
117124
}
118125

119126
private void startNextDownload() {
@@ -125,6 +132,7 @@ private void startNextDownload() {
125132
isDownloading = true;
126133
} else {
127134
stopDownloading();
135+
stopForeground(true);
128136
}
129137
}
130138

@@ -142,12 +150,12 @@ private void resumeDownload(long downloadId, String fileName) {
142150
notificationBuilder
143151
.setOngoing(true)
144152
.setSmallIcon(R.drawable.ic_app_logo)
145-
.setContentTitle(getString(R.string.notification_download_title))
153+
.setContentTitle(getString(R.string.notification_download_offline_title))
146154
.setContentText(getString(R.string.notification_upload_message, fileName))
147155
.setProgress(100, 0, false)
148156
.build();
149157
Notification notification = notificationBuilder.build();
150-
startForeground((int) downloadId, notification);
158+
startForeground(NOTIFICATION_OFFLINE_ID, notification);
151159
downloader.setDownloadCallbacks(this);
152160
downloader.resumeProgressCount(downloadId);
153161
}
@@ -194,12 +202,12 @@ public void downloadStarted(int id, String fileName) {
194202
notificationBuilder
195203
.setOngoing(true)
196204
.setSmallIcon(R.drawable.ic_app_logo)
197-
.setContentTitle(getString(R.string.notification_download_title))
205+
.setContentTitle(getString(R.string.notification_download_offline_title))
198206
.setContentText(getString(R.string.notification_upload_message, fileName))
199207
.setProgress(100, 0, false)
200208
.build();
201209
Notification notification = notificationBuilder.build();
202-
startForeground(id, notification);
210+
startForeground(NOTIFICATION_OFFLINE_ID, notification);
203211
}
204212

205213
@Override
@@ -209,19 +217,34 @@ public void downloadProgress(int id, int progress) {
209217
notificationBuilder
210218
.setProgress(100, progress, false);
211219
Notification notification = notificationBuilder.build();
212-
notificationManager.notify(id, notification);
220+
notificationManager.notify(NOTIFICATION_OFFLINE_ID, notification);
213221
}
214222

215223
@Override
216224
public void downloadSuccess(long id) {
217225
OfflineFile offlineFile = offlineFileRepository.getFileWithDownloadId(id);
218226
if (offlineFile != null) {
219227
moveFileInOfflineDirectory(offlineFile.getName());
228+
showDownloadedNotification(offlineFile);
220229
} else {
221230
stopForeground(true);
222231
}
223232
}
224233

234+
private void showDownloadedNotification(@NonNull OfflineFile offlineFile) {
235+
NotificationManager notificationManager = (NotificationManager) getApplicationContext()
236+
.getSystemService(Context.NOTIFICATION_SERVICE);
237+
238+
notificationBuilder
239+
.setContentTitle(getString(R.string.notification_offline_download_complete))
240+
.setContentText(getString(R.string.notification_upload_message, offlineFile.getName()))
241+
.setOngoing(false);
242+
243+
Notification notification = notificationBuilder.build();
244+
notificationManager.cancel(NOTIFICATION_OFFLINE_ID);
245+
notificationManager.notify((int) offlineFile.getTimeStamp(), notification);
246+
}
247+
225248
@Subscribe
226249
public void onFileMoved(FileMovedEvent event) {
227250
OfflineFile offlineFile = offlineFileRepository.getCurrentDownloadingFile();
@@ -237,7 +260,7 @@ public void onFileMoved(FileMovedEvent event) {
237260
.setProgress(100, 100, false);
238261

239262
Notification notification = notificationBuilder.build();
240-
notificationManager.notify((int) offlineFile.getDownloadId(), notification);
263+
notificationManager.notify(NOTIFICATION_OFFLINE_ID, notification);
241264

242265
offlineFile.setState(OfflineFile.DOWNLOADED);
243266
offlineFile.setDownloadId(-1);
@@ -261,7 +284,38 @@ private void moveFileInOfflineDirectory(String fileName) {
261284

262285
@Override
263286
public void downloadError(long id) {
287+
removeFromDownloader(id);
288+
stopNotification();
289+
showErrorNotification(id);
264290
removeOfflineFile(id);
291+
startNextDownload();
292+
}
293+
294+
private void removeFromDownloader(long id) {
295+
DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
296+
if (dm != null) {
297+
dm.remove(id);
298+
}
299+
}
300+
301+
private void showErrorNotification(long id) {
302+
OfflineFile offlineFile = offlineFileRepository.getFileWithDownloadId(id);
303+
if (offlineFile != null) {
304+
NotificationManager notificationManager = (NotificationManager) getApplicationContext()
305+
.getSystemService(Context.NOTIFICATION_SERVICE);
306+
307+
notificationBuilder
308+
.setContentTitle(getString(R.string.notification_offline_download_error))
309+
.setContentText(getString(R.string.notification_upload_message, offlineFile.getName()))
310+
.setOngoing(false);
311+
312+
Notification notification = notificationBuilder.build();
313+
notificationManager.notify((int) offlineFile.getTimeStamp(), notification);
314+
}
315+
}
316+
317+
private void stopNotification() {
318+
stopForeground(true);
265319
}
266320

267321
@Override
@@ -276,19 +330,32 @@ public void downloadPaused(long downloadId, int progress) {
276330
.setProgress(100, progress, false);
277331

278332
Notification notification = notificationBuilder.build();
279-
notificationManager.notify((int) downloadId, notification);
333+
notificationManager.notify(NOTIFICATION_OFFLINE_ID, notification);
280334

281335
stopDownloading();
282336
}
283337

284338
private void removeOfflineFile(long id) {
285339
OfflineFile offlineFile = offlineFileRepository.getFileWithDownloadId(id);
286-
offlineFileRepository.delete(offlineFile);
340+
if (offlineFile != null) {
341+
offlineFileRepository.delete(offlineFile);
342+
}
287343
}
288344

289345
private void scheduleNetworkConnectivityJob() {
290346
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
291347
NetConnectivityJob.scheduleJob(this);
292348
}
293349
}
350+
351+
@Subscribe
352+
public void onDownloadCanceled(OfflineCanceledEvent event) {
353+
stopForeground(true);
354+
List<OfflineFile> offlineFiles = offlineFileRepository.getAllOfflineFiles();
355+
if (offlineFiles.isEmpty()) {
356+
stopDownloading();
357+
} else if (event.getDownloadId() != -1) {
358+
startNextDownload();
359+
}
360+
}
294361
}

src/main/java/org/amahi/anywhere/util/Downloader.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private void startDownloading(Uri downloadUri, String downloadName, @FileOption.
9191
if (file.exists())
9292
file.delete();
9393

94-
downloadRequest.setVisibleInDownloadsUi(false)
94+
downloadRequest.setVisibleInDownloadsUi(true)
9595
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
9696

9797
this.downloadId = getDownloadManager(context).enqueue(downloadRequest);
@@ -128,8 +128,8 @@ public long startDownloadingForOfflineMode(Uri downloadUri, String downloadName)
128128
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
129129

130130
long id = getDownloadManager(context).enqueue(downloadRequest);
131-
startProgressCount(id);
132131
downloadCallbacks.downloadStarted((int) id, downloadName);
132+
startProgressCount(id);
133133
return id;
134134
}
135135

@@ -235,18 +235,21 @@ public void run() {
235235
Cursor cursor = getDownloadManager(context).query(q);
236236
if (cursor != null && cursor.moveToFirst()) {
237237
cursor.moveToFirst();
238-
int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
239-
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
240-
int progress = bytes_total != 0 ? 100 * bytes_downloaded / bytes_total : 0;
241-
downloadCallbacks.downloadProgress((int) id, progress);
238+
long bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
239+
long bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
240+
long progress = bytes_total != 0 ? (100 * bytes_downloaded) / bytes_total : 0;
241+
downloadCallbacks.downloadProgress((int) id, (int) progress);
242242

243243
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
244244
switch (status) {
245245

246246
case DownloadManager.STATUS_PAUSED:
247247
if (!(isNetworkAvailable())) {
248248
isDownloading = false;
249-
downloadCallbacks.downloadPaused(id, progress);
249+
downloadCallbacks.downloadPaused(id, (int) progress);
250+
} else {
251+
downloadCallbacks.downloadError(id);
252+
isDownloading = false;
250253
}
251254

252255
break;

src/main/res/values/strings.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,10 @@
9797
<string name="message_file_download_complete">File downloaded successfully</string>
9898
<string name="message_offline_file_deleted">Offline file removed successfully</string>
9999
<string name="notification_download_title">Downloading File</string>
100-
<string name="notification_offline_download_complete">File Available Offline</string>
100+
<string name="notification_download_offline_title">Making available offline</string>
101+
<string name="notification_offline_download_complete">File available offline</string>
101102
<string name="notification_offline_download_paused">Waiting for internet</string>
103+
<string name="notification_offline_download_error">Error while making file available offline</string>
102104

103105
<string name="share_subject">Check out my Amahi home server!</string>
104106
<string name="share_message">I use the Amahi Home Server for storing, backing up and streaming all my files.\n\nCheck it out!\n\n<a href="https://www.amahi.org/">https://www.amahi.org/</a></string>

0 commit comments

Comments
 (0)