2016-04-21 20:28:01 -03:00
|
|
|
package us.shandian.giga.service;
|
|
|
|
|
2017-01-10 13:35:16 +01:00
|
|
|
import android.Manifest;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.app.Notification;
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
import android.app.Service;
|
2017-01-10 11:41:24 +01:00
|
|
|
import android.content.Context;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.content.Intent;
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
|
|
import android.graphics.drawable.Drawable;
|
2017-01-10 11:41:24 +01:00
|
|
|
import android.net.Uri;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.os.Binder;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.HandlerThread;
|
|
|
|
import android.os.IBinder;
|
|
|
|
import android.os.Message;
|
|
|
|
import android.support.v4.app.NotificationCompat.Builder;
|
2017-06-28 07:27:32 +02:00
|
|
|
import android.support.v4.content.ContextCompat;
|
2017-01-10 13:35:16 +01:00
|
|
|
import android.support.v4.content.PermissionChecker;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.util.Log;
|
2017-01-10 13:35:16 +01:00
|
|
|
import android.widget.Toast;
|
2016-04-21 20:28:01 -03:00
|
|
|
|
2017-01-10 11:41:24 +01:00
|
|
|
import org.schabi.newpipe.R;
|
2016-09-27 21:33:26 +02:00
|
|
|
import org.schabi.newpipe.download.DownloadActivity;
|
2016-08-02 21:17:54 +02:00
|
|
|
import org.schabi.newpipe.settings.NewPipeSettings;
|
2017-01-10 11:41:24 +01:00
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import us.shandian.giga.get.DownloadDataSource;
|
2016-04-21 20:28:01 -03:00
|
|
|
import us.shandian.giga.get.DownloadManager;
|
|
|
|
import us.shandian.giga.get.DownloadManagerImpl;
|
|
|
|
import us.shandian.giga.get.DownloadMission;
|
2017-01-10 11:41:24 +01:00
|
|
|
import us.shandian.giga.get.sqlite.SQLiteDownloadDataSource;
|
|
|
|
|
2016-04-21 20:28:01 -03:00
|
|
|
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
|
|
|
|
2017-06-28 07:27:32 +02:00
|
|
|
public class DownloadManagerService extends Service {
|
|
|
|
|
|
|
|
private static final String TAG = DownloadManagerService.class.getSimpleName();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Message code of update messages stored as {@link Message#what}.
|
|
|
|
*/
|
|
|
|
private static final int UPDATE_MESSAGE = 0;
|
|
|
|
private static final int NOTIFICATION_ID = 1000;
|
|
|
|
private static final String EXTRA_NAME = "DownloadManagerService.extra.name";
|
|
|
|
private static final String EXTRA_LOCATION = "DownloadManagerService.extra.location";
|
|
|
|
private static final String EXTRA_IS_AUDIO = "DownloadManagerService.extra.is_audio";
|
|
|
|
private static final String EXTRA_THREADS = "DownloadManagerService.extra.threads";
|
|
|
|
|
|
|
|
|
|
|
|
private DMBinder mBinder;
|
|
|
|
private DownloadManager mManager;
|
|
|
|
private Notification mNotification;
|
|
|
|
private Handler mHandler;
|
|
|
|
private long mLastTimeStamp = System.currentTimeMillis();
|
|
|
|
private DownloadDataSource mDataSource;
|
|
|
|
|
|
|
|
|
|
|
|
private MissionListener missionListener = new MissionListener();
|
|
|
|
|
|
|
|
|
|
|
|
private void notifyMediaScanner(DownloadMission mission) {
|
|
|
|
Uri uri = Uri.parse("file://" + mission.location + "/" + mission.name);
|
|
|
|
// notify media scanner on downloaded media file ...
|
|
|
|
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreate() {
|
|
|
|
super.onCreate();
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "onCreate");
|
|
|
|
}
|
|
|
|
|
|
|
|
mBinder = new DMBinder();
|
|
|
|
if (mDataSource == null) {
|
|
|
|
mDataSource = new SQLiteDownloadDataSource(this);
|
|
|
|
}
|
|
|
|
if (mManager == null) {
|
|
|
|
ArrayList<String> paths = new ArrayList<>(2);
|
|
|
|
paths.add(NewPipeSettings.getVideoDownloadPath(this));
|
|
|
|
paths.add(NewPipeSettings.getAudioDownloadPath(this));
|
|
|
|
mManager = new DownloadManagerImpl(paths, mDataSource);
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "mManager == null");
|
|
|
|
Log.d(TAG, "Download directory: " + paths);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-29 12:02:21 +02:00
|
|
|
Intent openDownloadListIntent = new Intent(this, DownloadActivity.class)
|
|
|
|
.setAction(Intent.ACTION_MAIN);
|
|
|
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
|
|
|
|
openDownloadListIntent,
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
2017-06-28 07:27:32 +02:00
|
|
|
|
|
|
|
Drawable icon = ContextCompat.getDrawable(this, R.mipmap.ic_launcher);
|
|
|
|
|
2017-08-18 11:07:57 -07:00
|
|
|
Builder builder = new Builder(this, getString(R.string.notification_channel_id))
|
2017-06-29 12:02:21 +02:00
|
|
|
.setContentIntent(pendingIntent)
|
2017-06-28 07:27:32 +02:00
|
|
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
|
|
|
.setLargeIcon(((BitmapDrawable) icon).getBitmap())
|
|
|
|
.setContentTitle(getString(R.string.msg_running))
|
|
|
|
.setContentText(getString(R.string.msg_running_detail));
|
|
|
|
|
|
|
|
mNotification = builder.build();
|
|
|
|
|
|
|
|
HandlerThread thread = new HandlerThread("ServiceMessenger");
|
|
|
|
thread.start();
|
|
|
|
|
|
|
|
mHandler = new Handler(thread.getLooper()) {
|
|
|
|
@Override
|
|
|
|
public void handleMessage(Message msg) {
|
|
|
|
switch (msg.what) {
|
|
|
|
case UPDATE_MESSAGE: {
|
|
|
|
int runningCount = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < mManager.getCount(); i++) {
|
|
|
|
if (mManager.getMission(i).running) {
|
|
|
|
runningCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateState(runningCount);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void startMissionAsync(final String url, final String location, final String name,
|
|
|
|
final boolean isAudio, final int threads) {
|
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
int missionId = mManager.startMission(url, location, name, isAudio, threads);
|
|
|
|
mBinder.onMissionAdded(mManager.getMission(missionId));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "Starting");
|
|
|
|
}
|
|
|
|
Log.i(TAG, "Got intent: " + intent);
|
|
|
|
String action = intent.getAction();
|
|
|
|
if (action != null && action.equals(Intent.ACTION_RUN)) {
|
|
|
|
String name = intent.getStringExtra(EXTRA_NAME);
|
|
|
|
String location = intent.getStringExtra(EXTRA_LOCATION);
|
|
|
|
int threads = intent.getIntExtra(EXTRA_THREADS, 1);
|
|
|
|
boolean isAudio = intent.getBooleanExtra(EXTRA_IS_AUDIO, false);
|
|
|
|
String url = intent.getDataString();
|
|
|
|
startMissionAsync(url, location, name, isAudio, threads);
|
|
|
|
}
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "Destroying");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < mManager.getCount(); i++) {
|
|
|
|
mManager.pauseMission(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
stopForeground(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IBinder onBind(Intent intent) {
|
|
|
|
int permissionCheck;
|
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
|
|
|
|
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
|
|
|
|
if (permissionCheck == PermissionChecker.PERMISSION_DENIED) {
|
|
|
|
Toast.makeText(this, "Permission denied (read)", Toast.LENGTH_SHORT).show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
permissionCheck = PermissionChecker.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
|
|
if (permissionCheck == PermissionChecker.PERMISSION_DENIED) {
|
|
|
|
Toast.makeText(this, "Permission denied (write)", Toast.LENGTH_SHORT).show();
|
|
|
|
}
|
|
|
|
|
|
|
|
return mBinder;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void postUpdateMessage() {
|
|
|
|
mHandler.sendEmptyMessage(UPDATE_MESSAGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateState(int runningCount) {
|
|
|
|
if (runningCount == 0) {
|
|
|
|
stopForeground(true);
|
|
|
|
} else {
|
|
|
|
startForeground(NOTIFICATION_ID, mNotification);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void startMission(Context context, String url, String location, String name, boolean isAudio, int threads) {
|
|
|
|
Intent intent = new Intent(context, DownloadManagerService.class);
|
|
|
|
intent.setAction(Intent.ACTION_RUN);
|
|
|
|
intent.setData(Uri.parse(url));
|
|
|
|
intent.putExtra(EXTRA_NAME, name);
|
|
|
|
intent.putExtra(EXTRA_LOCATION, location);
|
|
|
|
intent.putExtra(EXTRA_IS_AUDIO, isAudio);
|
|
|
|
intent.putExtra(EXTRA_THREADS, threads);
|
|
|
|
context.startService(intent);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private class MissionListener implements DownloadMission.MissionListener {
|
|
|
|
@Override
|
|
|
|
public void onProgressUpdate(DownloadMission downloadMission, long done, long total) {
|
|
|
|
long now = System.currentTimeMillis();
|
|
|
|
long delta = now - mLastTimeStamp;
|
|
|
|
if (delta > 2000) {
|
|
|
|
postUpdateMessage();
|
|
|
|
mLastTimeStamp = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFinish(DownloadMission downloadMission) {
|
|
|
|
postUpdateMessage();
|
|
|
|
notifyMediaScanner(downloadMission);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(DownloadMission downloadMission, int errCode) {
|
|
|
|
postUpdateMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Wrapper of DownloadManager
|
|
|
|
public class DMBinder extends Binder {
|
|
|
|
public DownloadManager getDownloadManager() {
|
|
|
|
return mManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onMissionAdded(DownloadMission mission) {
|
|
|
|
mission.addListener(missionListener);
|
|
|
|
postUpdateMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onMissionRemoved(DownloadMission mission) {
|
|
|
|
mission.removeListener(missionListener);
|
|
|
|
postUpdateMessage();
|
|
|
|
}
|
|
|
|
}
|
2016-04-21 20:28:01 -03:00
|
|
|
}
|