├── 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 |