mirror of https://github.com/ThmmyNoLife/mTHMMY
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
8.2 KiB
226 lines
8.2 KiB
package gr.thmmy.mthmmy.services;
|
|
|
|
import android.app.DownloadManager;
|
|
import android.app.IntentService;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.os.Environment;
|
|
import android.support.annotation.NonNull;
|
|
import android.webkit.MimeTypeMap;
|
|
|
|
import java.io.File;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
|
|
import gr.thmmy.mthmmy.base.BaseApplication;
|
|
import gr.thmmy.mthmmy.receiver.Receiver;
|
|
import okhttp3.OkHttpClient;
|
|
import okhttp3.Request;
|
|
import okhttp3.Response;
|
|
import okio.BufferedSink;
|
|
import okio.Okio;
|
|
import timber.log.Timber;
|
|
|
|
/**
|
|
* An {@link IntentService} subclass for handling asynchronous task requests in
|
|
* a service on a separate handler thread.
|
|
*/
|
|
public class DownloadService extends IntentService {
|
|
private static final String TAG = "DownloadService";
|
|
private static int sDownloadId = 0;
|
|
|
|
private Receiver receiver;
|
|
|
|
public static final String SAVE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "mthmmy";
|
|
|
|
public static final String ACTION_DOWNLOAD = "gr.thmmy.mthmmy.services.action.DOWNLOAD";
|
|
public static final String EXTRA_DOWNLOAD_URL = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_URL";
|
|
|
|
public static final String EXTRA_DOWNLOAD_ID = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_ID";
|
|
public static final String EXTRA_DOWNLOAD_STATE = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_STATE";
|
|
public static final String EXTRA_FILE_NAME = "gr.thmmy.mthmmy.services.extra.FILE_NAME";
|
|
public static final String EXTRA_NOTIFICATION_TITLE = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TITLE";
|
|
public static final String EXTRA_NOTIFICATION_TEXT = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TEXT";
|
|
public static final String EXTRA_NOTIFICATION_TICKER = "gr.thmmy.mthmmy.services.extra.NOTIFICATION_TICKER";
|
|
|
|
public static final String STARTED = "Started";
|
|
public static final String COMPLETED = "Completed";
|
|
public static final String FAILED = "Failed";
|
|
|
|
|
|
public DownloadService() {
|
|
super("DownloadService");
|
|
}
|
|
|
|
@Override
|
|
public void onCreate() {
|
|
super.onCreate();
|
|
final IntentFilter filter = new IntentFilter(DownloadService.ACTION_DOWNLOAD);
|
|
receiver = new Receiver();
|
|
registerReceiver(receiver, filter);
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onDestroy() {
|
|
super.onDestroy();
|
|
this.unregisterReceiver(receiver);
|
|
}
|
|
|
|
/**
|
|
* Starts this service to perform action Download with the given parameters. If
|
|
* the service is already performing a task this action will be queued.
|
|
*
|
|
* @see IntentService
|
|
*/
|
|
public static void startActionDownload(Context context, String downloadUrl) {
|
|
Intent intent = new Intent(context, DownloadService.class);
|
|
intent.setAction(ACTION_DOWNLOAD);
|
|
intent.putExtra(EXTRA_DOWNLOAD_URL, downloadUrl);
|
|
context.startService(intent);
|
|
}
|
|
|
|
@Override
|
|
protected void onHandleIntent(Intent intent) {
|
|
if (intent != null) {
|
|
final String action = intent.getAction();
|
|
if (ACTION_DOWNLOAD.equals(action)) {
|
|
final String downloadLink = intent.getStringExtra(EXTRA_DOWNLOAD_URL);
|
|
handleActionDownload(downloadLink);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle action Foo in the provided background thread with the provided
|
|
* parameters.
|
|
*/
|
|
private void handleActionDownload(String downloadLink) {
|
|
OkHttpClient client = BaseApplication.getInstance().getClient();
|
|
BufferedSink sink = null;
|
|
String fileName = "file";
|
|
|
|
int downloadId = sDownloadId;
|
|
sDownloadId++;
|
|
|
|
try {
|
|
Request request = new Request.Builder().url(downloadLink).build();
|
|
Response response = client.newCall(request).execute();
|
|
|
|
String contentDisposition = response.headers("Content-Disposition").toString(); //check if link provides an attachment
|
|
if (contentDisposition.contains("attachment")) {
|
|
fileName = contentDisposition.split("\"")[1];
|
|
|
|
File dirPath = new File(SAVE_DIR);
|
|
if (!dirPath.isDirectory()) {
|
|
if (dirPath.mkdirs())
|
|
Timber.i("mTHMMY's directory created successfully!");
|
|
else
|
|
Timber.e("Couldn't create mTHMMY's directory...");
|
|
}
|
|
|
|
|
|
String nameFormat;
|
|
String[] tokens = fileName.split("\\.(?=[^\\.]+$)");
|
|
|
|
if (tokens.length != 2) {
|
|
Timber.w("Couldn't get file extension...");
|
|
nameFormat = fileName + "(%d)";
|
|
} else
|
|
nameFormat = tokens[0] + "(%d)." + tokens[1];
|
|
|
|
|
|
File file = new File(dirPath, fileName);
|
|
|
|
for (int i = 1; ; i++) {
|
|
if (!file.exists())
|
|
break;
|
|
|
|
file = new File(dirPath, String.format(nameFormat, i));
|
|
}
|
|
|
|
fileName = file.getName();
|
|
|
|
Timber.v("Started saving file %s", fileName);
|
|
sendNotification(downloadId, STARTED, fileName);
|
|
|
|
sink = Okio.buffer(Okio.sink(file));
|
|
sink.writeAll(response.body().source());
|
|
sink.flush();
|
|
Timber.i("Download OK!");
|
|
sendNotification(downloadId, COMPLETED, fileName);
|
|
|
|
// Register download
|
|
DownloadManager mManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
|
|
long length = file.length();
|
|
mManager.addCompletedDownload(fileName, fileName, false, getMimeType(file), SAVE_DIR +File.separator+ fileName, length, false);
|
|
|
|
} else
|
|
Timber.e("No attachment in response!");
|
|
} catch (FileNotFoundException e) {
|
|
Timber.i("Download failed...");
|
|
Timber.e(e, "FileNotFound");
|
|
sendNotification(downloadId, FAILED, fileName);
|
|
} catch (IOException e) {
|
|
Timber.i("Download failed...");
|
|
Timber.e(e, "IOException");
|
|
sendNotification(downloadId, FAILED, fileName);
|
|
} finally {
|
|
if (sink != null) {
|
|
try {
|
|
sink.close();
|
|
} catch (IOException e) {
|
|
// Ignore - Significant errors should already have been reported
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void sendNotification(int downloadId, String type, @NonNull String fileName) {
|
|
Intent intent = new Intent(ACTION_DOWNLOAD);
|
|
switch (type) {
|
|
case STARTED: {
|
|
intent.putExtra(EXTRA_NOTIFICATION_TITLE, "\"" + fileName + "\"");
|
|
intent.putExtra(EXTRA_NOTIFICATION_TEXT, "Download Started");
|
|
intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Downloading...");
|
|
break;
|
|
}
|
|
case COMPLETED: {
|
|
intent.putExtra(EXTRA_NOTIFICATION_TITLE, "\"" + fileName + "\"");
|
|
intent.putExtra(EXTRA_NOTIFICATION_TEXT, "Download Completed");
|
|
intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Completed");
|
|
break;
|
|
}
|
|
case FAILED: {
|
|
intent.putExtra(EXTRA_NOTIFICATION_TITLE, "\"" + fileName + "\"");
|
|
intent.putExtra(EXTRA_NOTIFICATION_TEXT, "Download Failed");
|
|
intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Failed");
|
|
break;
|
|
}
|
|
default: {
|
|
Timber.e("Invalid notification case!");
|
|
return;
|
|
}
|
|
}
|
|
intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId);
|
|
intent.putExtra(EXTRA_DOWNLOAD_STATE, type);
|
|
intent.putExtra(EXTRA_FILE_NAME, fileName);
|
|
sendBroadcast(intent);
|
|
|
|
}
|
|
|
|
@NonNull
|
|
static String getMimeType(@NonNull File file) {
|
|
String type = null;
|
|
final String url = file.toString();
|
|
final String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
|
if (extension != null)
|
|
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
|
if (type == null)
|
|
type = "*/*";
|
|
|
|
return type;
|
|
}
|
|
|
|
}
|
|
|