├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── sample
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── dimens.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-mdpi
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-hdpi-v11
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-mdpi-v11
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-xhdpi-v11
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-xxhdpi-v11
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ ├── drawable-xxxhdpi-v11
│ │ │ │ ├── bemobi_download_ic_notif_done.png
│ │ │ │ └── bemobi_download_ic_notif_error.png
│ │ │ └── layout
│ │ │ │ └── activity_main.xml
│ │ ├── java
│ │ │ └── br
│ │ │ │ └── com
│ │ │ │ └── bemobi
│ │ │ │ └── medescope
│ │ │ │ └── sample
│ │ │ │ ├── AppApplication.java
│ │ │ │ ├── service
│ │ │ │ └── PermissionService.java
│ │ │ │ ├── model
│ │ │ │ └── NotificationData.java
│ │ │ │ ├── receiver
│ │ │ │ └── BemobiDownloadReceiver.java
│ │ │ │ └── MainActivity.java
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ └── java
│ │ └── br
│ │ └── com
│ │ └── bemobi
│ │ └── medescope
│ │ ├── ApplicationTest.java
│ │ └── sample
│ │ └── ApplicationTest.java
├── proguard-rules.pro
└── build.gradle
├── medescope
├── src
│ ├── test
│ │ └── java
│ │ │ └── br
│ │ │ └── com
│ │ │ └── bemobi
│ │ │ └── download
│ │ │ └── MedescopeTest.java
│ ├── main
│ │ ├── java
│ │ │ └── br
│ │ │ │ └── com
│ │ │ │ └── bemobi
│ │ │ │ └── medescope
│ │ │ │ ├── constant
│ │ │ │ ├── Extras.java
│ │ │ │ ├── DownloadInfoStatusConstants.java
│ │ │ │ ├── DownloadConstants.java
│ │ │ │ └── DownloadInfoReasonConstants.java
│ │ │ │ ├── wrapper
│ │ │ │ ├── DownloadInfoWrapper.java
│ │ │ │ └── impl
│ │ │ │ │ └── DMDownloadInfoWrapper.java
│ │ │ │ ├── exception
│ │ │ │ ├── DownloadBaseException.java
│ │ │ │ ├── PathNotFoundException.java
│ │ │ │ └── DirectoryNotMountedException.java
│ │ │ │ ├── callback
│ │ │ │ └── DownloadStatusCallback.java
│ │ │ │ ├── service
│ │ │ │ ├── CommunicationService.java
│ │ │ │ ├── DownloadCommand.java
│ │ │ │ ├── DownloadService.java
│ │ │ │ └── impl
│ │ │ │ │ ├── DMIntentService.java
│ │ │ │ │ ├── BroadcastCommunicationService.java
│ │ │ │ │ ├── DMDownloadService.java
│ │ │ │ │ └── DownloadCommandService.java
│ │ │ │ ├── repository
│ │ │ │ ├── DownloadDataRepository.java
│ │ │ │ ├── DMRepository.java
│ │ │ │ ├── impl
│ │ │ │ │ └── MapDownloadDataRepository.java
│ │ │ │ └── PreferencesUtils.java
│ │ │ │ ├── DownloadFileUtils.java
│ │ │ │ ├── receiver
│ │ │ │ ├── BroadcastReceiverLogger.java
│ │ │ │ └── DMDownloaderReceiver.java
│ │ │ │ ├── log
│ │ │ │ ├── MapLogger.java
│ │ │ │ ├── IntentLogger.java
│ │ │ │ └── Logger.java
│ │ │ │ ├── model
│ │ │ │ ├── DownloadRequest.java
│ │ │ │ └── DownloadInfo.java
│ │ │ │ └── Medescope.java
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ └── java
│ │ └── br
│ │ └── com
│ │ └── bemobi
│ │ └── medescope
│ │ └── ApplicationTest.java
├── proguard-rules.pro
├── build.gradle
└── maven.gradle
├── .gitignore
├── gradle.properties
├── gradlew.bat
├── README.md
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':medescope', ':sample'
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DownloadSample
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-hdpi/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-hdpi/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-mdpi/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-mdpi/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xhdpi/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xhdpi/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxhdpi/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxhdpi/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxxhdpi/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi-v11/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-hdpi-v11/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi-v11/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-hdpi-v11/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi-v11/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-mdpi-v11/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi-v11/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-mdpi-v11/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi-v11/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xhdpi-v11/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi-v11/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xhdpi-v11/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi-v11/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxhdpi-v11/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxxhdpi/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/medescope/src/test/java/br/com/bemobi/download/MedescopeTest.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.download;
2 |
3 | /**
4 | * Created by brunocosta on 10/14/15.
5 | */
6 | public class MedescopeTest {
7 | }
8 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi-v11/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxhdpi-v11/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi-v11/bemobi_download_ic_notif_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxxhdpi-v11/bemobi_download_ic_notif_done.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi-v11/bemobi_download_ic_notif_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bemobi/medescope/HEAD/sample/src/main/res/drawable-xxxhdpi-v11/bemobi_download_ic_notif_error.png
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Sep 10 09:54:12 BRT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/constant/Extras.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.constant;
2 |
3 | /**
4 | * Created by luis.fernandez on 7/5/15.
5 | */
6 | public class Extras {
7 |
8 | public static final String EXTRA_DOWNLOAD = "br.com.bemobi.medescope.EXTRA_DOWNLOAD";
9 | }
10 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/wrapper/DownloadInfoWrapper.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.wrapper;
2 |
3 | /**
4 | * Created by raphael on 7/7/15.
5 | */
6 | public interface DownloadInfoWrapper {
7 | int translateStatus(STATUS status);
8 |
9 | int translateReason(REASON reason);
10 | }
11 |
--------------------------------------------------------------------------------
/sample/src/androidTest/java/br/com/bemobi/medescope/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/medescope/src/androidTest/java/br/com/bemobi/medescope/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/sample/src/androidTest/java/br/com/bemobi/medescope/sample/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.sample;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/exception/DownloadBaseException.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.exception;
2 |
3 | /**
4 | * Created by bkosawa on 10/07/15.
5 | */
6 | public class DownloadBaseException extends Exception {
7 |
8 | public DownloadBaseException() {
9 | }
10 |
11 | public DownloadBaseException(String detailMessage) {
12 | super(detailMessage);
13 | }
14 |
15 | public DownloadBaseException(String detailMessage, Throwable throwable) {
16 | super(detailMessage, throwable);
17 | }
18 |
19 | public DownloadBaseException(Throwable throwable) {
20 | super(throwable);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/constant/DownloadInfoStatusConstants.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.constant;
2 |
3 | /**
4 | * Created by raphael on 7/7/15.
5 | */
6 | public class DownloadInfoStatusConstants {
7 | public final static int NOT_ENQUEUED_STATUS = -1;
8 |
9 | public final static int PENDING_STATUS = 1 << 0;
10 |
11 | public final static int IN_PROGRESS_STATUS = 1 << 1;
12 |
13 | public final static int PAUSED_STATUS = 1 << 2;
14 |
15 | public final static int SUCCESSFUL_STATUS = 1 << 3;
16 |
17 | public final static int FAILED_STATUS = 1 << 4;
18 |
19 | public final static int UNKNOWN_ERROR = 1000;
20 | }
21 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/callback/DownloadStatusCallback.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.callback;
2 |
3 | /**
4 | * Created by bkosawa on 08/07/15.
5 | */
6 | public interface DownloadStatusCallback {
7 | void onDownloadNotEnqueued(String downloadId);
8 |
9 | void onDownloadPaused(String downloadId, int reason);
10 |
11 | void onDownloadInProgress(String downloadId, int progress);
12 |
13 | void onDownloadOnFinishedWithError(String downloadId, int reason, String data);
14 |
15 | void onDownloadOnFinishedWithSuccess(String downloadId, String filePath, String data);
16 |
17 | void onDownloadCancelled(String downloadId);
18 | }
19 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/exception/PathNotFoundException.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.exception;
2 |
3 | /**
4 | * Created by bkosawa on 10/07/15.
5 | */
6 | public class PathNotFoundException extends DownloadBaseException {
7 |
8 | public PathNotFoundException() {
9 | }
10 |
11 | public PathNotFoundException(String detailMessage) {
12 | super(detailMessage);
13 | }
14 |
15 | public PathNotFoundException(String detailMessage, Throwable throwable) {
16 | super(detailMessage, throwable);
17 | }
18 |
19 | public PathNotFoundException(Throwable throwable) {
20 | super(throwable);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/exception/DirectoryNotMountedException.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.exception;
2 |
3 | /**
4 | * Created by bkosawa on 10/07/15.
5 | */
6 | public class DirectoryNotMountedException extends DownloadBaseException {
7 |
8 | public DirectoryNotMountedException() {
9 | }
10 |
11 | public DirectoryNotMountedException(String detailMessage) {
12 | super(detailMessage);
13 | }
14 |
15 | public DirectoryNotMountedException(String detailMessage, Throwable throwable) {
16 | super(detailMessage, throwable);
17 | }
18 |
19 | public DirectoryNotMountedException(Throwable throwable) {
20 | super(throwable);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/sample/src/main/java/br/com/bemobi/medescope/sample/AppApplication.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.sample;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.stetho.Stetho;
6 |
7 | /**
8 | * Created by luisfernandez on 7/6/15.
9 | */
10 | public class AppApplication extends Application {
11 |
12 | @Override
13 | public void onCreate() {
14 | super.onCreate();
15 |
16 | Stetho.initialize(
17 | Stetho.newInitializerBuilder(this)
18 | .enableDumpapp(Stetho.defaultDumperPluginsProvider(this))
19 | .enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
20 | .build());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/CommunicationService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service;
2 |
3 | /**
4 | * Created by bkosawa on 02/07/15.
5 | */
6 | public interface CommunicationService {
7 |
8 | void sendFinishWithSuccessBroadcastData(String downloadId, String filePath, String data);
9 |
10 | void sendFinishWithErrorBroadcastData(String downloadId, int reason, String data);
11 |
12 | void sendDownloadStatusNotEnqueue(String downloadId);
13 |
14 | void sendDownloadStatusPaused(String downloadId, int reason);
15 |
16 | void sendDownloadStatusProgress(String downloadId, int progress);
17 |
18 | void showDownloadQueue();
19 |
20 | void sendCancelled(String downloadId);
21 | }
22 |
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/bruno.costa/android-sdks/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/medescope/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/bruno.costa/android-sdks/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/DownloadCommand.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service;
2 |
3 | import android.os.Bundle;
4 |
5 | import br.com.bemobi.medescope.model.DownloadRequest;
6 | import br.com.bemobi.medescope.model.DownloadInfo;
7 |
8 | /**
9 | * Created by bkosawa on 30/06/15.
10 | */
11 | public interface DownloadCommand {
12 |
13 | void startCommand();
14 |
15 | void executeCommand(String action, Bundle extras);
16 |
17 | void enqueue(DownloadRequest downloadRequest);
18 |
19 | void cancelAction(String downloadId);
20 |
21 | void finishAction(String downloadId, DownloadInfo downloadInfo);
22 |
23 | void clickNotificationAction(String[] downloadIds);
24 |
25 | void shutdownCommand();
26 | }
27 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/repository/DownloadDataRepository.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.repository;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * Created by bkosawa on 02/07/15.
7 | */
8 | public interface DownloadDataRepository {
9 |
10 | Map getDownloadsMap();
11 |
12 | void setDownloadsMap(Map downloadsMap);
13 |
14 | void putDownloadData(String downloadId, String data);
15 |
16 | String getDownloadData(String downloadId);
17 |
18 | void removeDownloadData(String downloadId);
19 |
20 | boolean isEmptyDownloadData();
21 |
22 | boolean containsDownloadDataKey(String key);
23 |
24 | void persistSubscribedId(String downloadId);
25 |
26 | String recoverSubscribedId();
27 |
28 | void removeSubscribedId();
29 | }
30 |
--------------------------------------------------------------------------------
/sample/src/main/java/br/com/bemobi/medescope/sample/service/PermissionService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.sample.service;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.pm.PackageManager;
6 | import android.support.v4.app.ActivityCompat;
7 |
8 | import br.com.bemobi.medescope.sample.MainActivity;
9 |
10 | /**
11 | * Created by mac on 18/01/18.
12 | */
13 |
14 | public class PermissionService {
15 | public static final int MY_PERMISSIONS_REQUEST_WRITE_STORAGE = 2018;
16 |
17 | public static void requestPermissions(Activity activity) {
18 | if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
19 | ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_WRITE_STORAGE);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/DownloadFileUtils.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope;
2 |
3 | import android.os.Environment;
4 |
5 | /**
6 | * Created by bruno.costa on 10/07/15.
7 | */
8 | public class DownloadFileUtils {
9 |
10 | /* Checks if external storage is available for read and write */
11 | public static boolean isExternalStorageWritable() {
12 | String state = Environment.getExternalStorageState();
13 | if (Environment.MEDIA_MOUNTED.equals(state)) {
14 | return true;
15 | }
16 | return false;
17 | }
18 |
19 | /* Checks if external storage is available to at least read */
20 | public static boolean isExternalStorageReadable() {
21 | String state = Environment.getExternalStorageState();
22 | if (Environment.MEDIA_MOUNTED.equals(state) ||
23 | Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
24 | return true;
25 | }
26 | return false;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/DownloadService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service;
2 |
3 | import android.content.Context;
4 |
5 | import java.util.Map;
6 |
7 | import br.com.bemobi.medescope.model.DownloadInfo;
8 |
9 | /**
10 | * Created by bkosawa on 30/06/15.
11 | */
12 | public interface DownloadService {
13 |
14 | void shutdown();
15 |
16 | boolean enqueue(String downloadId, String uri, String fileName, String title, String description, String data, boolean shouldDownloadOnlyInWifi, Map customHeaders);
17 |
18 | boolean isDownloadManagerUiActivated();
19 |
20 | boolean isDownloadManagerUiDeactivated();
21 |
22 | boolean isDownloadManagerActivated();
23 |
24 | boolean isDownloadManagerDeactivated(Context context);
25 |
26 | boolean cancel(String downloadId);
27 |
28 | void cleanupId(String downloadId);
29 |
30 | void notificationClicked(String[] downloadIds);
31 |
32 | DownloadInfo getDownloadInfo(String downloadId);
33 | }
34 |
--------------------------------------------------------------------------------
/medescope/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/receiver/BroadcastReceiverLogger.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.receiver;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 |
6 | import br.com.bemobi.medescope.log.IntentLogger;
7 | import br.com.bemobi.medescope.log.Logger;
8 |
9 | /**
10 | * Created by luis.fernandez on 6/27/15.
11 | */
12 | public class BroadcastReceiverLogger {
13 |
14 | private static final String TAG = "BroadcastReceiverLogger";
15 |
16 | private String from;
17 | private String feature;
18 |
19 | public BroadcastReceiverLogger(String from, String feature) {
20 | this.from = from;
21 | this.feature = feature;
22 | }
23 |
24 | public void onReceive(Context context, Intent intent) {
25 | Logger.debug(TAG, feature, "");
26 | Logger.debug(TAG, feature, String.format(">>>>>>>>>>>>>>>>>>>>>>>>>> DUMPING BROADCAST INTENT from: %s", from));
27 | Logger.debug(TAG, feature, String.format(" [%s] = %s", "ACTION", intent.getAction()));
28 |
29 | new IntentLogger(from, feature).logIntent(intent);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/medescope/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply from: 'maven.gradle'
3 |
4 | android {
5 | def globalConfiguration = rootProject.extensions.getByName("ext")
6 |
7 | compileSdkVersion rootProject.ext.androidCompileSdkVersion
8 | buildToolsVersion "$rootProject.ext.androidBuildToolsVersion"
9 |
10 | defaultConfig {
11 | minSdkVersion 14
12 | targetSdkVersion 27
13 | versionCode globalConfiguration.getAt("androidVersionCode")
14 | versionName globalConfiguration.getAt("androidVersionName")
15 | }
16 |
17 | compileOptions {
18 | sourceCompatibility JavaVersion.VERSION_1_8
19 | targetCompatibility JavaVersion.VERSION_1_8
20 | }
21 |
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 | }
29 |
30 | dependencies {
31 | compile ("com.android.support:appcompat-v7:$rootProject.ext.androidSupportVersion"){
32 | exclude module:'com.android.support:support-v4'
33 | }
34 | compile 'com.google.code.gson:gson:2.4'
35 | }
36 |
37 | uploadArchives.dependsOn(assemble)
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/log/MapLogger.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.log;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * Created by luis.fernandez on 7/5/15.
7 | */
8 | public class MapLogger {
9 |
10 | private static final String TAG = "MapLogger";
11 | private String feature;
12 |
13 | public MapLogger(String feature) {
14 | this.feature = feature;
15 | }
16 |
17 | public void log(Map map) {
18 | for (String key : map.keySet()) {
19 | Logger.debug(TAG, feature, String.format(" [%s] = %s", key, map.get(key)));
20 | }
21 | Logger.debug(TAG, feature, "\n");
22 | }
23 |
24 | public void logStringLong(Map map) {
25 | for (String key : map.keySet()) {
26 | Logger.debug(TAG, feature, String.format(" [%s] = %s", key, map.get(key)));
27 | }
28 | Logger.debug(TAG, feature, "\n");
29 | }
30 |
31 | public void logLongString(Map map) {
32 | for (Long key : map.keySet()) {
33 | Logger.debug(TAG, feature, String.format(" [%s] = %s", key, map.get(key)));
34 | }
35 | Logger.debug(TAG, feature, "\n");
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | def globalConfiguration = rootProject.extensions.getByName("ext")
5 |
6 | compileSdkVersion rootProject.ext.androidCompileSdkVersion
7 | buildToolsVersion "$rootProject.ext.androidBuildToolsVersion"
8 |
9 | defaultConfig {
10 | applicationId "br.com.bemobi.medescope.sample"
11 | minSdkVersion 14
12 | targetSdkVersion 27
13 | versionCode globalConfiguration.getAt("androidVersionCode")
14 | versionName globalConfiguration.getAt("androidVersionName")
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | }
23 |
24 | dependencies {
25 | compile "com.android.support:appcompat-v7:$rootProject.ext.androidSupportVersion"
26 | compile "com.android.support:support-v4:$rootProject.ext.androidSupportVersion"
27 | compile 'com.facebook.stetho:stetho:1.1.1'
28 | compile 'com.github.halysongoncalves:pugnotification:1.8.1'
29 | compile project(':medescope')
30 | //compile 'br.com.bemobi:medescope:1.1.2-SNAPSHOT@aar'
31 | compile 'com.google.code.gson:gson:2.4'
32 | }
33 |
--------------------------------------------------------------------------------
/sample/src/main/java/br/com/bemobi/medescope/sample/model/NotificationData.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.sample.model;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 |
6 | /**
7 | * Created by bkosawa on 30/06/15.
8 | */
9 | public class NotificationData {
10 |
11 | private String id;
12 |
13 | private String title;
14 |
15 | private String desc;
16 |
17 | public void setId(String id) {
18 | this.id = id;
19 | }
20 |
21 | public void setTitle(String title) {
22 | this.title = title;
23 | }
24 |
25 | public void setDesc(String desc) {
26 | this.desc = desc;
27 | }
28 |
29 | public String getId() {
30 | return id;
31 | }
32 |
33 | public String getTitle() {
34 | return title;
35 | }
36 |
37 | public String getDesc() {
38 | return desc;
39 | }
40 |
41 | public NotificationData(String id) {
42 | this.id = id;
43 | }
44 |
45 | public NotificationData(String id, String title, String desc) {
46 | this.id = id;
47 | this.title = title;
48 | this.desc = desc;
49 | }
50 |
51 | public String toJson() {
52 | Gson gson = new GsonBuilder().create();
53 | return gson.toJson(this);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/log/IntentLogger.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.log;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 |
6 | import java.util.Iterator;
7 | import java.util.Set;
8 |
9 | /**
10 | * Created by luisfernandez on 7/3/15.
11 | */
12 | public class IntentLogger {
13 | private static final String TAG = "IntentLogger";
14 |
15 | private String from;
16 | private String feature;
17 |
18 | public IntentLogger(String from, String feature) {
19 | this.from = from;
20 | this.feature = feature;
21 | }
22 |
23 | public void logIntent(Intent intent) {
24 | if (intent != null) {
25 | this.logBundle(intent.getExtras());
26 | }
27 | }
28 |
29 | public void logBundle(Bundle bundle) {
30 | Logger.debug(TAG, feature, String.format(">>>>>>>>>>>>>>>>>>>>>>>>>> DUMPING BUNDLE from: %s", from));
31 |
32 | if (bundle != null) {
33 | Set keys = bundle.keySet();
34 | for (String key : keys) {
35 | Object object = bundle.get(key);
36 |
37 | if (object != null) {
38 | String[] values = object.toString().split(", ");
39 |
40 | for (String value : values) {
41 | Logger.debug(TAG, feature, String.format(" [%s] = %s", key, value));
42 | }
43 | }
44 |
45 | }
46 |
47 | Logger.debug(TAG, feature, "\n");
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io
2 |
3 | ### Java ###
4 | *.class
5 |
6 |
7 |
8 |
9 | ### Intellij ###
10 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
11 |
12 | *.iml
13 |
14 | ## Directory-based project format:
15 | .idea/
16 | # if you remove the above rule, at least ignore the follwing:
17 |
18 | # User-specific stuff:
19 | # .idea/workspace.xml
20 | # .idea/tasks.xml
21 | # .idea/dictionaries
22 |
23 | # Sensitive or high-churn files:
24 | # .idea/dataSources.ids
25 | # .idea/dataSources.xml
26 | # .idea/sqlDataSources.xml
27 | # .idea/dynamic.xml
28 | # .idea/uiDesigner.xml
29 |
30 | # Gradle:
31 | # .idea/gradle.xml
32 | # .idea/libraries
33 |
34 | ## File-based project format:
35 | # *.ipr
36 | # *.iws
37 |
38 | ## Plugin-specific files:
39 |
40 | # IntelliJ
41 | out/
42 |
43 | # mpeltonen/sbt-idea plugin
44 | .idea_modules/
45 |
46 | # JIRA plugin
47 | atlassian-ide-plugin.xml
48 |
49 | # Crashlytics plugin (for Android Studio and IntelliJ)
50 | com_crashlytics_export_strings.xml
51 |
52 | #Generated files
53 | build/
54 |
55 | #Build folders of Android Studio
56 | **/build/
57 |
58 | ### Android ###
59 | # Built application files
60 | *.apk
61 | # *.ap_
62 |
63 | # Files for the Dalvik VM
64 | *.dex
65 |
66 | # Generated files
67 | bin/
68 | gen/
69 |
70 | # Gradle files
71 | .gradle/
72 |
73 | # Local configuration file (sdk path, etc)
74 | local.properties
75 |
76 | # Proguard folder generated by Eclipse
77 | # proguard/
78 |
79 | # Log Files
80 | *.log
81 |
82 | #Ignorando SVN!!
83 | **/.svn/
84 | .svn/
85 |
86 | app/mirror
87 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/constant/DownloadConstants.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.constant;
2 |
3 | /**
4 | * Created by bkosawa on 26/06/15.
5 | */
6 | public class DownloadConstants {
7 | public static final String EXTRA_STRING_FILE_PATH = "EXTRA_STRING_FILE_PATH";
8 | public static final String EXTRA_STRING_DOWNLOAD_ID = "EXTRA_STRING_DOWNLOAD_ID";
9 | public static final String EXTRA_ARRAY_STRING_DOWNLOAD_IDS = "EXTRA_ARRAY_STRING_DOWNLOAD_IDS";
10 | public static final String EXTRA_STRING_JSON_DATA = "EXTRA_STRING_JSON_DATA";
11 | public static final String EXTRA_INT_PROGRESS_PERCENTAGE = "EXTRA_INT_PROGRESS_PERCENTAGE";
12 | public static final String EXTRA_INT_ERROR_REASON = "EXTRA_INT_ERROR_REASON";
13 | public static final String EXTRA_DOWNLOAD_INFO = "EXTRA_DOWNLOAD_INFO";
14 | public static final String EXTRA_INT_REASON_KEY = "EXTRA_INT_REASON_KEY";
15 |
16 | public static final String DATA_MAP_PREF = "br.com.bemobi.download.DATA_MAP_PREF";
17 | public static final String DM_STRING_IDS_LIB_TO_DMIDS_MAP_PREF = "br.com.bemobi.medescope.DM_STRING_IDS_LIB_TO_DM_IDS_MAP_PREF";
18 | public static final String DM_STRING_IDS_DMIDS_TO_LIB_MAP_PREF = "br.com.bemobi.medescope.DM_STRING_IDS_DM_IDS_TO_LIB_MAP_PREF";
19 |
20 | public static final String LOG_FEATURE_DOWNLOAD = "BEMOBI_DOWNLOAD_LIB";
21 | public static final String LOG_FEATURE_SERVICE_LIFECYCLE = "SERVICE_LIFECYCLE";
22 | public static final String LOG_FEATURE_DOWNLOAD_DATA_STATE = "DOWNLOAD_DATA_STATE";
23 | public static final String LOG_FEATURE_DOWNLOAD_SEND_PROGRESS = "LOG_FEATURE_DOWNLOAD_SEND_PROGRESS";
24 |
25 | public static final String PREF_SUBSCRIBED_ID = "PREF_SUBSCRIBED_ID";
26 | }
27 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | VERSION_NAME=1.3.0
21 | VERSION_CODE=10
22 | ################################# MAVEN #################################
23 | POM_NAME=MedescopeAndroidLibrary
24 | POM_GROUP_ID=br.com.bemobi
25 | POM_ARTIFACT_ID=medescope
26 | POM_PACKAGING=aar
27 |
28 | POM_DESCRIPTION=This a is a ready-to-use library that encapsulate the Android Download Manager. Using an interface you can easily connect to your Activity or Fragment and used it. It runs on other process as an independent service.
29 | POM_URL=https://github.com/bemobi/medescope
30 | POM_SCM_URL=https://github.com/bemobi/medescope
31 | POM_SCM_CONNECTION=scm:git@github.com:bemobi/medescope.git
32 | POM_SCM_DEV_CONNECTION=scm:git@github.com:bemobi/medescope.git
33 | POM_LICENCE_NAME=The Apache Software License, Version 2.0
34 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
35 | POM_LICENCE_DIST=repo
36 | POM_DEVELOPER_ID=1
37 | POM_DEVELOPER_NAME=XAVIER
38 | org.gradle.jvmargs=-Xmx1536M
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/receiver/DMDownloaderReceiver.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.receiver;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.util.Log;
8 |
9 | import br.com.bemobi.medescope.service.DownloadService;
10 | import br.com.bemobi.medescope.service.impl.DMDownloadService;
11 | import br.com.bemobi.medescope.service.impl.DMIntentService;
12 |
13 | import static br.com.bemobi.medescope.constant.DownloadConstants.LOG_FEATURE_DOWNLOAD;
14 |
15 | /**
16 | * Created by bkosawa on 26/06/15.
17 | */
18 | public class DMDownloaderReceiver extends BroadcastReceiver {
19 | private static final String TAG = DMDownloaderReceiver.class.getSimpleName();
20 |
21 | public DMDownloaderReceiver() {
22 | }
23 |
24 | @Override
25 | public void onReceive(Context context, Intent intent) {
26 | new BroadcastReceiverLogger(TAG, LOG_FEATURE_DOWNLOAD).onReceive(context, intent);
27 |
28 | String action = intent.getAction();
29 |
30 | if(DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
31 | Log.d(TAG, "DM DOWNLOAD COMPLETED");
32 | Long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
33 |
34 | DMIntentService.actionFinish(context, downloadId);
35 | }
36 | else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {
37 | Log.d(TAG, "DM NOTIFICATION CLICKED");
38 |
39 | long[] downloadIds = null;
40 |
41 | if (intent.hasExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS)){
42 | downloadIds = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
43 | }
44 |
45 | DownloadService downloadService = DMDownloadService.getInstance(context);
46 |
47 | if (downloadService.isDownloadManagerUiActivated() && downloadService.isDownloadManagerActivated()) {
48 | DMIntentService.actionNotificationClicked(context, downloadIds);
49 | } else {
50 | Log.w(TAG, String.format("DownloadManager app disabled when receive %s event! Aborting...", action));
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
17 |
18 |
22 |
28 |
29 |
35 |
36 |
37 |
43 |
44 |
45 |
50 |
51 |
57 |
58 |
59 |
64 |
65 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/wrapper/impl/DMDownloadInfoWrapper.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.wrapper.impl;
2 |
3 | import android.app.DownloadManager;
4 |
5 | import br.com.bemobi.medescope.constant.DownloadInfoReasonConstants;
6 | import br.com.bemobi.medescope.wrapper.DownloadInfoWrapper;
7 |
8 | /**
9 | * Created by raphael on 7/7/15.
10 | */
11 | public class DMDownloadInfoWrapper implements DownloadInfoWrapper {
12 |
13 | @Override
14 | public int translateStatus(Integer status) {
15 | return status;
16 | }
17 |
18 | @Override
19 | public int translateReason(Integer reason) {
20 | int translatedReason;
21 |
22 | switch(reason){
23 | case DownloadManager.ERROR_CANNOT_RESUME:
24 | translatedReason = DownloadInfoReasonConstants.ERROR_GENERIC;
25 | break;
26 | case DownloadManager.ERROR_DEVICE_NOT_FOUND:
27 | translatedReason = DownloadInfoReasonConstants.ERROR_STORAGE_NOT_FOUND;
28 | break;
29 | case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
30 | translatedReason = DownloadInfoReasonConstants.ERROR_ALREADY_EXISTING_FILE;
31 | break;
32 | case DownloadManager.ERROR_FILE_ERROR:
33 | translatedReason = DownloadInfoReasonConstants.ERROR_FILE_GENERIC_PROBLEM;
34 | break;
35 | case DownloadManager.ERROR_HTTP_DATA_ERROR:
36 | translatedReason = DownloadInfoReasonConstants.ERROR_HTTP_DATA_ERROR;
37 | break;
38 | case DownloadManager.ERROR_INSUFFICIENT_SPACE:
39 | translatedReason = DownloadInfoReasonConstants.ERROR_INSUFFICIENT_STORAGE;
40 | break;
41 | case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
42 | translatedReason = DownloadInfoReasonConstants.ERROR_TOO_MANY_REDIRECTS;
43 | break;
44 | case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
45 | translatedReason = DownloadInfoReasonConstants.ERROR_UNHANDLED_HTTP_CODE;
46 | break;
47 | case DownloadManager.ERROR_UNKNOWN:
48 | translatedReason = DownloadInfoReasonConstants.ERROR_GENERIC;
49 | break;
50 | case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
51 | translatedReason = DownloadInfoReasonConstants.PAUSED_QUEUED_TO_DOWNLOAD_ON_WIFI;
52 | break;
53 | case DownloadManager.PAUSED_UNKNOWN:
54 | translatedReason = DownloadInfoReasonConstants.PAUSED_GENERIC_REASON;
55 | break;
56 | case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
57 | translatedReason = DownloadInfoReasonConstants.PAUSED_WAITING_NETWORK;
58 | break;
59 | case DownloadManager.PAUSED_WAITING_TO_RETRY:
60 | translatedReason = DownloadInfoReasonConstants.PAUSED_WAITING_NETWORK_AFTER_ERROR;
61 | break;
62 | default:
63 | translatedReason = reason;
64 | }
65 |
66 |
67 | return translatedReason;
68 | }
69 | }
--------------------------------------------------------------------------------
/medescope/maven.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'maven'
2 | apply plugin: 'signing'
3 |
4 | def isReleaseBuild() {
5 | return VERSION_NAME.contains("SNAPSHOT") == false
6 | }
7 |
8 | def getReleaseRepositoryUrl() {
9 | return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
10 | : "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
11 | }
12 |
13 | def getSnapshotRepositoryUrl() {
14 | return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
15 | : "https://oss.sonatype.org/content/repositories/snapshots/"
16 | }
17 |
18 | def getRepositoryUsername() {
19 | return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
20 | }
21 |
22 | def getRepositoryPassword() {
23 | return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
24 | }
25 |
26 | afterEvaluate { project ->
27 | uploadArchives {
28 | repositories {
29 | mavenDeployer {
30 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
31 |
32 | pom.groupId = POM_GROUP_ID
33 | pom.artifactId = POM_ARTIFACT_ID
34 | pom.version = VERSION_NAME
35 |
36 | repository(url: getReleaseRepositoryUrl()) {
37 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
38 | }
39 | snapshotRepository(url: getSnapshotRepositoryUrl()) {
40 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
41 | }
42 |
43 | pom.project {
44 | name POM_NAME
45 | packaging POM_PACKAGING
46 | description POM_DESCRIPTION
47 | url POM_URL
48 |
49 | scm {
50 | url POM_SCM_URL
51 | connection POM_SCM_CONNECTION
52 | developerConnection POM_SCM_DEV_CONNECTION
53 | }
54 |
55 | licenses {
56 | license {
57 | name POM_LICENCE_NAME
58 | url POM_LICENCE_URL
59 | distribution POM_LICENCE_DIST
60 | }
61 | }
62 |
63 | developers {
64 | developer {
65 | id POM_DEVELOPER_ID
66 | name POM_DEVELOPER_NAME
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
74 | signing {
75 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
76 | sign configurations.archives
77 | }
78 |
79 | task androidJavadocs(type: Javadoc) {
80 | source = android.sourceSets.main.java.srcDirs
81 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
82 | }
83 |
84 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
85 | classifier = 'javadoc'
86 | from androidJavadocs.destinationDir
87 | }
88 |
89 | task androidSourcesJar(type: Jar) {
90 | classifier = 'sources'
91 | from android.sourceSets.main.java.sourceFiles
92 | }
93 |
94 | artifacts {
95 | archives androidSourcesJar
96 | }
97 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Medescope Android Download Library
2 | =======
3 | [](http://android-arsenal.com/details/1/2799)
4 |
5 | This a is a ready-to-use library that encapsulate the Android Download Manager. Using an interface you can easily connect to your Activity or Fragment and used it. It runs on other process as an independent service.
6 |
7 | Download
8 | --------
9 |
10 | Download grab via Gradle:
11 | ```groovy
12 | dependencies{
13 | compile 'br.com.bemobi:medescope:1.1.0
14 | }
15 | ```
16 |
17 | Usage
18 | --------
19 | To download a file.
20 |
21 | ```
22 | Medescope
23 | .getInstance(this)
24 | .enqueue("DOWNLOAD_ID",
25 | "http://somefileiwanttodownload.com/file",
26 | "file_name",
27 | "Name that you appear on notification",
28 | "{some:'samplejson'}"
29 | );
30 | ```
31 |
32 | Set an application name to be shown on notification bar.
33 |
34 | ```
35 | Medescope.getInstance(this).setApplicationName("My Application Name"));
36 | ```
37 |
38 | Using a callback interface to simply response on your code.
39 |
40 | ```
41 | Medescope.getInstance(this).subscribeStatus(this, "DOWNLOAD_ID", new DownloadStatusCallback() {
42 | @Override
43 | public void onDownloadNotEnqueued(String downloadId) {
44 | //TODO DO SOMETHING
45 | }
46 |
47 | @Override
48 | public void onDownloadPaused(String downloadId, int reason) {
49 | //TODO DO SOMETHING
50 | }
51 |
52 | @Override
53 | public void onDownloadInProgress(String downloadId, int progress) {
54 | //TODO DO SOMETHING
55 | }
56 |
57 | @Override
58 | public void onDownloadOnFinishedWithError(String downloadId, int reason, String data) {
59 | //TODO DO SOMETHING
60 | }
61 |
62 | @Override
63 | public void onDownloadOnFinishedWithSuccess(String downloadId, String filePath, String data) {
64 | //TODO DO SOMETHING
65 | }
66 |
67 | @Override
68 | public void onDownloadCancelled(String downloadId) {
69 | //TODO DO SOMETHING
70 | }
71 | });
72 | ```
73 |
74 | For more, check our sample.
75 |
76 | Contributing
77 | --------
78 |
79 | 1. Fork it!
80 | 2. Create your feature branch: `git checkout -b my-new-feature`
81 | 3. Commit your changes: `git commit -am 'Add some feature'`
82 | 4. Push to the branch: `git push origin my-new-feature`
83 | 5. Submit a pull request :D
84 |
85 | License
86 | --------
87 |
88 | Copyright 2015 Bemobi
89 |
90 | Licensed under the Apache License, Version 2.0 (the "License");
91 | you may not use this file except in compliance with the License.
92 | You may obtain a copy of the License at
93 |
94 | http://www.apache.org/licenses/LICENSE-2.0
95 |
96 | Unless required by applicable law or agreed to in writing, software
97 | distributed under the License is distributed on an "AS IS" BASIS,
98 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99 | See the License for the specific language governing permissions and
100 | limitations under the License.
101 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/impl/DMIntentService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service.impl;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.util.Log;
7 |
8 | import br.com.bemobi.medescope.model.DownloadInfo;
9 | import br.com.bemobi.medescope.repository.DMRepository;
10 | import br.com.bemobi.medescope.service.DownloadService;
11 |
12 | /**
13 | * Created by bkosawa on 01/07/15.
14 | */
15 | public class DMIntentService implements Runnable {
16 |
17 | private static final String ACTION_DM_FINISH = "br.com.bemobi.medescope.ACTION_DM_FINISH";
18 | private static final String ACTION_DM_NOTIFICATION_CLICKED = "br.com.bemobi.medescope.ACTION_DM_NOTIFICATION_CLICKED";
19 | private static final String TAG = "DMIntentService";
20 |
21 | private Intent sIntent;
22 | private Context mContext;
23 |
24 | public DMIntentService(Intent sIntent, Context mContext) {
25 | this.sIntent = sIntent;
26 | this.mContext = mContext;
27 | }
28 |
29 | public static void actionFinish(Context context, long downloadId) {
30 | Intent intent = new Intent(context, DMIntentService.class);
31 | intent.setAction(ACTION_DM_FINISH);
32 | intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadId);
33 | new Thread(new DMIntentService(intent, context)).start();
34 | }
35 |
36 | public static void actionNotificationClicked(Context context, long[] downloadIds) {
37 | Intent serviceIntent = new Intent(context, DMIntentService.class);
38 | serviceIntent.setAction(ACTION_DM_NOTIFICATION_CLICKED);
39 | if (downloadIds != null) {
40 | serviceIntent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadIds);
41 | }
42 | new Thread(new DMIntentService(serviceIntent, context)).start();
43 | }
44 |
45 | @Override
46 | public void run() {
47 | if (sIntent != null) {
48 | DownloadService downloadService = DMDownloadService.getInstance(mContext);
49 | String action = sIntent.getAction();
50 | if (ACTION_DM_FINISH.equals(action) ) {
51 | Long dmDownloadId = sIntent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
52 | if(dmDownloadId >= 0) {
53 | String libId = DMRepository.getInstance(mContext).getClientId(dmDownloadId);
54 |
55 | DownloadInfo downloadInfo = downloadService.getDownloadInfo(libId);
56 |
57 | DownloadCommandService.actionFinishDownload(mContext, libId, downloadInfo);
58 | }
59 | } else if (ACTION_DM_NOTIFICATION_CLICKED.equals(action)) {
60 | String[] downloadIds = {};
61 | long[] ids = {};
62 | if(sIntent.hasExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS)) {
63 | ids = sIntent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
64 | }
65 |
66 | if(ids != null && ids.length > 0) {
67 | for (int i = 0; i < ids.length; i++) {
68 | downloadIds[i] = DMRepository.getInstance(mContext).getClientId(ids[i]);
69 | }
70 | }
71 |
72 | if (downloadService.isDownloadManagerUiActivated() && downloadService.isDownloadManagerActivated()) {
73 | downloadService.notificationClicked(downloadIds);
74 | } else {
75 | Log.w(TAG, "DownloadManager app disabled before trying to open the Download List screen! Aborting...");
76 | }
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/repository/DMRepository.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.repository;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 |
6 | import com.google.gson.Gson;
7 | import com.google.gson.reflect.TypeToken;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | import br.com.bemobi.medescope.constant.DownloadConstants;
13 |
14 | /**
15 | * Created by bkosawa on 01/07/15.
16 | */
17 | public class DMRepository {
18 |
19 | private static final String TAG = DMRepository.class.getSimpleName();
20 |
21 | private Context mContext;
22 | private static DMRepository instance;
23 |
24 | private Map mapIdsClientToDM;
25 | private Map mapIdsDMToClient;
26 |
27 | private DMRepository(Context context) {
28 | this.mContext = context;
29 | this.mapIdsClientToDM = new HashMap<>();
30 | this.mapIdsDMToClient = new HashMap<>();
31 | this.loadMaps();
32 | }
33 |
34 | public static DMRepository getInstance(Context context) {
35 | if(instance == null){
36 | instance = new DMRepository(context.getApplicationContext());
37 | }
38 | return instance;
39 | }
40 |
41 | public void persistIds(String downloadId, Long dmDownloadId) {
42 | if( !mapIdsDMToClient.containsKey(dmDownloadId) && !mapIdsClientToDM.containsKey(downloadId)) {
43 | mapIdsDMToClient.put(dmDownloadId, downloadId);
44 | mapIdsClientToDM.put(downloadId, dmDownloadId);
45 | persistMaps();
46 | }
47 |
48 | //TODO Should we give a feedback?
49 | }
50 |
51 | public void removeId(String downloadId){
52 | Long dmDownloadId = mapIdsClientToDM.get(downloadId);
53 | mapIdsDMToClient.remove(dmDownloadId);
54 | mapIdsClientToDM.remove(downloadId);
55 | persistMaps();
56 | }
57 |
58 | public void removeId(Long dmDownloadId){
59 | String downloadId = mapIdsDMToClient.get(dmDownloadId);
60 | mapIdsDMToClient.remove(dmDownloadId);
61 | mapIdsClientToDM.remove(downloadId);
62 | persistMaps();
63 | }
64 |
65 | public Long getDMId(String clientId){
66 | return mapIdsClientToDM.get(clientId);
67 | }
68 |
69 | public String getClientId(Long dmDownloadId){
70 | return mapIdsDMToClient.get(dmDownloadId);
71 | }
72 |
73 | private void loadMaps(){
74 | String mapIdsLibToDMStr = PreferencesUtils.getStringPreference(mContext.getApplicationContext(), DownloadConstants.DM_STRING_IDS_LIB_TO_DMIDS_MAP_PREF, "");
75 | if(!TextUtils.isEmpty(mapIdsLibToDMStr)) {
76 | Gson gson = new Gson();
77 | mapIdsClientToDM = gson.fromJson(mapIdsLibToDMStr, new TypeToken>(){}.getType());
78 | } else {
79 | mapIdsClientToDM = new HashMap<>();
80 | }
81 |
82 | String mapIdsDMtoLibStr = PreferencesUtils.getStringPreference(mContext.getApplicationContext(), DownloadConstants.DM_STRING_IDS_DMIDS_TO_LIB_MAP_PREF, "");
83 | if(!TextUtils.isEmpty(mapIdsDMtoLibStr)) {
84 | Gson gson = new Gson();
85 | mapIdsDMToClient = gson.fromJson(mapIdsDMtoLibStr, new TypeToken>(){}.getType());
86 | } else {
87 | mapIdsDMToClient = new HashMap<>();
88 | }
89 | }
90 |
91 | private void persistMaps(){
92 | PreferencesUtils.savePreference(mContext.getApplicationContext(), DownloadConstants.DM_STRING_IDS_LIB_TO_DMIDS_MAP_PREF, new Gson().toJson(mapIdsClientToDM));
93 | PreferencesUtils.savePreference(mContext.getApplicationContext(), DownloadConstants.DM_STRING_IDS_DMIDS_TO_LIB_MAP_PREF, new Gson().toJson(mapIdsDMToClient));
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/sample/src/main/java/br/com/bemobi/medescope/sample/receiver/BemobiDownloadReceiver.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.sample.receiver;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.graphics.BitmapFactory;
7 | import android.text.TextUtils;
8 | import android.util.Log;
9 |
10 | import com.google.gson.Gson;
11 |
12 | import br.com.bemobi.medescope.Medescope;
13 | import br.com.bemobi.medescope.constant.DownloadConstants;
14 | import br.com.bemobi.medescope.receiver.BroadcastReceiverLogger;
15 | import br.com.bemobi.medescope.sample.R;
16 | import br.com.bemobi.medescope.sample.model.NotificationData;
17 | import br.com.goncalves.pugnotification.notification.PugNotification;
18 |
19 | import static br.com.bemobi.medescope.constant.DownloadConstants.LOG_FEATURE_DOWNLOAD;
20 |
21 | /**
22 | * Created by bkosawa on 02/07/15.
23 | */
24 | public class BemobiDownloadReceiver extends BroadcastReceiver {
25 |
26 | private static final String TAG = BemobiDownloadReceiver.class.getSimpleName();
27 |
28 | @Override
29 | public void onReceive(Context context, Intent intent) {
30 | new BroadcastReceiverLogger(TAG, LOG_FEATURE_DOWNLOAD).onReceive(context, intent);
31 |
32 | if (intent != null) {
33 | String action = intent.getAction();
34 | if (Medescope.ACTION_BROADCAST_FINISH_WITH_SUCCESS.equals(action)) {
35 | String downloadId = intent.getStringExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID);
36 | String filePath = intent.getStringExtra(DownloadConstants.EXTRA_STRING_FILE_PATH);
37 |
38 | if (!TextUtils.isEmpty(downloadId)) {
39 | String data = intent.getStringExtra(DownloadConstants.EXTRA_STRING_JSON_DATA);
40 | NotificationData nData = new Gson().fromJson(data, NotificationData.class);
41 |
42 | PugNotification.with(context).load()
43 | .title(nData.getTitle())
44 | .message(nData.getDesc())
45 | .bigTextStyle(nData.getDesc())
46 | .smallIcon(R.mipmap.ic_launcher)
47 | .largeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.bemobi_download_ic_notif_done))
48 | .autoCancel(true)
49 | .simple()
50 | .build();
51 |
52 | Log.d(TAG, "File Path: " + filePath);
53 | }
54 | } else if (Medescope.ACTION_BROADCAST_FINISH_WITH_ERROR.equals(action)) {
55 | String downloadId = intent.getStringExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID);
56 | int errorMsg = intent.getIntExtra(DownloadConstants.EXTRA_INT_ERROR_REASON, -1);
57 |
58 | if (!TextUtils.isEmpty(downloadId)) {
59 | String data = intent.getStringExtra(DownloadConstants.EXTRA_STRING_JSON_DATA);
60 | NotificationData nData = new Gson().fromJson(data, NotificationData.class);
61 |
62 | PugNotification.with(context).load()
63 | .title(nData.getTitle())
64 | .message(errorMsg + " - " + nData.getDesc())
65 | .bigTextStyle(nData.getDesc())
66 | .smallIcon(R.mipmap.ic_launcher)
67 | .largeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.bemobi_download_ic_notif_error))
68 | .autoCancel(true)
69 | .simple()
70 | .build();
71 | }
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/repository/impl/MapDownloadDataRepository.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.repository.impl;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 |
6 | import com.google.gson.Gson;
7 | import com.google.gson.reflect.TypeToken;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | import br.com.bemobi.medescope.constant.DownloadConstants;
13 | import br.com.bemobi.medescope.repository.DownloadDataRepository;
14 | import br.com.bemobi.medescope.repository.PreferencesUtils;
15 |
16 | /**
17 | * Created by bkosawa on 01/07/15.
18 | */
19 | public class MapDownloadDataRepository implements DownloadDataRepository {
20 |
21 | private static final String TAG = MapDownloadDataRepository.class.getSimpleName();
22 |
23 | private static DownloadDataRepository downloadDataRepository;
24 |
25 | private Map downloadsMap = new HashMap<>();
26 |
27 | private Context mContext;
28 |
29 | public static DownloadDataRepository getInstance(Context context) {
30 | if(downloadDataRepository == null) {
31 | downloadDataRepository = new MapDownloadDataRepository(context);
32 | }
33 | return downloadDataRepository;
34 | }
35 |
36 | private MapDownloadDataRepository(Context context) {
37 | this.mContext = context.getApplicationContext();
38 | load();
39 | }
40 |
41 | @Override
42 | public Map getDownloadsMap() {
43 | return downloadsMap;
44 | }
45 |
46 | @Override
47 | public void setDownloadsMap(Map downloadsMap) {
48 | this.downloadsMap = downloadsMap;
49 | }
50 |
51 | @Override
52 | public void putDownloadData(String downloadId, String data) {
53 | this.downloadsMap.put(downloadId, data);
54 | persistDownloadData();
55 | }
56 |
57 | @Override
58 | public String getDownloadData(String downloadId) {
59 | return this.downloadsMap.get(downloadId);
60 | }
61 |
62 | @Override
63 | public void removeDownloadData(String downloadId) {
64 |
65 | this.downloadsMap.remove(downloadId);
66 | persistDownloadData();
67 | }
68 |
69 | @Override
70 | public boolean isEmptyDownloadData() {
71 | return this.downloadsMap.isEmpty();
72 | }
73 |
74 | @Override
75 | public boolean containsDownloadDataKey(String key) {
76 | return this.downloadsMap.containsKey(key);
77 | }
78 |
79 | @Override
80 | public void persistSubscribedId(String downloadId) {
81 | PreferencesUtils.savePreference(mContext.getApplicationContext(), DownloadConstants.PREF_SUBSCRIBED_ID, downloadId);
82 | }
83 |
84 | @Override
85 | public String recoverSubscribedId() {
86 | return PreferencesUtils.getStringPreference(mContext.getApplicationContext(), DownloadConstants.PREF_SUBSCRIBED_ID, "");
87 | }
88 |
89 | @Override
90 | public void removeSubscribedId() {
91 | PreferencesUtils.removePreference(mContext.getApplicationContext(), DownloadConstants.PREF_SUBSCRIBED_ID);
92 | }
93 |
94 | private void load() {
95 | String map = PreferencesUtils.getStringPreference(mContext.getApplicationContext(), DownloadConstants.DATA_MAP_PREF, "");
96 | if(!TextUtils.isEmpty(map)) {
97 | Gson gson = new Gson();
98 | downloadsMap = gson.fromJson(map, new TypeToken>(){}.getType());
99 | } else {
100 | downloadsMap = new HashMap<>();
101 | }
102 | }
103 |
104 | private void persistDownloadData()
105 | {
106 | PreferencesUtils.savePreference(mContext.getApplicationContext(), DownloadConstants.DATA_MAP_PREF, new Gson().toJson(downloadsMap));
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/model/DownloadRequest.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.model;
2 |
3 | import android.text.TextUtils;
4 |
5 | import java.io.Serializable;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | /**
10 | * Created by luis.fernandez on 7/5/15.
11 | */
12 | public class DownloadRequest implements Serializable {
13 |
14 | private String id;
15 | private String uri;
16 | private String fileName;
17 | private String downloadName;
18 | private String downloadDescription;
19 | private String clientPayload;
20 | private boolean shouldDownloadOnlyInWifi;
21 | private Map customHeaders;
22 |
23 | public DownloadRequest() {
24 | this.customHeaders = new HashMap<>();
25 | }
26 |
27 | public DownloadRequest(String id, String uri, String fileName, String downloadName, String downloadDescription, String clientPayload, boolean shouldDownloadOnlyInWifi, Map customHeaders) {
28 | this.id = id;
29 | this.uri = uri;
30 | this.fileName = fileName;
31 | this.downloadName = downloadName;
32 | this.downloadDescription = downloadDescription;
33 | this.clientPayload = clientPayload;
34 | this.shouldDownloadOnlyInWifi = shouldDownloadOnlyInWifi;
35 | this.customHeaders = customHeaders;
36 | }
37 |
38 | public boolean isValid() {
39 | return !TextUtils.isEmpty(id) &&
40 | !TextUtils.isEmpty(uri) &&
41 | !TextUtils.isEmpty(fileName) &&
42 | !TextUtils.isEmpty(downloadName) &&
43 | !TextUtils.isEmpty(downloadDescription) &&
44 | !TextUtils.isEmpty(clientPayload);
45 | }
46 |
47 | public String getId() {
48 | return id;
49 | }
50 |
51 | public void setId(String id) {
52 | this.id = id;
53 | }
54 |
55 | public String getUri() {
56 | return uri;
57 | }
58 |
59 | public void setUri(String uri) {
60 | this.uri = uri;
61 | }
62 |
63 | public String getFileName() {
64 | return fileName;
65 | }
66 |
67 | public void setFileName(String fileName) {
68 | this.fileName = fileName;
69 | }
70 |
71 | public String getDownloadName() {
72 | return downloadName;
73 | }
74 |
75 | public void setDownloadName(String downloadName) {
76 | this.downloadName = downloadName;
77 | }
78 |
79 | public String getDownloadDescription() {
80 | return downloadDescription;
81 | }
82 |
83 | public void setDownloadDescription(String downloadDescription) {
84 | this.downloadDescription = downloadDescription;
85 | }
86 |
87 | public String getClientPayload() {
88 | return clientPayload;
89 | }
90 |
91 | public void setClientPayload(String clientPayload) {
92 | this.clientPayload = clientPayload;
93 | }
94 |
95 | public Map getCustomHeaders() {
96 | return customHeaders;
97 | }
98 |
99 | public void setCustomHeaders(Map customHeaders) {
100 | this.customHeaders = customHeaders;
101 | }
102 |
103 | public boolean shouldDownloadOnlyInWifi() {
104 | return shouldDownloadOnlyInWifi;
105 | }
106 |
107 | public void setShouldDownloadOnlyInWifi(boolean shouldDownloadOnlyInWifi) {
108 | this.shouldDownloadOnlyInWifi = shouldDownloadOnlyInWifi;
109 | }
110 |
111 | @Override
112 | public String toString() {
113 | return "Download{" +
114 | "id='" + id + '\'' +
115 | ", uri='" + uri + '\'' +
116 | ", fileName='" + fileName + '\'' +
117 | ", downloadName='" + downloadName + '\'' +
118 | ", downloadDescription='" + downloadDescription + '\'' +
119 | ", clientPayload='" + clientPayload + '\'' +
120 | ", shouldDownloadOnlyInWifi=" + shouldDownloadOnlyInWifi +
121 | ", customHeaders=" + customHeaders +
122 | '}';
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/log/Logger.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.log;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | /**
7 | * Created by brunocosta on 9/10/15.
8 | */
9 | public class Logger {
10 |
11 | private static final String TAG_tag = Logger.class.getSimpleName();
12 |
13 | public static void setContext(Context mContext) {
14 | LogConfig.getInstance().setContext(mContext);
15 | }
16 |
17 | private static String getString(String word) {
18 | return (word == null) ? "null" : word;
19 | }
20 |
21 | public static void debug(String tag, String msg) {
22 | if (LogConfig.getInstance().isDebug()) {
23 | Log.d(TAG_tag, getString(tag) + ":" + getString(msg));
24 | }
25 | }
26 |
27 | public static void debug(String tag, String feature, String msg) {
28 | if (LogConfig.getInstance().isDebug()) {
29 | if (LogConfig.getInstance().isDetailed()) {
30 | Log.d(TAG_tag, getString(tag) + " [FEATURE:] " + getString(feature) + " > " + getString(msg));
31 | } else {
32 | Log.d(TAG_tag, getString(feature) + " > " + getString(msg));
33 | }
34 | }
35 | }
36 |
37 | public static void debug(String tag, String msg, Throwable throwable) {
38 | if (LogConfig.getInstance().isDebug()) {
39 | Log.d(TAG_tag, getString(tag) + ":" + getString(msg), throwable);
40 | }
41 | }
42 |
43 | public static void error(String tag, String msg) {
44 | if (LogConfig.getInstance().isError()) {
45 | Log.e(TAG_tag, getString(tag) + ":" + getString(msg));
46 | }
47 | }
48 |
49 | public static void error(String tag, String feature, String msg) {
50 | if (LogConfig.getInstance().isDebug()) {
51 | Log.e(TAG_tag, getString(tag) + " [FEATURE:] " + getString(feature) + " > " + getString(msg));
52 | }
53 | }
54 |
55 | public static void error(String tag, String msg, Throwable th) {
56 | if (LogConfig.getInstance().isError()) {
57 | Log.e(TAG_tag, getString(tag) + ":" + getString(msg), th);
58 | }
59 | }
60 |
61 | public static class LogConfig {
62 | private boolean detailed = false;
63 |
64 | private boolean debug = false;
65 |
66 | private boolean error = false;
67 |
68 | private int showWarnCount = 0;
69 |
70 | private static LogConfig instance;
71 |
72 | private Context mContext;
73 |
74 | protected static LogConfig getInstance() {
75 | if (instance == null) {
76 | instance = new LogConfig();
77 | }
78 | return instance;
79 | }
80 |
81 | protected void setContext(Context mContext) {
82 | this.mContext = mContext.getApplicationContext();
83 | init();
84 | }
85 |
86 | private void init() {
87 | initDetailedLog();
88 | initDebugLog();
89 | initErrorLog();
90 | }
91 |
92 | private void initDetailedLog() {
93 | int id = mContext.getResources().getIdentifier("mcare_detailed_log", "bool", mContext.getPackageName());
94 | if (id > 0) {
95 | detailed = mContext.getResources().getBoolean(id);
96 | }
97 | }
98 |
99 | private void initDebugLog() {
100 | int id = mContext.getResources().getIdentifier("mcare_debug_log", "bool", mContext.getPackageName());
101 | if (id > 0) {
102 | debug = mContext.getResources().getBoolean(id);
103 | }
104 | }
105 |
106 | private void initErrorLog() {
107 | int id = mContext.getResources().getIdentifier("mcare_error_log", "bool", mContext.getPackageName());
108 | if (id > 0) {
109 | error = mContext.getResources().getBoolean(id);
110 | }
111 | }
112 |
113 | protected boolean isDetailed() {
114 | warningNullContext();
115 | return detailed;
116 | }
117 |
118 | protected boolean isDebug() {
119 | warningNullContext();
120 | return debug;
121 | }
122 |
123 | protected boolean isError() {
124 | warningNullContext();
125 | return error;
126 | }
127 |
128 | private void warningNullContext() {
129 | if (mContext == null) {
130 | if (showWarnCount < 1) {
131 | Log.w(">>>> MCareLogUtil",
132 | "Use LogUtil.setContext(mContext) para que sua configuração no XML tenha efeito. Default: Todos os logs desligados.\n"
133 | + "Exemplo de XML:\n" + "true\n"
134 | + "true\n" + "true");
135 | showWarnCount++;
136 | }
137 | }
138 | }
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/impl/BroadcastCommunicationService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service.impl;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.util.Log;
7 |
8 | import br.com.bemobi.medescope.Medescope;
9 | import br.com.bemobi.medescope.constant.DownloadConstants;
10 | import br.com.bemobi.medescope.log.Logger;
11 | import br.com.bemobi.medescope.service.CommunicationService;
12 | import br.com.bemobi.medescope.service.DownloadService;
13 |
14 | /**
15 | * Created by bkosawa on 02/07/15.
16 | */
17 | public class BroadcastCommunicationService implements CommunicationService {
18 |
19 | private static final String TAG = BroadcastCommunicationService.class.getSimpleName();
20 |
21 | private static CommunicationService instance;
22 |
23 | private final Context mContext;
24 |
25 | private BroadcastCommunicationService(Context context){
26 | this.mContext = context;
27 | }
28 |
29 | public static CommunicationService getInstance(Context context){
30 | if(instance == null){
31 | instance = new BroadcastCommunicationService(context);
32 | }
33 | return instance;
34 | }
35 |
36 | @Override
37 | public void sendFinishWithSuccessBroadcastData(String downloadId, String filePath, String data) {
38 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "sendFinishWithSuccessBroadcastData with data: " + data);
39 | Intent finishIntent = new Intent();
40 | finishIntent.setAction(Medescope.ACTION_BROADCAST_FINISH_WITH_SUCCESS);
41 | finishIntent.setPackage(mContext.getPackageName());
42 | finishIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
43 | finishIntent.putExtra(DownloadConstants.EXTRA_STRING_FILE_PATH, filePath);
44 | finishIntent.putExtra(DownloadConstants.EXTRA_STRING_JSON_DATA, data);
45 | mContext.sendBroadcast(finishIntent);
46 | }
47 |
48 | @Override
49 | public void sendFinishWithErrorBroadcastData(String downloadId, int reason, String data) {
50 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "sendFinishWithErrorBroadcastData with data: " + data + " and reason: " + reason);
51 | Intent finishIntent = new Intent();
52 | finishIntent.setAction(Medescope.ACTION_BROADCAST_FINISH_WITH_ERROR);
53 | finishIntent.setPackage(mContext.getPackageName());
54 | finishIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
55 | finishIntent.putExtra(DownloadConstants.EXTRA_INT_ERROR_REASON, reason);
56 | finishIntent.putExtra(DownloadConstants.EXTRA_STRING_JSON_DATA, data);
57 | mContext.sendBroadcast(finishIntent);
58 | }
59 |
60 | @Override
61 | public void sendDownloadStatusNotEnqueue(String downloadId) {
62 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "sendDownloadStatusNotEnqueue");
63 | Intent progressIntent = new Intent();
64 | progressIntent.setAction(Medescope.ACTION_BROADCAST_NOT_ENQUEUED);
65 | progressIntent.setPackage(mContext.getPackageName());
66 | progressIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
67 | mContext.sendBroadcast(progressIntent);
68 | }
69 |
70 | @Override
71 | public void sendDownloadStatusPaused(String downloadId, int reason) {
72 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "sendDownloadStatusPaused");
73 | Intent progressIntent = new Intent();
74 | progressIntent.setAction(Medescope.ACTION_BROADCAST_PAUSED);
75 | progressIntent.setPackage(mContext.getPackageName());
76 | progressIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
77 | progressIntent.putExtra(DownloadConstants.EXTRA_INT_REASON_KEY, reason);
78 | mContext.sendBroadcast(progressIntent);
79 | }
80 |
81 | @Override
82 | public void sendDownloadStatusProgress(String downloadId, int progress) {
83 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "sendDownloadStatusProgress");
84 | Intent progressIntent = new Intent();
85 | progressIntent.setAction(Medescope.ACTION_BROADCAST_IN_PROGRESS);
86 | progressIntent.setPackage(mContext.getPackageName());
87 | progressIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
88 | progressIntent.putExtra(DownloadConstants.EXTRA_INT_PROGRESS_PERCENTAGE, progress);
89 | mContext.sendBroadcast(progressIntent);
90 | }
91 |
92 | @Override
93 | public void sendCancelled(String downloadId) {
94 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "sendCancelled");
95 | Intent progressIntent = new Intent();
96 | progressIntent.setAction(Medescope.ACTION_BROADCAST_CANCELLED);
97 | progressIntent.setPackage(mContext.getPackageName());
98 | progressIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
99 | mContext.sendBroadcast(progressIntent);
100 | }
101 |
102 | @Override
103 | public void showDownloadQueue() {
104 | DownloadService downloadService = DMDownloadService.getInstance(mContext);
105 |
106 | if (downloadService.isDownloadManagerUiActivated() && downloadService.isDownloadManagerActivated()) {
107 | Intent i = new Intent();
108 | i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
109 | i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
110 | mContext.startActivity(i);
111 | } else {
112 | Log.w(TAG, "DownloadManager app disabled before trying to open the Download List screen. Abort!");
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/model/DownloadInfo.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.model;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import br.com.bemobi.medescope.constant.DownloadInfoStatusConstants;
7 |
8 | /**
9 | * Created by bkosawa on 30/06/15.
10 | */
11 | public class DownloadInfo implements Parcelable{
12 |
13 | private int status;
14 |
15 | private int reason;
16 |
17 | private String filename;
18 |
19 | private String localURI;
20 |
21 | private long lastModified;
22 |
23 | private long downloadedSoFar;
24 |
25 | private long totalSize;
26 |
27 | private int progress;
28 |
29 | public DownloadInfo() {
30 | }
31 |
32 | public DownloadInfo(int status, int reason, String filename, String localURI, long lastModified, long downloadedSoFar, long totalSize, int progress) {
33 | this.status = status;
34 | this.reason = reason;
35 | this.filename = filename;
36 | this.localURI = localURI;
37 | this.lastModified = lastModified;
38 | this.downloadedSoFar = downloadedSoFar;
39 | this.totalSize = totalSize;
40 | this.progress = progress;
41 | }
42 |
43 | public DownloadInfo(int status, int reason) {
44 | this.status = status;
45 | this.reason = reason;
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | return "DownloadInfo{" +
51 | "status=" + status +
52 | ", reason=" + reason +
53 | ", filename='" + filename + '\'' +
54 | ", localURI='" + localURI + '\'' +
55 | ", lastModified=" + lastModified +
56 | ", downloadedSoFar=" + downloadedSoFar +
57 | ", totalSize=" + totalSize +
58 | ", progress=" + progress +
59 | '}';
60 | }
61 |
62 | public int getStatus() {
63 | return status;
64 | }
65 |
66 | public void setStatus(int status) {
67 | this.status = status;
68 | }
69 |
70 | public void setReason(int reason) {
71 | this.reason = reason;
72 | }
73 |
74 | public void setFilename(String filename) {
75 | this.filename = filename;
76 | }
77 |
78 | public void setLocalURI(String localURI) {
79 | this.localURI = localURI;
80 | }
81 |
82 | public void setLastModified(long lastModified) {
83 | this.lastModified = lastModified;
84 | }
85 |
86 | public void setDownloadedSoFar(long downloadedSoFar) {
87 | this.downloadedSoFar = downloadedSoFar;
88 | }
89 |
90 | public void setTotalSize(long totalSize) {
91 | this.totalSize = totalSize;
92 | }
93 |
94 | public void setProgress(int progress) {
95 | this.progress = progress;
96 | }
97 |
98 | public int getReason() {
99 | return reason;
100 | }
101 |
102 | public String getFilename() {
103 | return filename;
104 | }
105 |
106 | public String getLocalURI() {
107 | return localURI;
108 | }
109 |
110 | public long getLastModified() {
111 | return lastModified;
112 | }
113 |
114 | public long getDownloadedSoFar() {
115 | return downloadedSoFar;
116 | }
117 |
118 | public long getTotalSize() {
119 | return totalSize;
120 | }
121 |
122 | public int getProgress() {
123 | return progress;
124 | }
125 |
126 | public boolean isPaused() {
127 | return status == DownloadInfoStatusConstants.PAUSED_STATUS;
128 | }
129 |
130 | public boolean isInProgress() {
131 | return status == DownloadInfoStatusConstants.IN_PROGRESS_STATUS;
132 | }
133 |
134 | public boolean hasFinishedWithSuccess() {
135 | return status == DownloadInfoStatusConstants.SUCCESSFUL_STATUS;
136 | }
137 |
138 | public boolean hasFinishedWithError() {
139 | return status == DownloadInfoStatusConstants.FAILED_STATUS;
140 | }
141 |
142 | public boolean hasFinished() {
143 | return status == DownloadInfoStatusConstants.SUCCESSFUL_STATUS
144 | || status == DownloadInfoStatusConstants.FAILED_STATUS;
145 | }
146 |
147 | @Override
148 | public boolean equals(Object o) {
149 | if (this == o) return true;
150 | if (o == null || getClass() != o.getClass()) return false;
151 |
152 | DownloadInfo that = (DownloadInfo) o;
153 |
154 | if (status != that.status) return false;
155 | if (reason != that.reason) return false;
156 | return (Double.compare(that.progress, progress) != 0);
157 | }
158 |
159 | public int describeContents() {
160 | return 0;
161 | }
162 |
163 | public void writeToParcel(Parcel out, int flags) {
164 | out.writeInt(this.status);
165 | out.writeInt(this.reason);
166 | out.writeString(this.filename);
167 | out.writeString(this.localURI);
168 | out.writeLong(this.lastModified);
169 | out.writeLong(this.downloadedSoFar);
170 | out.writeLong(this.totalSize);
171 | out.writeInt(this.progress);
172 | }
173 |
174 | private DownloadInfo(Parcel in) {
175 | this.status = in.readInt();
176 | this.reason = in.readInt();
177 | this.filename = in.readString();
178 | this.localURI = in.readString();
179 | this.lastModified = in.readLong();
180 | this.downloadedSoFar = in.readLong();
181 | this.totalSize = in.readLong();
182 | this.progress = in.readInt();
183 | }
184 |
185 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
186 | public DownloadInfo createFromParcel(Parcel in) {
187 | return new DownloadInfo(in);
188 | }
189 |
190 | public DownloadInfo[] newArray(int size) {
191 | return new DownloadInfo[size];
192 | }
193 | };
194 | }
195 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/repository/PreferencesUtils.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.repository;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.SharedPreferences.Editor;
6 |
7 | /**
8 | * Created by brunocosta on 9/10/15.
9 | */
10 | public class PreferencesUtils {
11 | // private static Map preferences = new HashMap();
12 |
13 | public static SharedPreferences getSharedPreferences(Context context) {
14 | SharedPreferences pref
15 | // = preferences.get(context.getApplicationContext())
16 | ;
17 | // if (pref == null) {
18 | pref = context.getApplicationContext().getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
19 | // preferences.put(context, pref);
20 | // }
21 |
22 | return pref;
23 | }
24 |
25 | public static void clearPreferences(Context context) {
26 | SharedPreferences.Editor editor = context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE).edit();
27 | editor.clear();
28 | editor.commit();
29 | }
30 |
31 | public static boolean getBooleanPreference(Context context, int resId, boolean defaultValue) {
32 | return getSharedPreferences(context).getBoolean(context.getString(resId), defaultValue);
33 | }
34 |
35 | public static boolean getBooleanPreference(Context context, String prefKey, boolean defaultValue) {
36 | return getSharedPreferences(context).getBoolean(prefKey, defaultValue);
37 | }
38 |
39 | public static int getIntPreference(Context context, int resId, int defaultValue) {
40 | return getSharedPreferences(context).getInt(context.getString(resId), defaultValue);
41 | }
42 |
43 | public static int getIntPreference(Context context, String prefKey, int defaultValue) {
44 | return getSharedPreferences(context).getInt(prefKey, defaultValue);
45 | }
46 |
47 | public static long getLongPreference(Context context, int resId, long defaultValue) {
48 | return getSharedPreferences(context).getLong(context.getString(resId), defaultValue);
49 | }
50 |
51 | public static long getLongPreference(Context context, String prefKey, long defaultValue) {
52 | return getSharedPreferences(context).getLong(prefKey, defaultValue);
53 | }
54 |
55 | public static String getStringPreference(Context context, int resId, String defaultValue) {
56 | return getSharedPreferences(context).getString(context.getString(resId), defaultValue);
57 | }
58 |
59 | public static String getStringPreference(Context context, String prefKey, String defaultValue) {
60 | return getSharedPreferences(context).getString(prefKey, defaultValue);
61 | }
62 |
63 | public static void savePreference(Context context, int resId, int newValue) {
64 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
65 | Editor editor = mPreferences.edit();
66 | editor.putInt(context.getString(resId), newValue);
67 | editor.commit();
68 | }
69 |
70 | public static void savePreference(Context context, String prefKey, int newValue) {
71 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
72 | Editor editor = mPreferences.edit();
73 | editor.putInt(prefKey, newValue);
74 | editor.commit();
75 | }
76 |
77 | public static void savePreference(Context context, int resId, long newValue) {
78 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
79 | Editor editor = mPreferences.edit();
80 | editor.putLong(context.getString(resId), newValue);
81 | editor.commit();
82 | }
83 |
84 | public static void savePreference(Context context, String prefKey, long newValue){
85 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
86 | Editor editor = mPreferences.edit();
87 | editor.putLong(prefKey, newValue);
88 | editor.commit();
89 | }
90 |
91 | public static void savePreference(Context context, int resId, String newValue) {
92 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
93 | Editor editor = mPreferences.edit();
94 | editor.putString(context.getString(resId), newValue);
95 | editor.commit();
96 | }
97 |
98 | public static void savePreference(Context context, String prefKey, String newValue) {
99 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
100 | Editor editor = mPreferences.edit();
101 | editor.putString(prefKey, newValue);
102 | editor.commit();
103 | }
104 |
105 | public static void savePreference(Context context, int resId, Boolean newValue) {
106 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
107 | Editor editor = mPreferences.edit();
108 | editor.putBoolean(context.getString(resId), newValue);
109 | editor.commit();
110 | }
111 |
112 | public static void savePreference(Context context, String prefKey, Boolean newValue) {
113 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
114 | Editor editor = mPreferences.edit();
115 | editor.putBoolean(prefKey, newValue);
116 | editor.commit();
117 | }
118 |
119 | public static void removePreference(Context context, int resId) {
120 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
121 | Editor editor = mPreferences.edit();
122 | editor.remove(context.getString(resId));
123 | editor.commit();
124 | }
125 |
126 | public static void removePreference(Context context, String prefKey) {
127 | SharedPreferences mPreferences = PreferencesUtils.getSharedPreferences(context);
128 | Editor editor = mPreferences.edit();
129 | editor.remove(prefKey);
130 | editor.commit();
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/constant/DownloadInfoReasonConstants.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.constant;
2 |
3 | /**
4 | * Created by raphael on 7/7/15.
5 | */
6 | public class DownloadInfoReasonConstants {
7 |
8 | /**
9 | * Unknown error. :P
10 | */
11 | //public final static int REASON_UNKNOWN_ERROR = 0;
12 | public final static int PAUSED_GENERIC_ERROR = 2000;
13 |
14 |
15 | /**
16 | * Value of COLUMN_REASON when the download is paused because some network error occurred and the download manager is waiting before retrying the request.
17 | */
18 | //public final static int REASON_PAUSED_WAITING_TO_RETRY = 1;
19 | public final static int PAUSED_WAITING_NETWORK_AFTER_ERROR = 2001;
20 |
21 | /**
22 | * Value of COLUMN_REASON when the download is waiting for network connectivity to proceed.
23 | */
24 | //public final static int REASON_PAUSED_WAITING_FOR_NETWORK = 2;
25 | public final static int PAUSED_WAITING_NETWORK = 2002;
26 |
27 | /**
28 | * Value of COLUMN_REASON when the download exceeds a size limit for downloads over the mobile network and the download manager is waiting for a Wi-Fi connection to proceed.
29 | */
30 | //public final static int PAUSED_QUEUED_FOR_WIFI = 3;
31 | public final static int PAUSED_QUEUED_TO_DOWNLOAD_ON_WIFI = 2003;
32 |
33 | /**
34 | * Value of COLUMN_REASON when the download is paused for some other reason.
35 | */
36 | //public final static int REASON_PAUSED_UNKNOWN = 4;
37 | public final static int PAUSED_GENERIC_REASON = 2004;
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | /**
46 | * Value of COLUMN_REASON when a storage issue arises which doesn't fit under any other error code.
47 | */
48 | //public final static int REASON_ERROR_FILE_ERROR = 1001;
49 | public final static int ERROR_FILE_GENERIC_PROBLEM = 3001;
50 |
51 | /**
52 | * Value of COLUMN_REASON when an HTTP code was received that download manager can't handle.
53 | */
54 | //public final static int REASON_ERROR_UNHANDLED_HTTP_CODE = 1002;
55 | public final static int ERROR_UNHANDLED_HTTP_CODE = 3002;
56 |
57 | /**
58 | * Value of COLUMN_REASON when an error receiving or processing data occurred at the HTTP level.
59 | */
60 | //public final static int REASON_ERROR_HTTP_DATA_ERROR = 1004;
61 | public final static int ERROR_HTTP_DATA_ERROR = 3004;
62 |
63 | /**
64 | * Value of COLUMN_REASON when there were too many redirects.
65 | */
66 | //public final static int REASON_ERROR_TOO_MANY_REDIRECTS = 1005;
67 | public final static int ERROR_TOO_MANY_REDIRECTS = 3005;
68 |
69 | /**
70 | * Value of COLUMN_REASON when there was insufficient storage space.
71 | */
72 | //public final static int REASON_ERROR_INSUFFICIENT_SPACE = 1006;
73 | public final static int ERROR_INSUFFICIENT_STORAGE = 3006;
74 |
75 | /**
76 | * Value of COLUMN_REASON when no external storage device was found.
77 | */
78 | //public final static int REASON_ERROR_DEVICE_NOT_FOUND = 1007;
79 | public final static int ERROR_STORAGE_NOT_FOUND = 3007;
80 |
81 | /**
82 | * Value of COLUMN_REASON when some possibly transient error occurred but we can't resume the download.
83 | */
84 | //public final static int REASON_ERROR_CANNOT_RESUME = 1008;
85 | public final static int ERROR_GENERIC = 3008;
86 |
87 | /**
88 | * Value of COLUMN_REASON when the requested destination file already exists (the download manager will not overwrite an existing file).
89 | */
90 | //public final static int REASON_ERROR_FILE_ALREADY_EXISTS = 1009;
91 | public final static int ERROR_ALREADY_EXISTING_FILE = 3009;
92 |
93 | /**
94 | * Value of COLUMN_REASON when a storage issue arises which doesn't fit under any other error code.
95 | */
96 | //public final static int REASON_ERROR_BLOCKED = 1010;
97 | public final static int ERROR_GENERIC_STORAGE_PROBLEM = 3010;
98 |
99 | /**
100 | * Value of COLUMN_REASON There is no permission to write on file.
101 | */
102 | public final static int ERROR_PERMISSION_NOT_GRANTED = 3011;
103 |
104 | public static String getDownloadReasonText(int reason) {
105 | String reasonStr = "";
106 |
107 | switch(reason) {
108 | case DownloadInfoReasonConstants.ERROR_GENERIC: {
109 | reasonStr = "ERROR_GENERIC";
110 | break;
111 | }
112 | case DownloadInfoReasonConstants.ERROR_STORAGE_NOT_FOUND: {
113 | reasonStr = "ERROR_STORAGE_NOT_FOUND";
114 | break;
115 | }
116 | case DownloadInfoReasonConstants.ERROR_ALREADY_EXISTING_FILE: {
117 | reasonStr = "ERROR_ALREADY_EXISTING_FILE";
118 | break;
119 | }
120 | case DownloadInfoReasonConstants.ERROR_FILE_GENERIC_PROBLEM: {
121 | reasonStr = "ERROR_FILE_GENERIC_PROBLEM";
122 | break;
123 | }
124 | case DownloadInfoReasonConstants.ERROR_HTTP_DATA_ERROR: {
125 | reasonStr = "ERROR_HTTP_DATA_ERROR";
126 | break;
127 | }
128 | case DownloadInfoReasonConstants.ERROR_INSUFFICIENT_STORAGE: {
129 | reasonStr = "ERROR_INSUFFICIENT_STORAGE";
130 | break;
131 | }
132 | case DownloadInfoReasonConstants.ERROR_TOO_MANY_REDIRECTS: {
133 | reasonStr = "ERROR_TOO_MANY_REDIRECTS";
134 | break;
135 | }
136 | case DownloadInfoReasonConstants.ERROR_UNHANDLED_HTTP_CODE: {
137 | reasonStr = "ERROR_UNHANDLED_HTTP_CODE";
138 | break;
139 | }
140 | case DownloadInfoReasonConstants.PAUSED_QUEUED_TO_DOWNLOAD_ON_WIFI: {
141 | reasonStr = "PAUSED_QUEUED_TO_DOWNLOAD_ON_WIFI";
142 | break;
143 | }
144 | case DownloadInfoReasonConstants.PAUSED_GENERIC_REASON: {
145 | reasonStr = "PAUSED_GENERIC_REASON";
146 | break;
147 | }
148 | case DownloadInfoReasonConstants.PAUSED_WAITING_NETWORK: {
149 | reasonStr = "PAUSED_WAITING_NETWORK";
150 | break;
151 | }
152 | case DownloadInfoReasonConstants.PAUSED_WAITING_NETWORK_AFTER_ERROR: {
153 | reasonStr = "PAUSED_WAITING_NETWORK_AFTER_ERROR";
154 | break;
155 | }
156 | }
157 |
158 | return reasonStr;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/sample/src/main/java/br/com/bemobi/medescope/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.sample;
2 |
3 | import android.app.Activity;
4 | import android.content.pm.PackageManager;
5 | import android.os.Bundle;
6 | import android.support.annotation.NonNull;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.widget.AdapterView;
10 | import android.widget.ArrayAdapter;
11 | import android.widget.ProgressBar;
12 | import android.widget.Spinner;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | import br.com.bemobi.medescope.Medescope;
20 | import br.com.bemobi.medescope.callback.DownloadStatusCallback;
21 | import br.com.bemobi.medescope.exception.DirectoryNotMountedException;
22 | import br.com.bemobi.medescope.exception.PathNotFoundException;
23 | import br.com.bemobi.medescope.sample.model.NotificationData;
24 | import br.com.bemobi.medescope.sample.service.PermissionService;
25 |
26 |
27 | public class MainActivity extends Activity {
28 |
29 | private static final String TAG = MainActivity.class.getSimpleName();
30 | private static final String FILE_PATH = "FILE.zip";
31 |
32 | private String FILE_5MB = "http://speedtest.ftp.otenet.gr/files/test10Mb.db";
33 | private String FILE_10MB = "http://speedtest.ftp.otenet.gr/files/test10Mb.db";
34 | private String FILE_20MB = "http://download.thinkbroadband.com/20MB.zip";
35 | private String FILE_50MB = "http://download.thinkbroadband.com/50MB.zip";
36 | private String FILE_100MB = "http://download.thinkbroadband.com/100MB.zip";
37 | private String [] files = {FILE_5MB, FILE_10MB, FILE_20MB, FILE_50MB, FILE_100MB};
38 |
39 | private String downloadName = FILE_5MB;
40 |
41 | private Spinner spinner;
42 | private ProgressBar progressBar;
43 | private ArrayAdapter adapter;
44 |
45 | private TextView textStatus;
46 | private TextView textAction;
47 | private Medescope mMedescope;
48 |
49 | @Override
50 | protected void onCreate(Bundle savedInstanceState) {
51 | super.onCreate(savedInstanceState);
52 | setContentView(R.layout.activity_main);
53 |
54 | List spinnerArray = new ArrayList<>();
55 | spinnerArray.add("5MB File");
56 | spinnerArray.add("10MB File");
57 | spinnerArray.add("20MB File");
58 | spinnerArray.add("50MB File");
59 | spinnerArray.add("100MB File");
60 |
61 | textStatus = (TextView) findViewById(R.id.text);
62 | textAction = (TextView) findViewById(R.id.textAction);
63 |
64 | progressBar = (ProgressBar) findViewById(R.id.sample_progressBar);
65 |
66 | adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerArray);
67 |
68 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
69 | spinner = (Spinner) findViewById(R.id.download_spinner);
70 | spinner.setAdapter(adapter);
71 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
72 |
73 | @Override
74 | public void onItemSelected(AdapterView> parentView, View selectedItemView, int myPosition, long myID) {
75 | downloadName = files[myPosition];
76 | mMedescope.updateSubscriptionStatusId(MainActivity.this, "" + myID);
77 | hideProgress();
78 | }
79 |
80 | @Override
81 | public void onNothingSelected(AdapterView> parentView) {
82 | // your code here
83 | }
84 |
85 | });
86 |
87 | PermissionService.requestPermissions(this);
88 | }
89 |
90 | @Override
91 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
92 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
93 |
94 | switch (requestCode) {
95 | case PermissionService.MY_PERMISSIONS_REQUEST_WRITE_STORAGE: {
96 | if (grantResults.length <= 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) {
97 | textStatus.setText("PERMISSION DENIED");
98 | textAction.setText("");
99 | hideProgress();
100 | }
101 | return;
102 | }
103 |
104 | }
105 | }
106 |
107 | private void hideProgress() {
108 | progressBar.setVisibility(View.GONE);
109 | progressBar.setProgress(0);
110 | progressBar.setIndeterminate(false);
111 | }
112 |
113 | private void showProgress() {
114 | progressBar.setVisibility(View.VISIBLE);
115 | progressBar.setProgress(0);
116 | progressBar.setIndeterminate(true);
117 | }
118 |
119 | private void setPercentProgress(int progress) {
120 | progressBar.setVisibility(View.VISIBLE);
121 | progressBar.setProgress(progress);
122 | progressBar.setIndeterminate(false);
123 | }
124 |
125 | @Override
126 | protected void onResume() {
127 | super.onResume();
128 |
129 | mMedescope = Medescope.getInstance(this);
130 | mMedescope.setApplicationName(getString(R.string.app_name));
131 | mMedescope.subscribeStatus(this, "" + spinner.getSelectedItemId(), new DownloadStatusCallback() {
132 | @Override
133 | public void onDownloadNotEnqueued(String downloadId) {
134 | textAction.setText("ACTION NOT ENQUEUED");
135 | textStatus.setText("NOT ENQUEUED:");
136 | hideProgress();
137 | }
138 |
139 | @Override
140 | public void onDownloadPaused(String downloadId, int reason) {
141 | textAction.setText("ACTION PAUSED");
142 | textStatus.setText(String.format("NOT ENQUEUED: [reason: %s ]", reason));
143 | }
144 |
145 | @Override
146 | public void onDownloadInProgress(String downloadId, int progress) {
147 | textAction.setText("ACTION IN PROGRESS");
148 | Log.d(TAG, "Received download progress: " + progress);
149 | setPercentProgress(progress);
150 | textStatus.setText(String.format("PROGRESS: [progress: %s ]", progress));
151 | }
152 |
153 | @Override
154 | public void onDownloadOnFinishedWithError(String downloadId, int reason, String data) {
155 | textAction.setText("ACTION FINISH WITH ERROR");
156 | hideProgress();
157 | }
158 |
159 | @Override
160 | public void onDownloadOnFinishedWithSuccess(String downloadId, String filePath, String data) {
161 | textAction.setText("ACTION FINISH WITH SUCCESS");
162 | Log.d(TAG, "Received path: " + filePath);
163 | checkFilePath(filePath);
164 | hideProgress();
165 | }
166 |
167 | @Override
168 | public void onDownloadCancelled(String downloadId) {
169 | textAction.setText("ACTION FINISH WITH SUCCESS");
170 | hideProgress();
171 | }
172 | });
173 | }
174 |
175 | private void checkFilePath(String filePath) {
176 | String originalFilePath = "";
177 | try {
178 | originalFilePath = mMedescope.getDownloadDirectoryToRead(FILE_PATH);
179 | Log.d(TAG, "Original path: " + originalFilePath);
180 | } catch (DirectoryNotMountedException | PathNotFoundException e) {
181 | e.printStackTrace();
182 | }
183 |
184 | if (filePath.equals(originalFilePath)) {
185 | Toast.makeText(MainActivity.this, "Path sent is the expected", Toast.LENGTH_LONG).show();
186 | }
187 | }
188 |
189 | @Override
190 | protected void onPause() {
191 | super.onPause();
192 | Medescope.getInstance(this).unsubscribeStatus(this);
193 | }
194 |
195 | public void download(View view) {
196 | NotificationData data = new NotificationData("" + spinner.getSelectedItemId(), downloadName, getString(R.string.app_name));
197 |
198 | boolean shouldDownloadOnlyInWiFi = isLargeFile(downloadName);
199 |
200 | mMedescope.enqueue(
201 | data.getId(),
202 | downloadName,
203 | FILE_PATH,
204 | (String) spinner.getSelectedItem(),
205 | data.toJson(),
206 | shouldDownloadOnlyInWiFi);
207 | showProgress();
208 | }
209 |
210 | public void cancel(View view) {
211 | mMedescope.cancel("" + spinner.getSelectedItemId());
212 | hideProgress();
213 | }
214 |
215 | private boolean isLargeFile(String selected) {
216 | return FILE_20MB.equals(selected) || FILE_50MB.equals(selected) || FILE_100MB.equals(selected);
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/impl/DMDownloadService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service.impl;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.Context;
5 | import android.content.pm.PackageManager;
6 | import android.database.Cursor;
7 | import android.net.Uri;
8 | import android.os.Build;
9 | import android.os.Environment;
10 | import android.util.Log;
11 |
12 | import java.util.Map;
13 |
14 | import br.com.bemobi.medescope.DownloadFileUtils;
15 | import br.com.bemobi.medescope.log.Logger;
16 | import br.com.bemobi.medescope.model.DownloadInfo;
17 | import br.com.bemobi.medescope.repository.DMRepository;
18 | import br.com.bemobi.medescope.service.DownloadService;
19 | import br.com.bemobi.medescope.wrapper.DownloadInfoWrapper;
20 | import br.com.bemobi.medescope.wrapper.impl.DMDownloadInfoWrapper;
21 |
22 | import static br.com.bemobi.medescope.constant.DownloadConstants.LOG_FEATURE_DOWNLOAD;
23 |
24 | /**
25 | * Created by bkosawa on 30/06/15.
26 | */
27 | public class DMDownloadService implements DownloadService {
28 |
29 | private static final String TAG = DMDownloadService.class.getSimpleName();
30 |
31 | private static final String PACKAGE_DOWNLOAD_MANAGER = "com.android.providers.downloads";
32 | private static final String PACKAGE_DOWNLOAD_MANAGER_UI = "com.android.providers.downloads.ui";
33 |
34 | private static DMDownloadService instance;
35 | private static DownloadManager downloadManager;
36 | private DMRepository repository;
37 | private Context mContext;
38 | private boolean isHidden = false;
39 | private DownloadInfoWrapper downloadInfoWrapper;
40 |
41 | private DMDownloadService(Context context) {
42 | this.mContext = context;
43 | this.repository = DMRepository.getInstance(context);
44 | this.downloadInfoWrapper = new DMDownloadInfoWrapper();
45 | }
46 |
47 | public static DMDownloadService getInstance(Context context) {
48 | if(instance == null) {
49 | instance = new DMDownloadService(context.getApplicationContext());
50 | }
51 | return instance;
52 | }
53 |
54 | private static DownloadManager getDMInstance(Context context) {
55 | if (downloadManager == null) {
56 | downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
57 | }
58 | return downloadManager;
59 | }
60 |
61 | @Override
62 | public void shutdown() {
63 | Log.d(TAG, "shutdown");
64 | downloadManager = null;
65 | }
66 |
67 | @Override
68 | public boolean enqueue(String downloadId, String uri, String fileName, String title, String description, String data, boolean shouldDownloadOnlyInWifi, Map customHeaders) {
69 | if( isDownloadManagerDeactivated(mContext) ){
70 | return false;
71 | }
72 | if (DownloadFileUtils.isExternalStorageWritable()) {
73 | DownloadManager.Request request;
74 | request = new DownloadManager.Request(Uri.parse(uri));
75 | request.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, fileName);
76 | request.setTitle(title);
77 | request.setDescription(description);
78 | request.setAllowedOverRoaming(false);
79 | setAllowedNetworks(shouldDownloadOnlyInWifi, request);
80 |
81 | if (customHeaders != null && !customHeaders.isEmpty()) {
82 | // TODO setar variavel no build para logar somente em debug http://toastdroid.com/2014/03/28/customizing-your-build-with-gradle/
83 |
84 | for (String key : customHeaders.keySet()) {
85 | request.addRequestHeader(key, customHeaders.get(key));
86 | }
87 | }
88 |
89 | request = setHiddenDownload(request);
90 | Long dmId = getDMInstance(mContext).enqueue(request);
91 | repository.persistIds(downloadId, dmId);
92 | return dmId >= 0;
93 | }
94 |
95 | return false;
96 | }
97 |
98 | @Override
99 | public boolean isDownloadManagerUiActivated() {
100 | return !this.isDownloadManagerUiDeactivated();
101 | }
102 |
103 | @Override
104 | public boolean isDownloadManagerUiDeactivated(){
105 | try {
106 | int state = mContext.getPackageManager().getApplicationEnabledSetting(PACKAGE_DOWNLOAD_MANAGER_UI);
107 | return this.isDisabledState(state);
108 | } catch (IllegalArgumentException e) {
109 | return true;
110 | }
111 | }
112 |
113 | @Override
114 | public boolean isDownloadManagerActivated() {
115 | return !this.isDownloadManagerDeactivated(mContext);
116 | }
117 |
118 | @Override
119 | public boolean isDownloadManagerDeactivated(Context context) {
120 | try {
121 | int state = context.getPackageManager().getApplicationEnabledSetting(PACKAGE_DOWNLOAD_MANAGER);
122 | return this.isDisabledState(state);
123 | } catch (IllegalArgumentException e) {
124 | return true;
125 | }
126 | }
127 |
128 | private boolean isDisabledState(int state) {
129 | return state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED ||
130 | state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER ||
131 | state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
132 | }
133 |
134 | private void setAllowedNetworks(boolean shouldDownloadOnlyInWifi, DownloadManager.Request request) {
135 | if(shouldDownloadOnlyInWifi) {
136 | request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
137 | } else {
138 | request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
139 | }
140 | }
141 |
142 | private DownloadManager.Request setHiddenDownload(DownloadManager.Request request){
143 | if(isHidden) {
144 | request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
145 | }
146 | return request;
147 | }
148 |
149 | @Override
150 | public boolean cancel(String downloadId) {
151 | return getDMInstance(mContext).remove(repository.getDMId(downloadId)) > 0;
152 | }
153 |
154 | @Override
155 | public void cleanupId(String downloadId) {
156 | repository.removeId(downloadId);
157 | }
158 |
159 | @Override
160 | public void notificationClicked(String[] downloadIds) {
161 | DownloadCommandService.actionNotificationClicked(mContext, downloadIds);
162 | }
163 |
164 | @Override
165 | public DownloadInfo getDownloadInfo(String downloadId) {
166 | DownloadInfo downloadManagerInfo = null;
167 | Long dmDownloadId = repository.getDMId(downloadId);
168 | if (dmDownloadId != null) {
169 | Cursor cursor = getDMInstance(mContext).query(new DownloadManager.Query().setFilterById(repository.getDMId(downloadId)));
170 |
171 | if (cursor != null) {
172 | int status;
173 | int reason;
174 | String filename;
175 | String localURI;
176 | long lastModified;
177 | long downloadedSoFar;
178 | long totalSize;
179 | int progress = 0;
180 |
181 | if (cursor.moveToFirst()) {
182 |
183 | //column for status
184 | int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
185 | status = cursor.getInt(columnIndex);
186 |
187 | //column for reason code if the download failed or paused
188 | int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
189 | reason = cursor.getInt(columnReason);
190 |
191 | //get the download filename
192 | filename = "";
193 | int filenameIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
194 | String cursorString = cursor.getString(filenameIndex);
195 |
196 | if (cursorString != null) {
197 | Logger.debug(TAG, LOG_FEATURE_DOWNLOAD, " [ cursor.getString(filenameIndex) ] = " + cursor.getString(filenameIndex));
198 | Uri uri = Uri.parse(cursorString);
199 |
200 | if (uri != null) {
201 | Logger.debug(TAG, LOG_FEATURE_DOWNLOAD, "[ Uri.parse(cursor.getString(filenameIndex)).getPath() ] = " + Uri.parse(cursor.getString(filenameIndex)).getPath());
202 | filename = uri.getPath();
203 | }
204 | }
205 |
206 | int columnLocalURI = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
207 | localURI = cursor.getString(columnLocalURI);
208 |
209 | int columnLastModified = cursor.getColumnIndex(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP);
210 | lastModified = cursor.getLong(columnLastModified);
211 |
212 |
213 | int columnDownloadedSoFar = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
214 | downloadedSoFar = cursor.getLong(columnDownloadedSoFar);
215 |
216 | int columnTotalSize = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
217 | totalSize = cursor.getLong(columnTotalSize);
218 |
219 | if (status == DownloadManager.STATUS_RUNNING) {
220 | progress = (int) Math.round(((1.0 * downloadedSoFar) / totalSize) * 100);
221 | } else if (status == DownloadManager.STATUS_SUCCESSFUL) {
222 | progress = 100;
223 | }
224 |
225 | downloadManagerInfo = new DownloadInfo(downloadInfoWrapper.translateStatus(status), downloadInfoWrapper.translateReason(reason), filename, localURI, lastModified, downloadedSoFar, totalSize, progress);
226 | }
227 | cursor.close();
228 | }
229 | }
230 | return downloadManagerInfo;
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/Medescope.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope;
2 |
3 | import android.app.Activity;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.os.Environment;
9 | import android.text.TextUtils;
10 |
11 | import java.io.File;
12 | import java.util.Map;
13 |
14 | import br.com.bemobi.medescope.callback.DownloadStatusCallback;
15 | import br.com.bemobi.medescope.constant.DownloadConstants;
16 | import br.com.bemobi.medescope.exception.DirectoryNotMountedException;
17 | import br.com.bemobi.medescope.exception.PathNotFoundException;
18 | import br.com.bemobi.medescope.log.Logger;
19 | import br.com.bemobi.medescope.model.DownloadRequest;
20 | import br.com.bemobi.medescope.service.impl.DownloadCommandService;
21 |
22 | /**
23 | * Created by bkosawa on 26/06/15.
24 | */
25 | public class Medescope {
26 |
27 |
28 | private final String TAG = Medescope.class.getSimpleName();
29 |
30 | public static final String ACTION_BROADCAST_IN_PROGRESS = "br.com.bemobi.medescope.ACTION_BROADCAST_IN_PROGRESS";
31 | public static final String ACTION_BROADCAST_PAUSED = "br.com.bemobi.medescope.ACTION_BROADCAST_PAUSED";
32 | public static final String ACTION_BROADCAST_NOT_ENQUEUED = "br.com.bemobi.medescope.ACTION_BROADCAST_NOT_ENQUEUED";
33 | public static final String ACTION_BROADCAST_CANCELLED = "br.com.bemobi.medescope.ACTION_BROADCAST_CANCELLED";
34 | public static final String ACTION_BROADCAST_FINISH_WITH_SUCCESS = "br.com.bemobi.medescope.ACTION_BROADCAST_FINISH_WITH_SUCCESS";
35 | public static final String ACTION_BROADCAST_FINISH_WITH_ERROR = "br.com.bemobi.medescope.ACTION_BROADCAST_FINISH_WITH_ERROR";
36 |
37 | private Context mContext;
38 |
39 | private static Medescope instance;
40 |
41 | private static StatusBroadcastReceiver mReceiver;
42 |
43 | private String applicationName;
44 |
45 | private Medescope(Context context) {
46 | this.mContext = context.getApplicationContext();
47 | Logger.setContext(context.getApplicationContext());
48 | this.applicationName = "";
49 | }
50 |
51 | public static Medescope getInstance(Context context) {
52 | if( instance == null) {
53 | instance = new Medescope(context);
54 | mReceiver = new StatusBroadcastReceiver();
55 | }
56 | return instance;
57 | }
58 |
59 | public void setApplicationName(String applicationName){
60 | this.applicationName = applicationName;
61 | }
62 |
63 | public void enqueue(String id, String uri, String fileName, String downloadName, String developerPayload) {
64 | DownloadRequest downloadRequest = new DownloadRequest();
65 | downloadRequest.setId(id);
66 | downloadRequest.setUri(uri);
67 | downloadRequest.setFileName(fileName);
68 | downloadRequest.setDownloadName(downloadName);
69 | downloadRequest.setDownloadDescription(this.applicationName);
70 | downloadRequest.setClientPayload(developerPayload);
71 | downloadRequest.setShouldDownloadOnlyInWifi(false);
72 | enqueue(downloadRequest);
73 | }
74 |
75 | public void enqueue(String id, String uri, String fileName, String downloadName, String developerPayload, boolean shouldDownloadOnlyInWifi) {
76 | DownloadRequest downloadRequest = new DownloadRequest();
77 | downloadRequest.setId(id);
78 | downloadRequest.setUri(uri);
79 | downloadRequest.setFileName(fileName);
80 | downloadRequest.setDownloadName(downloadName);
81 | downloadRequest.setDownloadDescription(this.applicationName);
82 | downloadRequest.setClientPayload(developerPayload);
83 | downloadRequest.setShouldDownloadOnlyInWifi(shouldDownloadOnlyInWifi);
84 | enqueue(downloadRequest);
85 | }
86 |
87 | public void enqueue(String id, String uri, String fileName, String downloadName, String developerPayload, boolean shouldDownloadOnlyInWifi, Map customHeaders) {
88 | DownloadRequest downloadRequest = new DownloadRequest();
89 | downloadRequest.setId(id);
90 | downloadRequest.setUri(uri);
91 | downloadRequest.setFileName(fileName);
92 | downloadRequest.setDownloadName(downloadName);
93 | downloadRequest.setDownloadDescription(this.applicationName);
94 | downloadRequest.setClientPayload(developerPayload);
95 | if(customHeaders != null && !customHeaders.isEmpty()) {
96 | downloadRequest.setCustomHeaders(customHeaders);
97 | } else {
98 | Logger.error(TAG, "YOU, NASTY DEVELOPER, ARE PASSING A NULL OR EMPTY HEADER MAP");
99 | }
100 | downloadRequest.setShouldDownloadOnlyInWifi(shouldDownloadOnlyInWifi);
101 | enqueue(downloadRequest);
102 | }
103 |
104 | public void enqueue(DownloadRequest request) {
105 | if(request.isValid()){
106 | DownloadCommandService.actionEnqueue(mContext, request);
107 | return;
108 | }
109 | Logger.error(TAG, "This is not a valid Request!");
110 | Logger.error(TAG, "Please fill it up with the basic data");
111 | }
112 |
113 | public void cancel(String id){
114 | DownloadCommandService.actionCancel(mContext, id);
115 | }
116 |
117 | public void updateSubscriptionStatusId(Context context, String id){
118 | if(!mReceiver.isCallbackSet()){
119 | Logger.error(TAG, "YOU HAVE NOT SET A CALLBACK YET!!");
120 | Logger.error(TAG, "YOU SHOULD IMPLEMENT A BROADCAST RECEIVER BY YOURSELF");
121 | }
122 | DownloadCommandService.actionSubscribeStatusUpdate(context, id);
123 | }
124 |
125 | public void subscribeStatus(Activity activity, String id, DownloadStatusCallback callback){
126 | mReceiver.setCallback(callback);
127 | activity.registerReceiver(mReceiver, getStatusBroadcastFilter());
128 | DownloadCommandService.actionSubscribeStatusUpdate(mContext, id);
129 | }
130 |
131 | public void unsubscribeStatus(Activity activity){
132 | activity.unregisterReceiver(mReceiver);
133 | DownloadCommandService.actionUnsubscribeStatusUpdate(mContext);
134 | }
135 |
136 | public String getDownloadDirectoryToRead(String subPath) throws DirectoryNotMountedException, PathNotFoundException {
137 | if( !DownloadFileUtils.isExternalStorageReadable() ) {
138 | throw new DirectoryNotMountedException("Directory is not mounted to read!");
139 | }
140 | return getDownloadDirectory(subPath);
141 | }
142 |
143 | public String getDownloadDirectoryToWrite(String subPath) throws DirectoryNotMountedException, PathNotFoundException {
144 | if( !DownloadFileUtils.isExternalStorageWritable() ) {
145 | throw new DirectoryNotMountedException("Directory is not mounted to write!");
146 | }
147 | return getDownloadDirectory(subPath);
148 | }
149 |
150 | private String getDownloadDirectory(String subPath) throws PathNotFoundException {
151 | File file = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
152 | if(file == null) {
153 | throw new PathNotFoundException("External Path DIRECTORY_DOWNLOADS was not found!!");
154 | }
155 | if(TextUtils.isEmpty(subPath)){
156 | return file.getAbsolutePath();
157 | }
158 | return file.getAbsolutePath() + (subPath.startsWith("/") ? subPath : "/" + subPath);
159 | }
160 |
161 | private IntentFilter getStatusBroadcastFilter(){
162 | IntentFilter filter = new IntentFilter();
163 | filter.addAction(Medescope.ACTION_BROADCAST_NOT_ENQUEUED);
164 | filter.addAction(Medescope.ACTION_BROADCAST_PAUSED);
165 | filter.addAction(Medescope.ACTION_BROADCAST_IN_PROGRESS);
166 | filter.addAction(Medescope.ACTION_BROADCAST_CANCELLED);
167 | filter.addAction(Medescope.ACTION_BROADCAST_FINISH_WITH_ERROR);
168 | filter.addAction(Medescope.ACTION_BROADCAST_FINISH_WITH_SUCCESS);
169 | return filter;
170 | }
171 |
172 |
173 | private static class StatusBroadcastReceiver extends BroadcastReceiver {
174 |
175 | private final String TAG = StatusBroadcastReceiver.class.getName();
176 |
177 | private DownloadStatusCallback mCallback;
178 |
179 | public StatusBroadcastReceiver() {
180 | }
181 |
182 | public void setCallback(DownloadStatusCallback callback){
183 | this.mCallback = callback;
184 | }
185 |
186 | @Override
187 | public void onReceive(Context context, Intent intent) {
188 | if(mCallback != null) {
189 | String downloadId = intent.getStringExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID);
190 | String action = intent.getAction();
191 | if (Medescope.ACTION_BROADCAST_IN_PROGRESS.equals(action)) {
192 | int progress = intent.getIntExtra(DownloadConstants.EXTRA_INT_PROGRESS_PERCENTAGE, 0);
193 | mCallback.onDownloadInProgress(downloadId, progress);
194 | } else if (Medescope.ACTION_BROADCAST_PAUSED.equals(action)) {
195 | int reason = intent.getIntExtra(DownloadConstants.EXTRA_INT_REASON_KEY, 0);
196 | mCallback.onDownloadPaused(downloadId, reason);
197 | } else if (Medescope.ACTION_BROADCAST_NOT_ENQUEUED.equals(action)) {
198 | mCallback.onDownloadNotEnqueued(downloadId);
199 | } else if (Medescope.ACTION_BROADCAST_CANCELLED.equals(action)){
200 | mCallback.onDownloadCancelled(downloadId);
201 | } else if (Medescope.ACTION_BROADCAST_FINISH_WITH_ERROR.equals(action)) {
202 | int reason = intent.getIntExtra(DownloadConstants.EXTRA_INT_REASON_KEY, 0);
203 | String data = intent.getStringExtra(DownloadConstants.EXTRA_STRING_JSON_DATA);
204 | mCallback.onDownloadOnFinishedWithError(downloadId, reason, data);
205 | } else if (Medescope.ACTION_BROADCAST_FINISH_WITH_SUCCESS.equals(action)) {
206 | String filePath = intent.getStringExtra(DownloadConstants.EXTRA_STRING_FILE_PATH);
207 | String data = intent.getStringExtra(DownloadConstants.EXTRA_STRING_JSON_DATA);
208 | mCallback.onDownloadOnFinishedWithSuccess(downloadId, filePath, data);
209 | }
210 | } else {
211 | Logger.error(TAG, "You forgot to set a callback!!");
212 | }
213 | }
214 |
215 | public boolean isCallbackSet() {
216 | return mCallback != null;
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/medescope/src/main/java/br/com/bemobi/medescope/service/impl/DownloadCommandService.java:
--------------------------------------------------------------------------------
1 | package br.com.bemobi.medescope.service.impl;
2 |
3 | import android.Manifest;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.pm.PackageManager;
7 | import android.os.Bundle;
8 | import android.os.Handler;
9 | import android.os.HandlerThread;
10 | import android.os.Looper;
11 | import android.os.Message;
12 | import android.os.Process;
13 | import android.support.v4.app.ActivityCompat;
14 | import android.text.TextUtils;
15 |
16 | import br.com.bemobi.medescope.constant.DownloadConstants;
17 | import br.com.bemobi.medescope.constant.DownloadInfoReasonConstants;
18 | import br.com.bemobi.medescope.constant.Extras;
19 | import br.com.bemobi.medescope.log.IntentLogger;
20 | import br.com.bemobi.medescope.log.Logger;
21 | import br.com.bemobi.medescope.model.DownloadInfo;
22 | import br.com.bemobi.medescope.model.DownloadRequest;
23 | import br.com.bemobi.medescope.repository.DownloadDataRepository;
24 | import br.com.bemobi.medescope.repository.impl.MapDownloadDataRepository;
25 | import br.com.bemobi.medescope.service.CommunicationService;
26 | import br.com.bemobi.medescope.service.DownloadCommand;
27 | import br.com.bemobi.medescope.service.DownloadService;
28 |
29 | import static br.com.bemobi.medescope.constant.DownloadConstants.LOG_FEATURE_DOWNLOAD;
30 | import static br.com.bemobi.medescope.constant.DownloadConstants.LOG_FEATURE_SERVICE_LIFECYCLE;
31 |
32 | /**
33 | * Created by bkosawa on 26/06/15.
34 | */
35 | public class DownloadCommandService implements DownloadCommand, Runnable {
36 |
37 | private static final String TAG = DownloadCommandService.class.getSimpleName();
38 |
39 | private static final String ACTION_ENQUEUE = "br.com.bemobi.medescope.ACTION_ENQUEUE";
40 | private static final String ACTION_CANCEL = "br.com.bemobi.medescope.ACTION_CANCEL";
41 | private static final String ACTION_FINISH = "br.com.bemobi.medescope.ACTION_FINISH";
42 | private static final String ACTION_NOTIFICATION_CLICK = "br.com.bemobi.medescope.ACTION_NOTIFICATION_CLICK";
43 | private static final String ACTION_REGISTER_FOR_STATUS = "br.com.bemobi.medescope.ACTION_REGISTER_FOR_STATUS";
44 | private static final String ACTION_UNREGISTER_FOR_STATUS = "br.com.bemobi.medescope.ACTION_UNREGISTER_FOR_STATUS";
45 |
46 | private DownloadService downloadService;
47 |
48 | private DownloadDataRepository downloadDataRepository;
49 |
50 | private CommunicationService communicationService;
51 |
52 | private Looper mServiceLooper;
53 |
54 | private ServiceHandler mServiceHandler;
55 |
56 | private String downloadIdRegisteredToSendProgress = "";
57 |
58 | private boolean isStartedSendProgress = false;
59 |
60 | private Intent sIntent;
61 | private Context mContext;
62 |
63 | public DownloadCommandService(Intent intent, Context mContext) {
64 | this.sIntent = intent;
65 | this.mContext = mContext;
66 |
67 | initThreadHandler();
68 | startCommand();
69 | }
70 |
71 | public static void actionEnqueue(Context context, DownloadRequest downloadRequest) {
72 | Intent serviceIntent = new Intent(context, DownloadCommandService.class);
73 | serviceIntent.setAction(ACTION_ENQUEUE);
74 | serviceIntent.putExtra(Extras.EXTRA_DOWNLOAD, downloadRequest);
75 | new Thread(new DownloadCommandService(serviceIntent, context)).start();
76 | }
77 |
78 | public static void actionSubscribeStatusUpdate(Context context, String id) {
79 | Intent serviceIntent = new Intent(context, DownloadCommandService.class);
80 | serviceIntent.setAction(ACTION_REGISTER_FOR_STATUS);
81 | serviceIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, id);
82 | new Thread(new DownloadCommandService(serviceIntent, context)).start();
83 | }
84 |
85 | public static void actionUnsubscribeStatusUpdate(Context context) {
86 | Intent serviceIntent = new Intent(context, DownloadCommandService.class);
87 | serviceIntent.setAction(ACTION_UNREGISTER_FOR_STATUS);
88 | new Thread(new DownloadCommandService(serviceIntent, context)).start();
89 | }
90 |
91 | public static void actionCancel(Context context, String id) {
92 | Intent serviceIntent = new Intent(context, DownloadCommandService.class);
93 | serviceIntent.setAction(ACTION_CANCEL);
94 | serviceIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, id);
95 | new Thread(new DownloadCommandService(serviceIntent, context)).start();
96 | }
97 |
98 | public static void actionFinishDownload(Context context, String downloadId, DownloadInfo downloadInfo) {
99 | Intent serviceIntent = new Intent(context, DownloadCommandService.class);
100 | serviceIntent.setAction(ACTION_FINISH);
101 | serviceIntent.putExtra(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID, downloadId);
102 | serviceIntent.putExtra(DownloadConstants.EXTRA_DOWNLOAD_INFO, downloadInfo);
103 | new Thread(new DownloadCommandService(serviceIntent, context)).start();
104 | }
105 |
106 | public static void actionNotificationClicked(Context context, String[] downloadIds) {
107 | Intent serviceIntent = new Intent(context, DownloadCommandService.class);
108 | serviceIntent.setAction(ACTION_NOTIFICATION_CLICK);
109 | serviceIntent.putExtra(DownloadConstants.EXTRA_ARRAY_STRING_DOWNLOAD_IDS, downloadIds);
110 | new Thread(new DownloadCommandService(serviceIntent, context)).start();
111 | }
112 |
113 | @Override
114 | public void run() {
115 | Logger.debug(TAG, LOG_FEATURE_SERVICE_LIFECYCLE, "onStartCommand()");
116 | if (sIntent != null) {
117 | executeCommand(sIntent.getAction(), sIntent.getExtras());
118 | } else {
119 | startCommand();
120 | if( !TextUtils.isEmpty(this.downloadIdRegisteredToSendProgress )) {
121 | startProgressSender();
122 | }
123 | }
124 | }
125 |
126 | private void initThreadHandler() {
127 | HandlerThread thread = new HandlerThread("PROGRESS_SENDER", Process.THREAD_PRIORITY_BACKGROUND);
128 | thread.start();
129 | mServiceLooper = thread.getLooper();
130 | mServiceHandler = new ServiceHandler(mServiceLooper);
131 | }
132 |
133 | @Override
134 | public void startCommand() {
135 | Logger.debug(TAG, LOG_FEATURE_SERVICE_LIFECYCLE, "startCommand()");
136 | this.downloadDataRepository = MapDownloadDataRepository.getInstance(mContext.getApplicationContext());
137 | this.downloadService = DMDownloadService.getInstance(mContext.getApplicationContext());
138 | this.communicationService = BroadcastCommunicationService.getInstance(mContext.getApplicationContext());
139 | this.isStartedSendProgress = false;
140 | this.downloadIdRegisteredToSendProgress = downloadDataRepository.recoverSubscribedId();
141 | }
142 |
143 | @Override
144 | public void executeCommand(String action, Bundle extras) {
145 | Logger.debug(TAG, LOG_FEATURE_SERVICE_LIFECYCLE, String.format(">>>>>>>>>>>>>>>>>>>>>>>>>> ACTION RECEIVED: %s", action));
146 | new IntentLogger(TAG, LOG_FEATURE_DOWNLOAD).logBundle(extras);
147 |
148 | if (ACTION_ENQUEUE.equals(action)) {
149 | //TODO transformar os parametros em um objeto Parcelable
150 | DownloadRequest downloadRequest = (DownloadRequest) extras.getSerializable(Extras.EXTRA_DOWNLOAD);
151 | this.enqueue(downloadRequest);
152 | } else if (ACTION_CANCEL.equals(action)) {
153 | cancelAction(getIdStringFromBundle(extras));
154 | } else if (ACTION_FINISH.equals(action)) {
155 | finishAction(getDownloadIdFromBundle(extras), getDownloadInfoFromBundle(extras));
156 | } else if (ACTION_NOTIFICATION_CLICK.equals(action)) {
157 | clickNotificationAction(getDownloadIdsFromBundle(extras));
158 | } else if (ACTION_REGISTER_FOR_STATUS.equals(action)) {
159 | registerForStatus(getIdStringFromBundle(extras));
160 | } else if (ACTION_UNREGISTER_FOR_STATUS.equals(action)) {
161 | unregisterForStatus();
162 | }
163 |
164 | if (downloadDataRepository.isEmptyDownloadData() && !isStartedSendProgress) {
165 | shutdownCommand();
166 | }
167 | }
168 |
169 | @Override
170 | public void shutdownCommand() {
171 | downloadService.shutdown();
172 | }
173 |
174 | @Override
175 | public void enqueue(DownloadRequest downloadRequest) {
176 | if (downloadRequest == null || !downloadRequest.isValid()) {
177 | Logger.error(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, String.format("Invalid download object param: %s", downloadRequest.toString()));
178 | return;
179 | }
180 |
181 | if (downloadDataRepository.containsDownloadDataKey(downloadRequest.getId())) {
182 | DownloadInfo downloadInfo = downloadService.getDownloadInfo(downloadRequest.getId());
183 |
184 | if (downloadInfo == null) {
185 | this.enqueue(downloadService, downloadRequest);
186 | return;
187 | }
188 |
189 | if (downloadInfo.hasFinished()) {
190 | downloadService.cleanupId(downloadRequest.getId());
191 | this.enqueue(downloadService, downloadRequest);
192 | } else {
193 | Logger.error(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, String.format("This download is in execution with status: %s", downloadInfo.getStatus()));
194 | Logger.error(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "Do you would like to subscribe to receive status update? Medescope.subscribeStatus([downloadId])");
195 | }
196 |
197 | } else {
198 | this.enqueue(downloadService, downloadRequest);
199 | }
200 | }
201 |
202 | private void enqueue(DownloadService downloadService, DownloadRequest downloadRequest){
203 | downloadService.cleanupId(downloadRequest.getId());
204 | downloadDataRepository.removeDownloadData(downloadRequest.getId());
205 | downloadDataRepository.putDownloadData(downloadRequest.getId(), downloadRequest.getClientPayload());
206 |
207 | if(!hasPermission()){
208 |
209 | communicationService
210 | .sendFinishWithErrorBroadcastData(
211 | downloadRequest.getId(),
212 | DownloadInfoReasonConstants.ERROR_PERMISSION_NOT_GRANTED,
213 | downloadDataRepository.getDownloadData(downloadRequest.getId()));
214 | return;
215 | }
216 |
217 | boolean enqueued = downloadService.enqueue(
218 | downloadRequest.getId(),
219 | downloadRequest.getUri(),
220 | downloadRequest.getFileName(),
221 | downloadRequest.getDownloadName(),
222 | downloadRequest.getDownloadDescription(),
223 | downloadRequest.getClientPayload(),
224 | downloadRequest.shouldDownloadOnlyInWifi(),
225 | downloadRequest.getCustomHeaders()
226 | );
227 | if (shouldStartSendProgressOnEnqueue(downloadRequest.getId())) {
228 | startProgressSender();
229 | }
230 |
231 | if (!enqueued) {
232 | communicationService
233 | .sendFinishWithErrorBroadcastData(
234 | downloadRequest.getId(),
235 | DownloadInfoReasonConstants.ERROR_GENERIC,
236 | downloadDataRepository.getDownloadData(downloadRequest.getId()));
237 | }
238 | }
239 |
240 | private boolean hasPermission(){
241 | int permission = ActivityCompat
242 | .checkSelfPermission(mContext.getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
243 |
244 | if(permission== PackageManager.PERMISSION_GRANTED){
245 | return true;
246 | }
247 |
248 | return false;
249 | }
250 |
251 | private boolean shouldStartSendProgressOnEnqueue(String enqueueDownloadId){
252 | return enqueueDownloadId.equals(downloadIdRegisteredToSendProgress) && !isStartedSendProgress;
253 | }
254 |
255 | @Override
256 | public void cancelAction(String downloadId) {
257 | if (!TextUtils.isEmpty(downloadId) && downloadDataRepository.containsDownloadDataKey(downloadId)) {
258 | downloadService.cancel(downloadId);
259 | }
260 | }
261 |
262 | @Override
263 | public void finishAction(String downloadId, DownloadInfo downloadInfo) {
264 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "Finish Action");
265 | String downloadData = downloadDataRepository.getDownloadData(downloadId);
266 |
267 | downloadDataRepository.removeDownloadData(downloadId);
268 | downloadService.cleanupId(downloadId);
269 |
270 | if (downloadInfo != null) {
271 | if (downloadInfo.hasFinishedWithSuccess()) {
272 | communicationService.sendFinishWithSuccessBroadcastData(downloadId, downloadInfo.getFilename(), downloadData);
273 | } else if (downloadInfo.hasFinishedWithError()) {
274 | communicationService.sendFinishWithErrorBroadcastData(downloadId, downloadInfo.getReason(), downloadData);
275 | }
276 | } else {
277 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD, "Cancelled");
278 | communicationService.sendCancelled(downloadId);
279 | }
280 | }
281 |
282 | @Override
283 | public void clickNotificationAction(String[] downloadIds) {
284 | communicationService.showDownloadQueue();
285 | }
286 |
287 | private void registerForStatus(String downloadId) {
288 | downloadIdRegisteredToSendProgress = downloadId;
289 | downloadDataRepository.persistSubscribedId(downloadId);
290 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_SERVICE_LIFECYCLE, "isStartedSendProgress:" + isStartedSendProgress);
291 |
292 | if (!isStartedSendProgress) {
293 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_SERVICE_LIFECYCLE, "Starting Sender Progress!");
294 | startProgressSender();
295 | }
296 | }
297 |
298 | private void unregisterForStatus() {
299 | downloadIdRegisteredToSendProgress = "";
300 | downloadDataRepository.removeSubscribedId();
301 | }
302 |
303 | //TODO this method must be atomic(?)
304 | public void startProgressSender() {
305 | Logger.debug(TAG, LOG_FEATURE_SERVICE_LIFECYCLE, "startProgressSender()");
306 |
307 | isStartedSendProgress = true;
308 | Message msg = mServiceHandler.obtainMessage();
309 | mServiceHandler.sendMessage(msg);
310 | }
311 |
312 | private final class ServiceHandler extends Handler {
313 |
314 | public ServiceHandler(Looper looper) {
315 | super(looper);
316 | Logger.debug(TAG, LOG_FEATURE_SERVICE_LIFECYCLE, "ServiceHandler()");
317 | }
318 |
319 | @Override
320 | public void handleMessage(Message msg) {
321 | Logger.debug(TAG, LOG_FEATURE_SERVICE_LIFECYCLE, "ServiceHandler.handleMessage()");
322 | DownloadInfo lastSentDownloadInfo = null;
323 |
324 | if (!downloadDataRepository.containsDownloadDataKey(downloadIdRegisteredToSendProgress)) {
325 | communicationService.sendDownloadStatusNotEnqueue(downloadIdRegisteredToSendProgress);
326 | isStartedSendProgress = false;
327 | }
328 |
329 | DownloadInfo downloadInfo = downloadService.getDownloadInfo(downloadIdRegisteredToSendProgress);
330 | if (downloadInfo == null) {
331 | communicationService.sendDownloadStatusNotEnqueue(downloadIdRegisteredToSendProgress);
332 | isStartedSendProgress = false;
333 | }
334 |
335 | while (!TextUtils.isEmpty(downloadIdRegisteredToSendProgress) && isStartedSendProgress) {
336 | try {
337 |
338 | if (downloadInfo == null
339 | || !downloadDataRepository.containsDownloadDataKey(downloadIdRegisteredToSendProgress)) {
340 | isStartedSendProgress = false;
341 | break;
342 | }
343 |
344 | if (downloadInfo.equals(lastSentDownloadInfo)) {
345 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD_SEND_PROGRESS, "I have already sent this info");
346 | } else if (downloadInfo.hasFinished()) {
347 | // TODO em alguns casos o download está com 100% e não está sendo enviado o evento de FINISHED. Tratar esse caso posteriormente
348 | communicationService.sendDownloadStatusProgress(downloadIdRegisteredToSendProgress, downloadInfo.getProgress());
349 | isStartedSendProgress = false;
350 | break;
351 | }else if (downloadInfo.isPaused()) {
352 | communicationService.sendDownloadStatusPaused(downloadIdRegisteredToSendProgress, downloadInfo.getReason());
353 | } else if (downloadInfo.isInProgress()) {
354 | communicationService.sendDownloadStatusProgress(downloadIdRegisteredToSendProgress, downloadInfo.getProgress());
355 | } else {
356 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD_SEND_PROGRESS, "BIZARRE STATUS!! PANIC ALERT!!!");
357 | }
358 |
359 | lastSentDownloadInfo = downloadInfo;
360 |
361 | Thread.sleep(300);
362 |
363 | downloadInfo = downloadService.getDownloadInfo(downloadIdRegisteredToSendProgress);
364 |
365 | } catch (InterruptedException exception) {
366 | Logger.error(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD_SEND_PROGRESS, "ERROR ON THREAD STATUS SENDER!!!!");
367 | isStartedSendProgress = false;
368 | }
369 | }
370 |
371 | isStartedSendProgress = false;
372 |
373 | Logger.debug(TAG, DownloadConstants.LOG_FEATURE_DOWNLOAD_SEND_PROGRESS, "Finishing Status Sender!!!!!");
374 | }
375 | }
376 |
377 | private String getIdStringFromBundle(Bundle extras) {
378 | return extras.getString(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID);
379 | }
380 |
381 | private String getDownloadIdFromBundle(Bundle extras) {
382 | return extras.getString(DownloadConstants.EXTRA_STRING_DOWNLOAD_ID);
383 | }
384 |
385 | private String[] getDownloadIdsFromBundle(Bundle extras) {
386 | return extras.getStringArray(DownloadConstants.EXTRA_ARRAY_STRING_DOWNLOAD_IDS);
387 | }
388 |
389 | private DownloadInfo getDownloadInfoFromBundle(Bundle extras) {
390 | return extras.getParcelable(DownloadConstants.EXTRA_DOWNLOAD_INFO);
391 | }
392 | }
393 |
--------------------------------------------------------------------------------