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;
|
2018-09-23 15:12:23 -03:00
|
|
|
import android.app.NotificationManager;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.app.PendingIntent;
|
|
|
|
import android.app.Service;
|
2018-09-23 15:12:23 -03:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.ComponentName;
|
2017-01-10 11:41:24 +01:00
|
|
|
import android.content.Context;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.content.Intent;
|
2018-09-23 15:12:23 -03:00
|
|
|
import android.content.IntentFilter;
|
|
|
|
import android.content.ServiceConnection;
|
2018-11-20 19:10:50 -03:00
|
|
|
import android.content.SharedPreferences;
|
2017-11-06 12:27:10 +00:00
|
|
|
import android.graphics.Bitmap;
|
|
|
|
import android.graphics.BitmapFactory;
|
2018-09-23 15:12:23 -03:00
|
|
|
import android.net.ConnectivityManager;
|
|
|
|
import android.net.NetworkInfo;
|
2017-01-10 11:41:24 +01:00
|
|
|
import android.net.Uri;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.os.Binder;
|
2018-09-23 15:12:23 -03:00
|
|
|
import android.os.Build;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.IBinder;
|
2018-09-23 15:12:23 -03:00
|
|
|
import android.os.Looper;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.os.Message;
|
2018-11-20 19:10:50 -03:00
|
|
|
import android.preference.PreferenceManager;
|
|
|
|
import android.support.v4.app.NotificationCompat;
|
2016-04-21 20:28:01 -03:00
|
|
|
import android.support.v4.app.NotificationCompat.Builder;
|
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;
|
2018-11-26 00:20:25 -03:00
|
|
|
import android.util.SparseArray;
|
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;
|
2018-11-20 19:10:50 -03:00
|
|
|
import org.schabi.newpipe.player.helper.LockManager;
|
2017-01-10 11:41:24 +01:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
import java.io.File;
|
2017-01-10 11:41:24 +01:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
2016-04-21 20:28:01 -03:00
|
|
|
import us.shandian.giga.get.DownloadMission;
|
2018-09-23 15:12:23 -03:00
|
|
|
import us.shandian.giga.service.DownloadManager.NetworkState;
|
2017-01-10 11:41:24 +01:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
import static org.schabi.newpipe.BuildConfig.APPLICATION_ID;
|
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 {
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
private static final String TAG = "DownloadManagerService";
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
public static final int MESSAGE_RUNNING = 0;
|
|
|
|
public static final int MESSAGE_PAUSED = 1;
|
|
|
|
public static final int MESSAGE_FINISHED = 2;
|
|
|
|
public static final int MESSAGE_PROGRESS = 3;
|
|
|
|
public static final int MESSAGE_ERROR = 4;
|
|
|
|
public static final int MESSAGE_DELETED = 5;
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
private static final int FOREGROUND_NOTIFICATION_ID = 1000;
|
|
|
|
private static final int DOWNLOADS_NOTIFICATION_ID = 1001;
|
|
|
|
|
|
|
|
private static final String EXTRA_URLS = "DownloadManagerService.extra.urls";
|
2017-06-28 07:27:32 +02:00
|
|
|
private static final String EXTRA_NAME = "DownloadManagerService.extra.name";
|
|
|
|
private static final String EXTRA_LOCATION = "DownloadManagerService.extra.location";
|
2018-09-23 15:12:23 -03:00
|
|
|
private static final String EXTRA_KIND = "DownloadManagerService.extra.kind";
|
2017-06-28 07:27:32 +02:00
|
|
|
private static final String EXTRA_THREADS = "DownloadManagerService.extra.threads";
|
2018-09-23 15:12:23 -03:00
|
|
|
private static final String EXTRA_POSTPROCESSING_NAME = "DownloadManagerService.extra.postprocessingName";
|
|
|
|
private static final String EXTRA_POSTPROCESSING_ARGS = "DownloadManagerService.extra.postprocessingArgs";
|
|
|
|
private static final String EXTRA_SOURCE = "DownloadManagerService.extra.source";
|
2018-11-20 19:10:50 -03:00
|
|
|
private static final String EXTRA_NEAR_LENGTH = "DownloadManagerService.extra.nearLength";
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
private static final String ACTION_RESET_DOWNLOAD_FINISHED = APPLICATION_ID + ".reset_download_finished";
|
|
|
|
private static final String ACTION_OPEN_DOWNLOADS_FINISHED = APPLICATION_ID + ".open_downloads_finished";
|
2017-06-28 07:27:32 +02:00
|
|
|
|
|
|
|
private DMBinder mBinder;
|
|
|
|
private DownloadManager mManager;
|
|
|
|
private Notification mNotification;
|
|
|
|
private Handler mHandler;
|
2018-11-26 00:20:25 -03:00
|
|
|
private boolean mForeground = false;
|
|
|
|
private NotificationManager notificationManager = null;
|
|
|
|
private boolean mDownloadNotificationEnable = true;
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
private int downloadDoneCount = 0;
|
|
|
|
private Builder downloadDoneNotification = null;
|
|
|
|
private StringBuilder downloadDoneList = null;
|
2018-11-20 19:10:50 -03:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
private final ArrayList<Handler> mEchoObservers = new ArrayList<>(1);
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
private BroadcastReceiver mNetworkStateListener;
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
private SharedPreferences mPrefs = null;
|
|
|
|
private final SharedPreferences.OnSharedPreferenceChangeListener mPrefChangeListener = this::handlePreferenceChange;
|
|
|
|
|
|
|
|
private boolean wakeLockAcquired = false;
|
|
|
|
private LockManager wakeLock = null;
|
|
|
|
|
|
|
|
private int downloadFailedNotificationID = DOWNLOADS_NOTIFICATION_ID + 1;
|
2018-11-26 00:20:25 -03:00
|
|
|
private Builder downloadFailedNotification = null;
|
|
|
|
private SparseArray<DownloadMission> mFailedDownloads = new SparseArray<>(5);
|
2018-11-20 19:10:50 -03:00
|
|
|
|
|
|
|
private Bitmap icLauncher;
|
|
|
|
private Bitmap icDownloadDone;
|
2018-11-26 00:20:25 -03:00
|
|
|
private Bitmap icDownloadFailed;
|
|
|
|
|
|
|
|
private PendingIntent mOpenDownloadList;
|
2018-11-20 19:10:50 -03:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
/**
|
|
|
|
* notify media scanner on downloaded media file ...
|
|
|
|
*
|
|
|
|
* @param file the downloaded file
|
|
|
|
*/
|
|
|
|
private void notifyMediaScanner(File file) {
|
|
|
|
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreate() {
|
|
|
|
super.onCreate();
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "onCreate");
|
|
|
|
}
|
|
|
|
|
|
|
|
mBinder = new DMBinder();
|
2018-09-23 15:12:23 -03:00
|
|
|
mHandler = new Handler(Looper.myLooper()) {
|
|
|
|
@Override
|
|
|
|
public void handleMessage(Message msg) {
|
|
|
|
DownloadManagerService.this.handleMessage(msg);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
mManager = new DownloadManager(this, mHandler);
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2017-06-29 12:02:21 +02:00
|
|
|
Intent openDownloadListIntent = new Intent(this, DownloadActivity.class)
|
|
|
|
.setAction(Intent.ACTION_MAIN);
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
mOpenDownloadList = PendingIntent.getActivity(this, 0,
|
2017-06-29 12:02:21 +02:00
|
|
|
openDownloadListIntent,
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
icLauncher = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher);
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2017-08-18 11:07:57 -07:00
|
|
|
Builder builder = new Builder(this, getString(R.string.notification_channel_id))
|
2018-11-26 00:20:25 -03:00
|
|
|
.setContentIntent(mOpenDownloadList)
|
2017-06-28 07:27:32 +02:00
|
|
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
2018-11-20 19:10:50 -03:00
|
|
|
.setLargeIcon(icLauncher)
|
2017-06-28 07:27:32 +02:00
|
|
|
.setContentTitle(getString(R.string.msg_running))
|
|
|
|
.setContentText(getString(R.string.msg_running_detail));
|
|
|
|
|
|
|
|
mNotification = builder.build();
|
2018-09-23 15:12:23 -03:00
|
|
|
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
mNetworkStateListener = new BroadcastReceiver() {
|
2017-06-28 07:27:32 +02:00
|
|
|
@Override
|
2018-09-23 15:12:23 -03:00
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) {
|
|
|
|
handleConnectivityChange(null);
|
|
|
|
return;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
handleConnectivityChange(intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO));
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
};
|
2018-09-23 15:12:23 -03:00
|
|
|
registerReceiver(mNetworkStateListener, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
|
2018-11-20 19:10:50 -03:00
|
|
|
|
|
|
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
mPrefs.registerOnSharedPreferenceChangeListener(mPrefChangeListener);
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
handlePreferenceChange(mPrefs, getString(R.string.downloads_cross_network));
|
2018-11-29 15:16:46 -03:00
|
|
|
handlePreferenceChange(mPrefs, getString(R.string.downloads_maximum_retry));
|
2018-11-26 00:20:25 -03:00
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
wakeLock = new LockManager(this);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
|
|
if (DEBUG) {
|
2018-09-23 15:12:23 -03:00
|
|
|
if (intent == null) {
|
|
|
|
Log.d(TAG, "Restarting");
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
}
|
2017-06-28 07:27:32 +02:00
|
|
|
Log.d(TAG, "Starting");
|
|
|
|
}
|
|
|
|
Log.i(TAG, "Got intent: " + intent);
|
|
|
|
String action = intent.getAction();
|
2018-09-23 15:12:23 -03:00
|
|
|
if (action != null) {
|
|
|
|
if (action.equals(Intent.ACTION_RUN)) {
|
|
|
|
String[] urls = intent.getStringArrayExtra(EXTRA_URLS);
|
|
|
|
String name = intent.getStringExtra(EXTRA_NAME);
|
|
|
|
String location = intent.getStringExtra(EXTRA_LOCATION);
|
|
|
|
int threads = intent.getIntExtra(EXTRA_THREADS, 1);
|
|
|
|
char kind = intent.getCharExtra(EXTRA_KIND, '?');
|
|
|
|
String psName = intent.getStringExtra(EXTRA_POSTPROCESSING_NAME);
|
|
|
|
String[] psArgs = intent.getStringArrayExtra(EXTRA_POSTPROCESSING_ARGS);
|
|
|
|
String source = intent.getStringExtra(EXTRA_SOURCE);
|
2018-11-20 19:10:50 -03:00
|
|
|
long nearLength = intent.getLongExtra(EXTRA_NEAR_LENGTH, 0);
|
2018-09-23 15:12:23 -03:00
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
mHandler.post(() -> mManager.startMission(urls, location, name, kind, threads, source, psName, psArgs, nearLength));
|
2018-09-23 15:12:23 -03:00
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
} else if (downloadDoneNotification != null) {
|
|
|
|
if (action.equals(ACTION_RESET_DOWNLOAD_FINISHED) || action.equals(ACTION_OPEN_DOWNLOADS_FINISHED)) {
|
|
|
|
downloadDoneCount = 0;
|
|
|
|
downloadDoneList.setLength(0);
|
|
|
|
}
|
|
|
|
if (action.equals(ACTION_OPEN_DOWNLOADS_FINISHED)) {
|
|
|
|
startActivity(new Intent(this, DownloadActivity.class)
|
|
|
|
.setAction(Intent.ACTION_MAIN)
|
|
|
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
|
|
);
|
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
}
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "Destroying");
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
stopForeground(true);
|
|
|
|
|
|
|
|
if (notificationManager != null && downloadDoneNotification != null) {
|
|
|
|
downloadDoneNotification.setDeleteIntent(null);// prevent NewPipe running when is killed, cleared from recent, etc
|
|
|
|
notificationManager.notify(DOWNLOADS_NOTIFICATION_ID, downloadDoneNotification.build());
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
mManager.pauseAllMissions();
|
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
if (wakeLockAcquired) wakeLock.releaseWifiAndCpu();
|
|
|
|
|
|
|
|
unregisterReceiver(mNetworkStateListener);
|
|
|
|
mPrefs.unregisterOnSharedPreferenceChangeListener(mPrefChangeListener);
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
if (icDownloadDone != null) icDownloadDone.recycle();
|
|
|
|
if (icDownloadFailed != null) icDownloadFailed.recycle();
|
2018-11-20 19:10:50 -03:00
|
|
|
icLauncher.recycle();
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@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;
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
public void handleMessage(Message msg) {
|
2018-11-20 19:10:50 -03:00
|
|
|
DownloadMission mission = (DownloadMission) msg.obj;
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
switch (msg.what) {
|
|
|
|
case MESSAGE_FINISHED:
|
|
|
|
notifyMediaScanner(mission.getDownloadedFile());
|
|
|
|
notifyFinishedDownload(mission.name);
|
2018-11-20 19:10:50 -03:00
|
|
|
mManager.setFinished(mission);
|
|
|
|
updateForegroundState(mManager.runAnotherMission());
|
2018-09-23 15:12:23 -03:00
|
|
|
break;
|
|
|
|
case MESSAGE_RUNNING:
|
|
|
|
case MESSAGE_PROGRESS:
|
|
|
|
updateForegroundState(true);
|
|
|
|
break;
|
|
|
|
case MESSAGE_ERROR:
|
2018-11-26 00:20:25 -03:00
|
|
|
notifyFailedDownload(mission);
|
2018-11-20 19:10:50 -03:00
|
|
|
updateForegroundState(mManager.runAnotherMission());
|
|
|
|
break;
|
|
|
|
case MESSAGE_PAUSED:
|
2018-09-23 15:12:23 -03:00
|
|
|
updateForegroundState(mManager.getRunningMissionsCount() > 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
if (msg.what != MESSAGE_ERROR)
|
|
|
|
mFailedDownloads.delete(mFailedDownloads.indexOfValue(mission));
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
synchronized (mEchoObservers) {
|
2018-11-26 00:20:25 -03:00
|
|
|
for (Handler handler : mEchoObservers) {
|
|
|
|
Message echo = new Message();
|
|
|
|
echo.what = msg.what;
|
|
|
|
echo.obj = msg.obj;
|
|
|
|
|
|
|
|
handler.sendMessage(echo);
|
2018-09-23 15:12:23 -03:00
|
|
|
}
|
|
|
|
}
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
private void handleConnectivityChange(NetworkInfo info) {
|
|
|
|
NetworkState status;
|
|
|
|
|
|
|
|
if (info == null) {
|
|
|
|
status = NetworkState.Unavailable;
|
|
|
|
Log.i(TAG, "actual connectivity status is unavailable");
|
|
|
|
} else if (!info.isAvailable() || !info.isConnected()) {
|
|
|
|
status = NetworkState.Unavailable;
|
|
|
|
Log.i(TAG, "actual connectivity status is not available and not connected");
|
|
|
|
} else {
|
|
|
|
int type = info.getType();
|
|
|
|
if (type == ConnectivityManager.TYPE_MOBILE || type == ConnectivityManager.TYPE_MOBILE_DUN) {
|
|
|
|
status = NetworkState.MobileOperating;
|
|
|
|
} else if (type == ConnectivityManager.TYPE_WIFI) {
|
|
|
|
status = NetworkState.WifiOperating;
|
|
|
|
} else if (type == ConnectivityManager.TYPE_WIMAX ||
|
|
|
|
type == ConnectivityManager.TYPE_ETHERNET ||
|
|
|
|
type == ConnectivityManager.TYPE_BLUETOOTH) {
|
|
|
|
status = NetworkState.OtherOperating;
|
|
|
|
} else {
|
|
|
|
status = NetworkState.Unavailable;
|
|
|
|
}
|
|
|
|
Log.i(TAG, "actual connectivity status is " + status.name());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mManager == null) return;// avoid race-conditions while the service is starting
|
|
|
|
mManager.handleConnectivityChange(status);
|
|
|
|
}
|
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
private void handlePreferenceChange(SharedPreferences prefs, String key) {
|
2018-11-29 15:16:46 -03:00
|
|
|
if (key.equals(getString(R.string.downloads_maximum_retry))) {
|
2018-11-26 00:20:25 -03:00
|
|
|
try {
|
2018-11-29 15:16:46 -03:00
|
|
|
String value = prefs.getString(key, getString(R.string.downloads_maximum_retry_default));
|
2018-11-26 00:20:25 -03:00
|
|
|
mManager.mPrefMaxRetry = Integer.parseInt(value);
|
|
|
|
} catch (Exception e) {
|
|
|
|
mManager.mPrefMaxRetry = 0;
|
|
|
|
}
|
2018-11-24 00:14:37 -03:00
|
|
|
mManager.updateMaximumAttempts();
|
2018-11-26 00:20:25 -03:00
|
|
|
} else if (key.equals(getString(R.string.downloads_cross_network))) {
|
2018-11-24 00:14:37 -03:00
|
|
|
mManager.mPrefCrossNetwork = prefs.getBoolean(key, false);
|
2018-11-20 19:10:50 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
public void updateForegroundState(boolean state) {
|
|
|
|
if (state == mForeground) return;
|
|
|
|
|
|
|
|
if (state) {
|
|
|
|
startForeground(FOREGROUND_NOTIFICATION_ID, mNotification);
|
2018-11-20 19:10:50 -03:00
|
|
|
if (!wakeLockAcquired) wakeLock.acquireWifiAndCpu();
|
2017-06-28 07:27:32 +02:00
|
|
|
} else {
|
2018-09-23 15:12:23 -03:00
|
|
|
stopForeground(true);
|
2018-11-20 19:10:50 -03:00
|
|
|
if (wakeLockAcquired) wakeLock.releaseWifiAndCpu();
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
mForeground = state;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
public static void startMission(Context context, String urls[], String location, String name, char kind,
|
|
|
|
int threads, String source, String psName, String[] psArgs, long nearLength) {
|
2017-06-28 07:27:32 +02:00
|
|
|
Intent intent = new Intent(context, DownloadManagerService.class);
|
|
|
|
intent.setAction(Intent.ACTION_RUN);
|
2018-09-23 15:12:23 -03:00
|
|
|
intent.putExtra(EXTRA_URLS, urls);
|
2017-06-28 07:27:32 +02:00
|
|
|
intent.putExtra(EXTRA_NAME, name);
|
|
|
|
intent.putExtra(EXTRA_LOCATION, location);
|
2018-09-23 15:12:23 -03:00
|
|
|
intent.putExtra(EXTRA_KIND, kind);
|
2017-06-28 07:27:32 +02:00
|
|
|
intent.putExtra(EXTRA_THREADS, threads);
|
2018-09-23 15:12:23 -03:00
|
|
|
intent.putExtra(EXTRA_SOURCE, source);
|
2018-11-20 19:10:50 -03:00
|
|
|
intent.putExtra(EXTRA_POSTPROCESSING_NAME, psName);
|
|
|
|
intent.putExtra(EXTRA_POSTPROCESSING_ARGS, psArgs);
|
|
|
|
intent.putExtra(EXTRA_NEAR_LENGTH, nearLength);
|
2017-06-28 07:27:32 +02:00
|
|
|
context.startService(intent);
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
public static void checkForRunningMission(Context context, String location, String name, DMChecker check) {
|
|
|
|
Intent intent = new Intent();
|
|
|
|
intent.setClass(context, DownloadManagerService.class);
|
|
|
|
context.bindService(intent, new ServiceConnection() {
|
|
|
|
@Override
|
|
|
|
public void onServiceConnected(ComponentName cname, IBinder service) {
|
|
|
|
try {
|
|
|
|
((DMBinder) service).getDownloadManager().checkForRunningMission(location, name, check);
|
|
|
|
} catch (Exception err) {
|
|
|
|
Log.w(TAG, "checkForRunningMission() callback is defective", err);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: find a efficient way to unbind the service. This destroy the service due idle, but is started again when the user start a download.
|
|
|
|
context.unbindService(this);
|
|
|
|
}
|
2017-06-28 07:27:32 +02:00
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
@Override
|
|
|
|
public void onServiceDisconnected(ComponentName name) {
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
}, Context.BIND_AUTO_CREATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void notifyFinishedDownload(String name) {
|
2018-11-26 00:20:25 -03:00
|
|
|
if (!mDownloadNotificationEnable || notificationManager == null) {
|
2018-09-23 15:12:23 -03:00
|
|
|
return;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
if (downloadDoneNotification == null) {
|
|
|
|
downloadDoneList = new StringBuilder(name.length());
|
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
icDownloadDone = BitmapFactory.decodeResource(this.getResources(), android.R.drawable.stat_sys_download_done);
|
2018-09-23 15:12:23 -03:00
|
|
|
downloadDoneNotification = new Builder(this, getString(R.string.notification_channel_id))
|
|
|
|
.setAutoCancel(true)
|
2018-11-20 19:10:50 -03:00
|
|
|
.setLargeIcon(icDownloadDone)
|
2018-09-23 15:12:23 -03:00
|
|
|
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
2018-11-26 00:20:25 -03:00
|
|
|
.setDeleteIntent(makePendingIntent(ACTION_RESET_DOWNLOAD_FINISHED))
|
|
|
|
.setContentIntent(makePendingIntent(ACTION_OPEN_DOWNLOADS_FINISHED));
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
if (downloadDoneCount < 1) {
|
|
|
|
downloadDoneList.append(name);
|
|
|
|
|
|
|
|
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
|
|
downloadDoneNotification.setContentTitle(getString(R.string.app_name));
|
|
|
|
} else {
|
2018-11-20 19:10:50 -03:00
|
|
|
downloadDoneNotification.setContentTitle(null);
|
2018-09-23 15:12:23 -03:00
|
|
|
}
|
2018-11-20 19:10:50 -03:00
|
|
|
|
|
|
|
downloadDoneNotification.setContentText(getString(R.string.download_finished));
|
|
|
|
downloadDoneNotification.setStyle(new NotificationCompat.BigTextStyle()
|
|
|
|
.setBigContentTitle(getString(R.string.download_finished))
|
|
|
|
.bigText(name)
|
|
|
|
);
|
2018-09-23 15:12:23 -03:00
|
|
|
} else {
|
2018-11-20 19:10:50 -03:00
|
|
|
downloadDoneList.append('\n');
|
2018-09-23 15:12:23 -03:00
|
|
|
downloadDoneList.append(name);
|
|
|
|
|
2018-11-20 19:10:50 -03:00
|
|
|
downloadDoneNotification.setStyle(new NotificationCompat.BigTextStyle().bigText(downloadDoneList));
|
2018-09-23 15:12:23 -03:00
|
|
|
downloadDoneNotification.setContentTitle(getString(R.string.download_finished_more, String.valueOf(downloadDoneCount + 1)));
|
2018-11-20 19:10:50 -03:00
|
|
|
downloadDoneNotification.setContentText(downloadDoneList);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
notificationManager.notify(DOWNLOADS_NOTIFICATION_ID, downloadDoneNotification.build());
|
|
|
|
downloadDoneCount++;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
public void notifyFailedDownload(DownloadMission mission) {
|
|
|
|
if (!mDownloadNotificationEnable || mFailedDownloads.indexOfValue(mission) >= 0) return;
|
|
|
|
|
|
|
|
int id = downloadFailedNotificationID++;
|
|
|
|
mFailedDownloads.put(id, mission);
|
2018-11-20 19:10:50 -03:00
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
if (downloadFailedNotification == null) {
|
|
|
|
icDownloadFailed = BitmapFactory.decodeResource(this.getResources(), android.R.drawable.stat_sys_warning);
|
|
|
|
downloadFailedNotification = new Builder(this, getString(R.string.notification_channel_id))
|
|
|
|
.setAutoCancel(true)
|
|
|
|
.setLargeIcon(icDownloadFailed)
|
|
|
|
.setSmallIcon(android.R.drawable.stat_sys_warning)
|
|
|
|
.setContentIntent(mOpenDownloadList);
|
|
|
|
}
|
2018-11-20 19:10:50 -03:00
|
|
|
|
|
|
|
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
2018-11-26 00:20:25 -03:00
|
|
|
downloadFailedNotification.setContentTitle(getString(R.string.app_name));
|
|
|
|
downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle()
|
|
|
|
.bigText(getString(R.string.download_failed).concat(": ").concat(mission.name)));
|
2018-11-20 19:10:50 -03:00
|
|
|
} else {
|
2018-11-26 00:20:25 -03:00
|
|
|
downloadFailedNotification.setContentTitle(getString(R.string.download_failed));
|
|
|
|
downloadFailedNotification.setContentText(mission.name);
|
|
|
|
downloadFailedNotification.setStyle(new NotificationCompat.BigTextStyle()
|
|
|
|
.bigText(mission.name));
|
2018-11-20 19:10:50 -03:00
|
|
|
}
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
notificationManager.notify(id, downloadFailedNotification.build());
|
|
|
|
}
|
|
|
|
|
|
|
|
private PendingIntent makePendingIntent(String action) {
|
|
|
|
Intent intent = new Intent(this, DownloadManagerService.class).setAction(action);
|
|
|
|
return PendingIntent.getService(this, intent.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
2018-11-20 19:10:50 -03:00
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
private void manageObservers(Handler handler, boolean add) {
|
|
|
|
synchronized (mEchoObservers) {
|
|
|
|
if (add) {
|
2018-11-20 19:10:50 -03:00
|
|
|
mEchoObservers.add(handler);
|
2018-09-23 15:12:23 -03:00
|
|
|
} else {
|
|
|
|
mEchoObservers.remove(handler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-28 07:27:32 +02:00
|
|
|
|
|
|
|
// Wrapper of DownloadManager
|
|
|
|
public class DMBinder extends Binder {
|
|
|
|
public DownloadManager getDownloadManager() {
|
|
|
|
return mManager;
|
|
|
|
}
|
|
|
|
|
2018-09-23 15:12:23 -03:00
|
|
|
public void addMissionEventListener(Handler handler) {
|
|
|
|
manageObservers(handler, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeMissionEventListener(Handler handler) {
|
|
|
|
manageObservers(handler, false);
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
|
|
|
|
2018-11-26 00:20:25 -03:00
|
|
|
public void clearDownloadNotifications() {
|
|
|
|
if (notificationManager == null) return;
|
|
|
|
if (downloadDoneNotification != null) {
|
|
|
|
notificationManager.cancel(DOWNLOADS_NOTIFICATION_ID);
|
|
|
|
downloadDoneList.setLength(0);
|
|
|
|
downloadDoneCount = 0;
|
|
|
|
}
|
|
|
|
if (downloadFailedNotification != null) {
|
|
|
|
for (; downloadFailedNotificationID > DOWNLOADS_NOTIFICATION_ID; downloadFailedNotificationID--) {
|
|
|
|
notificationManager.cancel(downloadFailedNotificationID);
|
|
|
|
}
|
|
|
|
mFailedDownloads.clear();
|
|
|
|
downloadFailedNotificationID++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void enableNotifications(boolean enable) {
|
|
|
|
mDownloadNotificationEnable = enable;
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-11-26 00:20:25 -03:00
|
|
|
|
2017-06-28 07:27:32 +02:00
|
|
|
}
|
2018-09-23 15:12:23 -03:00
|
|
|
|
|
|
|
public interface DMChecker {
|
|
|
|
void callback(boolean listed, boolean finished);
|
|
|
|
}
|
|
|
|
|
2016-04-21 20:28:01 -03:00
|
|
|
}
|