From 47d1057ca75ab03315aa44535e82a5aa9faa89ac Mon Sep 17 00:00:00 2001 From: aigestudio Date: Wed, 20 May 2015 11:41:02 +0800 Subject: [PATCH] 1.0.0 --- .idea/.name | 1 + .idea/compiler.xml | 23 + .idea/copyright/Apache.xml | 9 + .idea/copyright/profiles_settings.xml | 3 + .idea/encodings.xml | 5 + .idea/gradle.xml | 20 + .idea/misc.xml | 38 ++ .idea/modules.xml | 11 + .idea/scopes/scope_settings.xml | 5 + .idea/vcs.xml | 8 + Demo/Demo.iml | 91 ++++ Demo/build.gradle | 26 ++ Demo/proguard-rules.pro | 17 + Demo/src/main/AndroidManifest.xml | 26 ++ .../aigestudio/downloader/demo/DLService.java | 65 +++ .../downloader/demo/MainActivity.java | 168 +++++++ .../downloader/demo/NotificationUtil.java | 24 + .../main/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 626 bytes .../main/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 471 bytes .../main/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 849 bytes .../main/res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 1226 bytes .../main/res/drawable-xxxhdpi/ic_launcher.png | Bin 0 -> 2004 bytes Demo/src/main/res/layout/activity_main.xml | 208 +++++++++ Demo/src/main/res/values/strings.xml | 26 ++ Downloader/Downloader.iml | 89 ++++ Downloader/build.gradle | 23 + Downloader/proguard-rules.pro | 17 + Downloader/src/main/AndroidManifest.xml | 1 + .../aigestudio/downloader/bizs/DBManager.java | 142 ++++++ .../aigestudio/downloader/bizs/DLManager.java | 409 ++++++++++++++++++ .../downloader/cons/HttpConnPars.java | 38 ++ .../downloader/cons/PublicCons.java | 77 ++++ .../downloader/daos/DBOpenHelper.java | 45 ++ .../aigestudio/downloader/daos/TaskDAO.java | 72 +++ .../aigestudio/downloader/daos/ThreadDAO.java | 103 +++++ .../downloader/entities/DLInfo.java | 19 + .../downloader/entities/TaskInfo.java | 19 + .../downloader/entities/ThreadInfo.java | 21 + .../aigestudio/downloader/interfaces/DAO.java | 31 ++ .../downloader/interfaces/DLTaskListener.java | 63 +++ .../interfaces/IDLThreadListener.java | 11 + .../aigestudio/downloader/utils/FileUtil.java | 64 +++ .../aigestudio/downloader/utils/LogUtil.java | 52 +++ .../aigestudio/downloader/utils/NetUtil.java | 123 ++++++ MultiThreadDownloader.iml | 21 + build.gradle | 14 + gradle.properties | 18 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 +++++++ gradlew.bat | 90 ++++ settings.gradle | 1 + 52 files changed, 2507 insertions(+) create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/Apache.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/scopes/scope_settings.xml create mode 100644 .idea/vcs.xml create mode 100644 Demo/Demo.iml create mode 100644 Demo/build.gradle create mode 100644 Demo/proguard-rules.pro create mode 100644 Demo/src/main/AndroidManifest.xml create mode 100644 Demo/src/main/java/cn/aigestudio/downloader/demo/DLService.java create mode 100644 Demo/src/main/java/cn/aigestudio/downloader/demo/MainActivity.java create mode 100644 Demo/src/main/java/cn/aigestudio/downloader/demo/NotificationUtil.java create mode 100644 Demo/src/main/res/drawable-hdpi/ic_launcher.png create mode 100644 Demo/src/main/res/drawable-mdpi/ic_launcher.png create mode 100644 Demo/src/main/res/drawable-xhdpi/ic_launcher.png create mode 100644 Demo/src/main/res/drawable-xxhdpi/ic_launcher.png create mode 100644 Demo/src/main/res/drawable-xxxhdpi/ic_launcher.png create mode 100644 Demo/src/main/res/layout/activity_main.xml create mode 100644 Demo/src/main/res/values/strings.xml create mode 100644 Downloader/Downloader.iml create mode 100644 Downloader/build.gradle create mode 100644 Downloader/proguard-rules.pro create mode 100644 Downloader/src/main/AndroidManifest.xml create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/bizs/DBManager.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/bizs/DLManager.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/cons/HttpConnPars.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/cons/PublicCons.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/daos/DBOpenHelper.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/daos/TaskDAO.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/daos/ThreadDAO.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/entities/DLInfo.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/entities/TaskInfo.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/entities/ThreadInfo.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/interfaces/DAO.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/interfaces/DLTaskListener.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/interfaces/IDLThreadListener.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/utils/FileUtil.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/utils/LogUtil.java create mode 100644 Downloader/src/main/java/cn/aigestudio/downloader/utils/NetUtil.java create mode 100644 MultiThreadDownloader.iml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..60ccf44 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +MultiThreadDownloader \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..217af47 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/.idea/copyright/Apache.xml b/.idea/copyright/Apache.xml new file mode 100644 index 0000000..7c21b31 --- /dev/null +++ b/.idea/copyright/Apache.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..f1f8114 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..cbaffd1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + Apache + + + + + + + + 1.8 + + + + + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..823d9dd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..9d32e50 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Demo/Demo.iml b/Demo/Demo.iml new file mode 100644 index 0000000..5449630 --- /dev/null +++ b/Demo/Demo.iml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/build.gradle b/Demo/build.gradle new file mode 100644 index 0000000..6e30614 --- /dev/null +++ b/Demo/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 22 + buildToolsVersion "22.0.1" + + defaultConfig { + applicationId "cn.aigestudio.downloader.demo" + minSdkVersion 4 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile project(':Downloader') + compile 'com.android.support:support-v4:22.1.1' +} diff --git a/Demo/proguard-rules.pro b/Demo/proguard-rules.pro new file mode 100644 index 0000000..723652e --- /dev/null +++ b/Demo/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this dlLocalFile are appended to flags specified +# in H:\Programming\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include dirPath and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/Demo/src/main/AndroidManifest.xml b/Demo/src/main/AndroidManifest.xml new file mode 100644 index 0000000..5f7f85c --- /dev/null +++ b/Demo/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/src/main/java/cn/aigestudio/downloader/demo/DLService.java b/Demo/src/main/java/cn/aigestudio/downloader/demo/DLService.java new file mode 100644 index 0000000..c8bba8c --- /dev/null +++ b/Demo/src/main/java/cn/aigestudio/downloader/demo/DLService.java @@ -0,0 +1,65 @@ +package cn.aigestudio.downloader.demo; + +import android.app.NotificationManager; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.IBinder; +import android.support.v4.app.NotificationCompat; + +import java.io.File; + +import cn.aigestudio.downloader.bizs.DLManager; +import cn.aigestudio.downloader.interfaces.DLTaskListener; +import cn.aigestudio.downloader.utils.FileUtil; +import cn.aigestudio.downloader.utils.LogUtil; + +/** + * 执行下载的Service + * + * @author AigeStudio 2015-05-18 + */ +public class DLService extends Service { + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String url = intent.getStringExtra("url"); + String path = intent.getStringExtra("path"); + final int id = intent.getIntExtra("id", -1); + final NotificationManager nm = (NotificationManager) getSystemService(Context + .NOTIFICATION_SERVICE); + final NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + .setContentTitle(FileUtil.getFileNameFromUrl(url).replace("/", "")) + .setSmallIcon(R.drawable.ic_launcher); + + DLManager.getInstance(this).dlStart(url, path, new DLTaskListener() { + @Override + public void onProgress(int progress) { + builder.setProgress(100, progress, false); + nm.notify(id, builder.build()); + } + + @Override + public void onFinish(File file) { + LogUtil.i("onFinish"); + installApk(file); + nm.cancel(id); + } + }); + return super.onStartCommand(intent, flags, startId); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + private void installApk(File file) { + LogUtil.i("installApk"); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); + startActivity(intent); + } +} diff --git a/Demo/src/main/java/cn/aigestudio/downloader/demo/MainActivity.java b/Demo/src/main/java/cn/aigestudio/downloader/demo/MainActivity.java new file mode 100644 index 0000000..1178c08 --- /dev/null +++ b/Demo/src/main/java/cn/aigestudio/downloader/demo/MainActivity.java @@ -0,0 +1,168 @@ +package cn.aigestudio.downloader.demo; + +import android.app.Activity; +import android.app.Notification; +import android.os.Bundle; +import android.os.Environment; +import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; + +import cn.aigestudio.downloader.bizs.DLManager; +import cn.aigestudio.downloader.interfaces.DLTaskListener; + +public class MainActivity extends Activity { + private static final String URL1 = "http://183.230.95.76:9999/bcs.91.com/pcsuite-dev/apk/c684f54c3f941cd71baef085e2ac8662.apk"; + private static final String URL2 = "http://bcs.apk.r1.91.com/data/upload/apkres/2015/5_17/13/com.tencent.mobileqq_015020349.apk"; + private static final String URL3 = "http://dlsw.baidu.com/sw-search-sp/soft/9e/12035/BaiduHi_V4.7.1.2_setup.1429175376.exe"; + private static final String URL4 = "http://dlsw.baidu.com/sw-search-sp/soft/a2/12282/SinaUC_Release_8.3.4.22616.1396945592.exe"; + private static final String URL5 = "http://dlsw.baidu.com/sw-search-sp/soft/4b/17170/Install_WLMessenger14.0.8117.416.1393467029.exe"; + private static final String URL6 = "http://dlsw.baidu.com/sw-search-sp/soft/a2/25705/sinaSHOW-v1-1.1395901693.dmg"; + + private static final int[] RES_ID_BTN_START = {R.id.main_dl_start_btn1, R.id.main_dl_start_btn2, + R.id.main_dl_start_btn3, R.id.main_dl_start_btn4, R.id.main_dl_start_btn5, + R.id.main_dl_start_btn6}; + private static final int[] RES_ID_BTN_STOP = {R.id.main_dl_stop_btn1, R.id.main_dl_stop_btn2, + R.id.main_dl_stop_btn3, R.id.main_dl_stop_btn4, R.id.main_dl_stop_btn5, + R.id.main_dl_stop_btn6}; + private static final int[] RES_ID_PB = {R.id.main_dl_pb1, R.id.main_dl_pb2, R.id.main_dl_pb3, + R.id.main_dl_pb4, R.id.main_dl_pb5, R.id.main_dl_pb6}; + private static final int[] RES_ID_NOTIFY = {R.id.main_notify_btn1, R.id.main_notify_btn2, + R.id.main_notify_btn3, R.id.main_notify_btn4, R.id.main_notify_btn5, + R.id.main_notify_btn6}; + + private String saveDir; + + private ProgressBar[] pbDLs; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Button[] btnStarts = new Button[RES_ID_BTN_START.length]; + for (int i = 0; i < btnStarts.length; i++) { + btnStarts[i] = (Button) findViewById(RES_ID_BTN_START[i]); + btnStarts[i].setOnClickListener(new MainClickListener()); + } + + Button[] btnStops = new Button[RES_ID_BTN_STOP.length]; + for (int i = 0; i < btnStops.length; i++) { + btnStops[i] = (Button) findViewById(RES_ID_BTN_STOP[i]); + btnStops[i].setOnClickListener(new MainClickListener()); + } + + pbDLs = new ProgressBar[RES_ID_PB.length]; + for (int i = 0; i < pbDLs.length; i++) { + pbDLs[i] = (ProgressBar) findViewById(RES_ID_PB[i]); + pbDLs[i].setMax(100); + pbDLs[i].setOnClickListener(new MainClickListener()); + } + + Button[] btnNotifys = new Button[RES_ID_NOTIFY.length]; + for (int i = 0; i < btnNotifys.length; i++) { + btnNotifys[i] = (Button) findViewById(RES_ID_NOTIFY[i]); + btnNotifys[i].setOnClickListener(new MainClickListener()); + } + + saveDir = Environment.getExternalStorageDirectory() + "/AigeStudio/"; + } + + private class MainClickListener implements View.OnClickListener { + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.main_dl_start_btn1: + DLManager.getInstance(MainActivity.this).dlStart(URL1, saveDir, + new DLTaskListener() { + @Override + public void onProgress(int progress) { + pbDLs[1].setProgress(progress); + } + }); + break; + case R.id.main_dl_stop_btn1: + DLManager.getInstance(MainActivity.this).dlStop(URL1); + break; + case R.id.main_dl_start_btn2: + DLManager.getInstance(MainActivity.this).dlStart(URL2, saveDir, + new DLTaskListener() { + @Override + public void onProgress(int progress) { + pbDLs[2].setProgress(progress); + } + }); + break; + case R.id.main_dl_stop_btn2: + DLManager.getInstance(MainActivity.this).dlStop(URL2); + break; + case R.id.main_dl_start_btn3: + DLManager.getInstance(MainActivity.this).dlStart(URL3, saveDir, + new DLTaskListener() { + @Override + public void onProgress(int progress) { + pbDLs[3].setProgress(progress); + } + }); + break; + case R.id.main_dl_stop_btn3: + DLManager.getInstance(MainActivity.this).dlStop(URL3); + break; + case R.id.main_dl_start_btn4: + DLManager.getInstance(MainActivity.this).dlStart(URL4, saveDir, + new DLTaskListener() { + @Override + public void onProgress(int progress) { + pbDLs[4].setProgress(progress); + } + }); + break; + case R.id.main_dl_stop_btn4: + DLManager.getInstance(MainActivity.this).dlStop(URL4); + break; + case R.id.main_dl_start_btn5: + DLManager.getInstance(MainActivity.this).dlStart(URL5, saveDir, + new DLTaskListener() { + @Override + public void onProgress(int progress) { + pbDLs[5].setProgress(progress); + } + }); + break; + case R.id.main_dl_stop_btn5: + DLManager.getInstance(MainActivity.this).dlStop(URL5); + break; + case R.id.main_dl_start_btn6: + DLManager.getInstance(MainActivity.this).dlStart(URL6, saveDir, + new DLTaskListener() { + @Override + public void onProgress(int progress) { + pbDLs[6].setProgress(progress); + } + }); + break; + case R.id.main_dl_stop_btn6: + DLManager.getInstance(MainActivity.this).dlStop(URL6); + break; + case R.id.main_notify_btn1: + NotificationUtil.notificationForDLAPK(MainActivity.this, URL1); + break; + case R.id.main_notify_btn2: + NotificationUtil.notificationForDLAPK(MainActivity.this, URL2); + break; + case R.id.main_notify_btn3: + NotificationUtil.notificationForDLAPK(MainActivity.this, URL3); + break; + case R.id.main_notify_btn4: + NotificationUtil.notificationForDLAPK(MainActivity.this, URL4); + break; + case R.id.main_notify_btn5: + NotificationUtil.notificationForDLAPK(MainActivity.this, URL5); + break; + case R.id.main_notify_btn6: + NotificationUtil.notificationForDLAPK(MainActivity.this, URL6); + break; + } + } + } +} diff --git a/Demo/src/main/java/cn/aigestudio/downloader/demo/NotificationUtil.java b/Demo/src/main/java/cn/aigestudio/downloader/demo/NotificationUtil.java new file mode 100644 index 0000000..514d2f2 --- /dev/null +++ b/Demo/src/main/java/cn/aigestudio/downloader/demo/NotificationUtil.java @@ -0,0 +1,24 @@ +package cn.aigestudio.downloader.demo; + +import android.content.Context; +import android.content.Intent; +import android.os.Environment; + +/** + * 通知工具类 + * + * @author AigeStudio 2015-05-18 + */ +public final class NotificationUtil { + public static void notificationForDLAPK(Context context, String url) { + notificationForDLAPK(context, url, Environment.getExternalStorageDirectory() + "/AigeStudio/"); + } + + public static void notificationForDLAPK(Context context, String url, String path) { + Intent intent = new Intent(context, DLService.class); + intent.putExtra("url", url); + intent.putExtra("path", path); + intent.putExtra("id", (int) (Math.random() * 1024)); + context.startService(intent); + } +} diff --git a/Demo/src/main/res/drawable-hdpi/ic_launcher.png b/Demo/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cd9fe5fc614794ec6698440b2a9f89e368bd1922 GIT binary patch literal 626 zcmV-&0*(ENP)JrzJ3CZQ=v2W`5L}#uB0U%V49+^W>U{#KyP%U$k8b)2)Vex4 z3hk3pi%TzQ`z`RU4)wwyt&ZR0Duac^Vj`Cj^6FknCg?2Eia06z{+o(jCWzY_`>+g00x5SFgwF zfQfc=?Kl|+*#^_AA1AA(xel+t7~-uo04bt}w&L5QhDlsIUfcV+iQeyZ_mR#JOPfru zeMOD1{-HfM1Rwy?=n8|3DL)J`Eg~2MgJkO=44Pbn?mXhE?D5M>w-tYf_0Jdg0>v@x z=H++>t0A305rEuyyJIj%9Ner@LI!p7)@oe@YMOrzRq}J4lh^pSTt(#m3r}oD5r9nD zKp140U;zk#MAIndAk0A`fyh~dWZjyc()b4|V>V@a9=4U9z#s$GUyK5nXT!996aWAK M07*qoM6N<$f?$LYq5uE@ literal 0 HcmV?d00001 diff --git a/Demo/src/main/res/drawable-mdpi/ic_launcher.png b/Demo/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..bc3beb865a46005e15b77e8794cf14a459ec5acc GIT binary patch literal 471 zcmV;|0Vw{7P)R=j?w9|6~~Xq{ad2H`)^BMvZulI>#$N)|YE`-~3I z1OZ=CcP|h?KxY7WAa0qF06YzY@S?!_Qnzv)>k$CXnZR5Db|5t~0)QhV2$DNO{r;5t#af-E_{mUu9ma3XE_`BfKEB!m*I(zQ`cqCJhDn`q3 znh7kig&mN|Y~>?#b<#Kn+SrsKn}nGX-2l)jx0H2hDf6UZ>AeWx4T3Pz4;0-}GJzxo z*a1-)-Q#sl4wN_>B^nLJUk@=t@@R2Ul-y$#)z?_juhHBD+*V@;$+(s!vUcP3c5Amu zWJU*DvW(_9EywBDHj@eb$ifaNM)nV`?HR~g;HvJc-+v`mrDWFModF`^gg{~_8%6*C N002ovPDHLkV1o1H%lrTU literal 0 HcmV?d00001 diff --git a/Demo/src/main/res/drawable-xhdpi/ic_launcher.png b/Demo/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..234724a0a6a89df7d5e0bf4fdec792035e2abf57 GIT binary patch literal 849 zcmV-X1FrmuP)DDM}VE3%OnC^FxpEHU}xtti2xUj_7Vix*||(2zy+hd1Oaw-E|Umw z!Duf*fSsMoJ!)5n9EJ-rDCrMsuw|3_vbQ z)MBxG(TUtt#k=(JEPGz zCrPKr$I~JxO_wEu00daho6R#^0sc&@8WB*1%Rh_&f2LK92&ls4A4Y&b)2c=URN?Xu zBfy_&RU-nbaQTO$ZbkU-bp4lj;Z^emjlSH9C>>Lu-bX-V8wfx^V*-tr=L$eTnZSH@ zXIDhtmXrNToGpJJmUgriSHQD_-Tj<*ewGfVZ|@K0v!Mu3o?20V2Ot0eN&=T-{0K5( z^BY2dA4^jc0!-Nah7jP#($s_i6E?pg1o*KuH4R3<(fwOD#^Y;`O%xo5I!XH}=jYnW z!3fYEaCDAOM@JJb^dkTPn+ZhS3u?^$@A6y$jZO4kKx00p2O(gIECE~i z+|VwMetr19y3k1L{jCV@hF;dlf5bGWbw!3NpaNDz6af)bD>@ONg!N=PIY`o7SH{&b z9^S1)HJ{x+7fGroW+^L8vH$j$Fak{Hi{B6e{8*Zr5MaXQH-rE`mZl~In6UW`A;6EN zsR;olY<@!s@MCFeLVyXI-_W20_+g>xUj&K|>i}CU0R+VIEw&?|h$uFIfLOl8b_5g= b#RmQWBju2e@NZ@400000NkvXXu0mjf)P-|a literal 0 HcmV?d00001 diff --git a/Demo/src/main/res/drawable-xxhdpi/ic_launcher.png b/Demo/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6248217cba87565da09918476b06df9331cdbf33 GIT binary patch literal 1226 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$farfn}nni(^Pd+}pVu^MoA*+MWx9 zzWVY)YRQ!)jyHtPJNR~<3;M)X$uN(>wdjcP2ca0NnB`3SU9}P>E>$_^)ph63wZ8K2 z#cyxk{P}G6&2Ecxb3ZmVI4lrO;%seD6cF-Y5%4(VZou@g!G)nwrG`aWfDcLNfa(Q< z*ORAAebB5@V7gBIw}E9suqBgh%KxXniW7P^yk!+w@%G>8tIAYjPgl8+n_i|Ieujyk zWzx;gnX;N5U4ko&qjiseT^XdaaW{+D=6~)+)r$)p6%lvFG z{rBWcr{6z+p1+j+Ooz3=80+HkE;w#?Vhj(o7x6^d-|#BW~9`zrvLwc&s}=- z=FLA|k;+mQ%LdZlWXScc*2_LOaNxYk~K|9RQ3 z&bh7&ViSN)7Uoo#z|zABbi0b6g94|#Fh`?+2iPPv0Vc%>;Kbvj0Q6xe1C!^E84f@# zLX0evJ{UF%a5RGLP6jGdxv;$a?;qE6`K7LW>OY!i%4*+!SjY#8%RgamBt(-hrwH%w z3!loR?)Cn(WIlMX;=QrND|~>(bV6HX0pTXDG^a^~Tj6Q^f$c8>Y*g z7D(-$wNZ^_7T@n}#=B?Ag=M5WQ literal 0 HcmV?d00001 diff --git a/Demo/src/main/res/drawable-xxxhdpi/ic_launcher.png b/Demo/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..8cca71329504ad90581ab8effab24207405401e3 GIT binary patch literal 2004 zcmd5-Yfuwc6u!HxWQ8D`!4fF1jS)dq2$50bxq)EtfuRT@BMm`Ow2FdN5#_NF3?K|a zOB*l>q7@xpO$B^JksVDdDj+T6qfoUXqaZ?zs5}GRcE9vzQ?OlH2>Ya)CF`14670On4~3YpNZ= zq`mqMA6RYl5$p;_SBtlV2Apz~^*^q;JE+ORiMzji{g4YGQgit{5(FyBUa&|ztK$G> z`lcTjfql}gFv@#3vdtcPBrBhZQ|-^sr65wqr-B^<$SXwy;T7ij2TPC_eE+hQzX?+f z7+l0}YMh=G~iK4NCIIK=Jrxi>& zQs?YGH+5|al$vtvA`eE@YMK7Zbp)f7PTNemBrvtHD(hbb{&PA$WunTtBei~af#cv} z_~BKB(moWUGQ0ixl3MZ3im)YZKWfuB)ZZ=e#_8B(=`6TD>HUFhkPvLMO8~g)JI~S3 znXVcpbb990Q3XiwRMFwZ7b;=o{0+;PETGR%fjW7$ni)`~x+HHu)Y9BJ8z*eq&~|y< zs3pSVR=E(Q%MN`Iirp*DFshG@-fIen$1Y~;;o_qW^9gdv3DzmI_@PCpbosgn5=1=e z&cpCh_bKD8H!r`kq*b=KcF*8(x348>aW2jLVgp9yS62dB@FzBh@YytJ)-F%FzX%OI z+#0Pll`el!0ie#r!Ilo2H>o897Y>e;=F z5w~mW%Ov0Nn{t5+u)=TeaU=o1t*_>xIexn=fGh#D)ienm`{e$@S$>f^@gL_~Uh4KG zcNrFZ@XiI}N!{Um2*DWGFngoc{7kAF{rv2TDZeZ*hw9l)C&+1k!5pdRJNsNZ82TaS zDF;||%iRBZ*OSL7ncb0`xYHA^h5yq;^5LX5MAg_2DkROpHpVTR)BV1^kbC*a%|v=*kI3yM9LlL4qtrgWwn3!$Tn_Nv(NNAn2yj#L zE_pVDoocFCvL_3m()G&8f;j+wcj>;o00R)S|JSEqAOtyiv9p~8<7DiYW8Oyq+WvH% zjaL9bc-5;iL@WS}b$t~mLP;Rs+oyAeaUx?wLN5x@daee$Ab|Alsxq_V0NCom*`_lz z%#hGf&i$7-V<8z^V0)Mnuo6e3iZWm2C}gCJE|MnI`@^*4>b_=zcBJ;~bbx5eial{S z35?g<4k&29OV@hwF#;GZEchUz{ix>KS)(`!S&GK#VPa@4Dqte%Mo&BWHUovr{OI2r NtO!~otPPMJ`V+tY^>+XO literal 0 HcmV?d00001 diff --git a/Demo/src/main/res/layout/activity_main.xml b/Demo/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..9751885 --- /dev/null +++ b/Demo/src/main/res/layout/activity_main.xml @@ -0,0 +1,208 @@ + + + + + + +