package com.wangdaye.mysplash.common.utils.helper;
import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.view.View;
import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;
import com.liulishuo.filedownloader.model.FileDownloadStatus;
import com.wangdaye.mysplash.Mysplash;
import com.wangdaye.mysplash.R;
import com.wangdaye.mysplash.common.data.entity.item.DownloadMission;
import com.wangdaye.mysplash.common.data.entity.unsplash.Collection;
import com.wangdaye.mysplash.common.data.entity.unsplash.Photo;
import com.wangdaye.mysplash.common.data.entity.table.DownloadMissionEntity;
import com.wangdaye.mysplash.common.utils.FileUtils;
import java.util.List;
/**
* Download helper.
* */
public class DownloadHelper {
// data
private boolean foreground;
public static final int DOWNLOAD_TYPE = 1;
public static final int SHARE_TYPE = 2;
public static final int WALLPAPER_TYPE = 3;
public static final int COLLECTION_TYPE = 4;
public static final int RESULT_SUCCEED = 1;
public static final int RESULT_FAILED = -1;
public static final int RESULT_DOWNLOADING = 0;
/** <br> singleton. */
private static DownloadHelper instance;
public static DownloadHelper getInstance() {
if (instance == null) {
synchronized (DownloadHelper.class) {
if (instance == null) {
instance = new DownloadHelper();
}
}
}
return instance;
}
/** <br> life cycle. */
private DownloadHelper() {
foreground = false;
}
public void init(Context context) {
FileDownloader.init(context);
}
public void setServiceAlive(boolean alive) {
if (alive) {
FileDownloader.getImpl().bindService();
} else {
FileDownloader.getImpl().unBindServiceIfIdle();
}
}
void setForeground(Notification notification) {
if (notification != null) {
if (!foreground) {
foreground = true;
FileDownloader.getImpl()
.startForeground(
NotificationHelper.DOWNLOAD_NOTIFICATION_ID,
notification);
}
}
}
void stopForeground() {
foreground = false;
FileDownloader.getImpl().stopForeground(true);
}
/** <br> data. */
// insert.
public void addMission(Context c, Photo p, int type) {
if (FileUtils.createDownloadPath(c)) {
addMission(c, new DownloadMissionEntity(p, type));
}
}
public void addMission(Context c, Collection collection) {
if (FileUtils.createDownloadPath(c)) {
addMission(c, new DownloadMissionEntity(collection));
}
}
private long addMission(Context c, DownloadMissionEntity entity) {
FileUtils.deleteFile(entity);
final OnDownloadListener listener = new OnDownloadListener(c.getApplicationContext(), entity);
entity.missionId = FileDownloader.getImpl()
.create(entity.downloadUrl)
.setPath(entity.getFilePath())
.setCallbackProgressMinInterval(NotificationHelper.REFRESH_RATE)
.setListener(listener)
.asInQueueTask()
.enqueue();
FileDownloader.getImpl().start(listener, false);
entity.result = DownloadHelper.RESULT_DOWNLOADING;
DatabaseHelper.getInstance(c).writeDownloadEntity(entity);
NotificationHelper.showSnackbar(
c.getString(R.string.feedback_download_start),
Snackbar.LENGTH_SHORT);
return entity.missionId;
}
@Nullable
public DownloadMission restartMission(Context c, long missionId) {
DownloadMissionEntity entity = DatabaseHelper.getInstance(c).readDownloadEntity(missionId);
if (entity == null) {
return null;
} else {
FileDownloader.getImpl()
.clear((int) missionId, entity.getFilePath());
DatabaseHelper.getInstance(c).deleteDownloadEntity(missionId);
DownloadMission mission = new DownloadMission(entity);
mission.entity.missionId = addMission(c, mission.entity);
mission.entity.result = RESULT_DOWNLOADING;
mission.process = 0;
return mission;
}
}
// delete.
public void removeMission(Context c, long id) {
DownloadMissionEntity entity = DatabaseHelper.getInstance(c).readDownloadEntity(id);
if (entity != null && entity.result != RESULT_SUCCEED) {
FileDownloader.getImpl()
.clear((int) id, entity.getFilePath());
}
DatabaseHelper.getInstance(c).deleteDownloadEntity(id);
}
public void clearMission(Context c, List<DownloadMissionEntity> entityList, boolean clearDatabase) {
for (int i = 0; i < entityList.size(); i ++) {
if (entityList.get(i).result != RESULT_SUCCEED) {
FileDownloader.getImpl()
.clear(
(int) entityList.get(i).missionId,
entityList.get(i).getFilePath());
}
}
FileDownloader.getImpl().clearAllTaskData();
if (clearDatabase) {
DatabaseHelper.getInstance(c).clearDownloadEntity();
}
}
// update.
public void updateMissionResult(Context c, long id, int result) {
DownloadMissionEntity entity = DatabaseHelper.getInstance(c).readDownloadEntity(id);
if (entity != null) {
entity.result = result;
DatabaseHelper.getInstance(c).updateDownloadEntity(entity);
}
}
// query.
@Nullable
public DownloadMission getDownloadMission(Context context, long id) {
DownloadMissionEntity entity = DatabaseHelper.getInstance(context).readDownloadEntity(id);
if (entity == null) {
return null;
} else {
entity.result = getDownloadResult(entity);
float process = getMissionProcess(entity);
return new DownloadMission(entity, process);
}
}
private int getDownloadResult(DownloadMissionEntity entity) {
switch (FileDownloader.getImpl().getStatus((int) entity.missionId, entity.getFilePath())) {
case FileDownloadStatus.completed:
return RESULT_SUCCEED;
case FileDownloadStatus.error:
case FileDownloadStatus.warn:
case FileDownloadStatus.paused:
return RESULT_FAILED;
default:
return RESULT_DOWNLOADING;
}
}
private float getMissionProcess(DownloadMissionEntity entity) {
long soFar = FileDownloader.getImpl().getSoFar((int) entity.missionId);
long total = FileDownloader.getImpl().getTotal((int) entity.missionId);
return (int) (100.0 * soFar / total);
}
boolean isMissionSuccess(Context context, long id) {
DownloadMissionEntity entity = DatabaseHelper.getInstance(context).readDownloadEntity(id);
return entity == null || getDownloadResult(entity) == RESULT_SUCCEED;
}
}
class OnDownloadListener extends FileDownloadListener {
// data
private Context context;
private String title;
private long soFar;
private long total;
/** <br> life cycle. */
OnDownloadListener(Context context, DownloadMissionEntity entity) {
this.context = context;
this.title = entity.getRealTitle();
this.soFar = this.total = 0;
}
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
Notification notification = NotificationHelper.getInstance(context)
.sendDownloadProgressNotification(title, soFarBytes - soFar, totalBytes - total, true, false);
DownloadHelper.getInstance().setForeground(notification);
soFar = soFarBytes;
total = totalBytes;
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
Notification notification = NotificationHelper.getInstance(context)
.sendDownloadProgressNotification(title, soFarBytes - soFar, totalBytes - total, false, false);
DownloadHelper.getInstance().setForeground(notification);
soFar = soFarBytes;
total = totalBytes;
}
@Override
protected void completed(BaseDownloadTask task) {
downloadFinish(task.getId());
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
downloadFinish(task.getId());
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
downloadFinish(task.getId());
}
@Override
protected void warn(BaseDownloadTask task) {
downloadFinish(task.getId());
}
/** <br> data. */
private void downloadFinish(int missionId) {
DownloadMissionEntity entity = DatabaseHelper.getInstance(context)
.readDownloadEntity(missionId);
if (DownloadHelper.getInstance().isMissionSuccess(context, missionId)) {
if (entity != null) {
if (entity.downloadType != DownloadHelper.COLLECTION_TYPE) {
downloadPhotoSuccess(context, entity);
} else {
downloadCollectionSuccess(context, entity);
}
DownloadHelper.getInstance()
.updateMissionResult(context, entity.missionId, DownloadHelper.RESULT_SUCCEED);
}
} else if (entity != null) {
if (entity.downloadType != DownloadHelper.COLLECTION_TYPE) {
downloadPhotoFailed(context, entity);
} else {
downloadCollectionFailed(context, entity);
}
DownloadHelper.getInstance()
.updateMissionResult(context, entity.missionId, DownloadHelper.RESULT_FAILED);
}
Notification notification = NotificationHelper.getInstance(context)
.sendDownloadProgressNotification(title, -soFar, -total, true, true);
if (notification != null) {
DownloadHelper.getInstance().setForeground(notification);
} else {
DownloadHelper.getInstance().stopForeground();
}
DownloadHelper.getInstance().setServiceAlive(false);
}
private void downloadPhotoSuccess(Context c, DownloadMissionEntity entity) {
c.sendBroadcast(
new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + entity.getFilePath())));
if (Mysplash.getInstance() != null
&& Mysplash.getInstance().getTopActivity() != null) {
switch (entity.downloadType) {
case DownloadHelper.DOWNLOAD_TYPE:
simpleDownloadSuccess(entity);
break;
case DownloadHelper.SHARE_TYPE: {
shareDownloadSuccess(entity);
break;
}
case DownloadHelper.WALLPAPER_TYPE: {
wallpaperDownloadSuccess(entity);
break;
}
}
} else {
NotificationHelper.sendDownloadPhotoSuccessNotification(c, entity);
}
}
private void simpleDownloadSuccess(DownloadMissionEntity entity) {
Context c = Mysplash.getInstance().getTopActivity();
NotificationHelper.showActionSnackbar(
c.getString(R.string.feedback_download_photo_success),
c.getString(R.string.check),
Snackbar.LENGTH_LONG,
new OnCheckPhotoListener(Mysplash.getInstance().getTopActivity(), entity.title));
}
private void shareDownloadSuccess(DownloadMissionEntity entity) {
// Uri file = Uri.parse("file://" + entity.getFilePath());
Uri file = FileUtils.filePathToUri(context, entity.getFilePath());
Intent action = new Intent(Intent.ACTION_SEND);
action.putExtra(Intent.EXTRA_STREAM, file);
action.setType("image/*");
Mysplash.getInstance()
.getTopActivity()
.startActivity(
Intent.createChooser(
action,
Mysplash.getInstance()
.getString(R.string.feedback_choose_share_app)));
}
private void wallpaperDownloadSuccess(DownloadMissionEntity entity) {
// Uri file = Uri.parse("file://" + entity.getFilePath());
Uri file = FileUtils.filePathToUri(context, entity.getFilePath());
Intent action = new Intent(Intent.ACTION_ATTACH_DATA);
action.setDataAndType(file, "image/jpg");
action.putExtra("mimeType", "image/jpg");
Mysplash.getInstance()
.getTopActivity()
.startActivity(
Intent.createChooser(
action,
Mysplash.getInstance()
.getString(R.string.feedback_choose_wallpaper_app)));
}
private void downloadCollectionSuccess(Context c, DownloadMissionEntity entity) {
if (Mysplash.getInstance() != null
&& Mysplash.getInstance().getTopActivity() != null) {
NotificationHelper.showActionSnackbar(
c.getString(R.string.feedback_download_collection_success),
c.getString(R.string.check),
Snackbar.LENGTH_LONG,
new OnCheckCollectionListener(c, entity.title));
} else {
NotificationHelper.sendDownloadCollectionSuccessNotification(c, entity);
}
}
private void downloadPhotoFailed(Context c, DownloadMissionEntity entity) {
if (Mysplash.getInstance() != null
&& Mysplash.getInstance().getTopActivity() != null) {
NotificationHelper.showActionSnackbar(
c.getString(R.string.feedback_download_photo_failed),
c.getString(R.string.check),
Snackbar.LENGTH_LONG,
onStartManageActivityListener);
} else {
NotificationHelper.sendDownloadPhotoFailedNotification(c, entity);
}
}
private void downloadCollectionFailed(Context c, DownloadMissionEntity entity) {
if (Mysplash.getInstance() != null
&& Mysplash.getInstance().getTopActivity() != null) {
NotificationHelper.showActionSnackbar(
c.getString(R.string.feedback_download_collection_failed),
c.getString(R.string.check),
Snackbar.LENGTH_LONG,
onStartManageActivityListener);
} else {
NotificationHelper.sendDownloadCollectionFailedNotification(c, entity);
}
}
/** <br> interface. */
private class OnCheckPhotoListener implements View.OnClickListener {
// widget
private Context c;
// data
private String title;
// life cycle.
OnCheckPhotoListener(Context c, String title) {
this.c = c;
this.title = title;
}
@Override
public void onClick(View v) {
IntentHelper.startCheckPhotoActivity(c, title);
}
}
private class OnCheckCollectionListener implements View.OnClickListener {
// widget
private Context c;
// data
private String title;
// life cycle.
OnCheckCollectionListener(Context c, String title) {
this.c = c;
this.title = title;
}
@Override
public void onClick(View v) {
IntentHelper.startCheckCollectionActivity(c, title);
}
}
private View.OnClickListener onStartManageActivityListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
IntentHelper.startDownloadManageActivity(Mysplash.getInstance().getTopActivity());
}
};
}