源代码备份
This commit is contained in:
2
app/.gitignore
vendored
Normal file
2
app/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/build
|
||||
*.log
|
96
app/build.gradle
Normal file
96
app/build.gradle
Normal file
@ -0,0 +1,96 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.arialyy.simple"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
multiDexEnabled true
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file("lyy.keystore")
|
||||
storePassword "123456"
|
||||
keyAlias "key0"
|
||||
keyPassword "123456"
|
||||
v2SigningEnabled false
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
debuggable true
|
||||
minifyEnabled false //混淆
|
||||
}
|
||||
release {
|
||||
zipAlignEnabled true
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/services/javax.annotation.processing.Processor'
|
||||
merge 'META-INF/services/com.arialyy.aria.core.inf.IUtil'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
|
||||
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.kotlin_version}"
|
||||
api 'com.github.PhilJay:MPAndroidChart:v3.0.3'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
|
||||
implementation 'com.github.bumptech.glide:glide:3.7.0'
|
||||
implementation 'com.pddstudio:highlightjs-android:1.5.0'
|
||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||
implementation project(':AppFrame')
|
||||
|
||||
// aria
|
||||
kapt project(':AriaCompiler')
|
||||
implementation project(':Aria')
|
||||
implementation project(':M3U8Component')
|
||||
implementation project(':FtpComponent')
|
||||
implementation project(path: ':AriaAnnotations')
|
||||
implementation project(path: ':SFtpComponent')
|
||||
|
||||
|
||||
// implementation 'com.arialyy.aria:core:3.8.12'
|
||||
// kapt 'com.arialyy.aria:compiler:3.8.12'
|
||||
// implementation 'com.arialyy.aria:ftpComponent:3.8.12' // 如果需要使用ftp,请增加该组件
|
||||
// implementation 'com.arialyy.aria:sftpComponent:3.8.12' // 如果需要使用ftp,请增加该组件
|
||||
// implementation 'com.arialyy.aria:m3u8Component:3.8.12' // 如果需要使用m3u8下载功能,请增加该组件
|
||||
|
||||
debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
18
app/gradle.properties
Normal file
18
app/gradle.properties
Normal file
@ -0,0 +1,18 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment addComponent
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, addComponent
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
BIN
app/lyy.keystore
Normal file
BIN
app/lyy.keystore
Normal file
Binary file not shown.
135
app/proguard-rules.pro
vendored
Normal file
135
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# 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 *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
################################### 混淆配置 start ###########################################
|
||||
#指定代码的压缩级别
|
||||
-optimizationpasses 1
|
||||
#包明不混合大小写
|
||||
-dontusemixedcaseclassnames
|
||||
#不去忽略非公共的库类
|
||||
-dontskipnonpubliclibraryclasses
|
||||
#优化 不优化输入的类文件
|
||||
-dontoptimize
|
||||
#预校验
|
||||
-dontpreverify
|
||||
#混淆时是否记录日志
|
||||
-verbose
|
||||
# 混淆时所采用的算法
|
||||
#-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||
-optimizations !code/simplification/cast,!field/*,!class/merging/*
|
||||
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
#忽略警告
|
||||
#-ignorewarning
|
||||
################################### 混淆配置 end ############################################
|
||||
|
||||
|
||||
################## 记录生成的日志数据,gradle build时在本项目根目录输出 #################
|
||||
####### 输出文件夹 build/outputs/mapping
|
||||
#apk 包内所有 class 的内部结构
|
||||
-dump build/outputs/mapping/class_files.txt
|
||||
#未混淆的类和成员
|
||||
-printseeds build/outputs/mapping/kpa_seeds.txt
|
||||
#列出从 apk 中删除的代码
|
||||
-printusage build/outputs/mapping/kpa_unused.txt
|
||||
#混淆前后的映射
|
||||
-printmapping build/outputs/mapping/kpa_mapping.txt
|
||||
################## 记录生成的日志数据,gradle build时 在本项目根目录输出-end #################
|
||||
|
||||
################## 常用属性配置-start ##################
|
||||
# 保护注解
|
||||
-keepattributes *Annotation*
|
||||
# 保护support v4 包
|
||||
-dontwarn android.support.v4.app.**
|
||||
-keep class android.support.v4.app.**{ *; }
|
||||
# 保护andorid x
|
||||
-keep class com.google.android.material.** {*;}
|
||||
-keep class androidx.** {*;}
|
||||
-keep public class * extends androidx.**
|
||||
-keep interface androidx.** {*;}
|
||||
-dontwarn com.google.android.material.**
|
||||
-dontnote com.google.android.material.**
|
||||
-dontwarn androidx.**
|
||||
# 保护一些奇葩的问题
|
||||
-dontwarn org.xmlpull.v1.XmlPullParser
|
||||
-dontwarn org.xmlpull.v1.XmlSerializer
|
||||
-keep class org.xmlpull.v1.* {*;}
|
||||
|
||||
# 保护JS接口
|
||||
-keepclassmembers class * {
|
||||
@android.webkit.JavascriptInterface <methods>;
|
||||
}
|
||||
##保持 native 方法不被混淆
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
##保持 Parcelable 不被混淆
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
##保持 Serializable 不被混淆
|
||||
-keepnames class * implements java.io.Serializable
|
||||
#
|
||||
#保持 Serializable 不被混淆并且enum 类也不被混淆
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
#避免混淆泛型 如果混淆报错建议关掉
|
||||
#–keepattributes Signature
|
||||
# webview + js
|
||||
-keepattributes *JavascriptInterface*
|
||||
|
||||
################## 常用属性配置-end ##################
|
||||
|
||||
################## kotlin-start ##################
|
||||
-keep class kotlin.** { *; }
|
||||
-keep class kotlin.Metadata { *; }
|
||||
-dontwarn kotlin.**
|
||||
-keepclassmembers class **$WhenMappings {
|
||||
<fields>;
|
||||
}
|
||||
-keepclassmembers class kotlin.Metadata {
|
||||
public <methods>;
|
||||
}
|
||||
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
|
||||
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
|
||||
}
|
||||
################## kotlin-end ##################
|
||||
|
||||
-dontwarn com.arialyy.aria.**
|
||||
-keep class com.arialyy.aria.**{*;}
|
||||
-keep class **$$DownloadListenerProxy{ *; }
|
||||
-keep class **$$UploadListenerProxy{ *; }
|
||||
-keep class **$$DownloadGroupListenerProxy{ *; }
|
||||
-keep class **$$DGSubListenerProxy{ *; }
|
||||
-keepclasseswithmembernames class * {
|
||||
@Download.* <methods>;
|
||||
@Upload.* <methods>;
|
||||
@DownloadGroup.* <methods>;
|
||||
}
|
||||
-keep class com.arialyy.aria.ftp.download.FtpDLoaderUtil{*;}
|
||||
-adaptresourcefilenames **.IUtil
|
||||
-adaptresourcefilecontents **.IUtil
|
@ -0,0 +1,30 @@
|
||||
package com.example.arial.downloaddemo
|
||||
|
||||
import androidx.test.runner.AndroidJUnit4
|
||||
import com.arialyy.aria.util.CommonUtil
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.net.URLDecoder
|
||||
import java.net.URLEncoder
|
||||
import kotlin.math.pow
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ApiTest {
|
||||
|
||||
@Test
|
||||
fun testAddChar(){
|
||||
var str = "\\\\+道+歉+信\u0026感 谢 信"
|
||||
str = str.replace("\\+".toRegex(), "%2B")
|
||||
println("========")
|
||||
println(str)
|
||||
println(URLEncoder.encode(str))
|
||||
println(URLDecoder.decode(str))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSpeed() {
|
||||
val speed = 1024.0.pow(4.0) * 2
|
||||
println("speed = ${CommonUtil.formatFileSize(speed)}")
|
||||
|
||||
}
|
||||
}
|
72
app/src/main/AndroidManifest.xml
Normal file
72
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:sharedUserId="com.arialyy"
|
||||
package="com.arialyy.simple">
|
||||
|
||||
<application
|
||||
android:name="com.arialyy.simple.base.BaseApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<!--android:name=".test.TestFTPDirActivity"-->
|
||||
<!--android:name=".test.TestFTPActivity"-->
|
||||
<!--android:name=".download.group.DownloadGroupActivity"-->
|
||||
<!--android:name=".MainActivity"-->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".core.download.fragment.MultiFragmentActivity"/>
|
||||
<activity android:name=".core.upload.SFtpUploadActivity" />
|
||||
<activity android:name=".core.download.SFtpDownloadActivity" />
|
||||
<activity android:name=".core.download.DownloadActivity" />
|
||||
<activity android:name=".core.download.SingleTaskActivity" />
|
||||
<activity android:name=".core.download.mutil.MultiTaskListActivity" />
|
||||
<activity android:name=".core.download.fragment.FragmentActivity" />
|
||||
<activity android:name=".core.download.mutil.MultiDownloadActivity" />
|
||||
<activity android:name=".core.download.HighestPriorityActivity" />
|
||||
<activity android:name=".core.download.group.DownloadGroupActivity" />
|
||||
<activity android:name=".core.download.FtpDownloadActivity" />
|
||||
<activity android:name=".core.download.group.FTPDirDownloadActivity" />
|
||||
<activity android:name=".core.upload.HttpUploadActivity" />
|
||||
<activity android:name=".core.upload.FtpUploadActivity" />
|
||||
<activity android:name=".core.download.KotlinDownloadActivity" />
|
||||
<activity android:name=".core.download.ComponentActivity" />
|
||||
<activity
|
||||
android:name=".core.FullScreenCodeActivity"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/FullScreen"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize" />
|
||||
<activity android:name=".core.download.m3u8.M3U8VodDLoadActivity" />
|
||||
<activity android:name=".core.download.m3u8.M3U8LiveDLoadActivity" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/aria_fileprovider_paths" />
|
||||
</provider>
|
||||
|
||||
<service android:name=".core.download.service.DownloadService" />
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
</manifest>
|
165
app/src/main/assets/aria_config.xml
Normal file
165
app/src/main/assets/aria_config.xml
Normal file
@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<aria>
|
||||
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
|
||||
|
||||
<!--Aria框架配置-->
|
||||
<app>
|
||||
<!--是否使用AriaCrashHandler来捕获异常,异常日志保存在:/mnt/sdcard/Android/data/{package_name}/files/log/-->
|
||||
<useAriaCrashHandler value="false"/>
|
||||
<!--设置Aria的日志级别,{@link ALog#LOG_LEVEL_VERBOSE}-->
|
||||
<logLevel value="2"/>
|
||||
<!-- 是否检查网络 true: 检查网络,false: 不检查网络-->
|
||||
<netCheck value="true"/>
|
||||
<!--除非无法使用注解,否则不建议使用广播来接受任务状态,true:使用广播接收任务状态,false:不适用广播接收状态 -->
|
||||
<!-- http://aria.laoyuyu.me/aria_doc/api/use_broadcast.html -->
|
||||
<useBroadcast value="false"/>
|
||||
<!--断网的时候是否重试,true:断网也重试;false:断网不重试,直接走失败的回调-->
|
||||
<notNetRetry value="true"/>
|
||||
</app>
|
||||
|
||||
|
||||
<!--普通下载任务-->
|
||||
<download>
|
||||
<!--设置http下载获取文件大小是否使用Head请求。true:使用head请求,false:使用默认的get请求。默认为false-->
|
||||
<!--只适用于3.8.11以上的版本-->
|
||||
<useHeadRequest value="false"/>
|
||||
|
||||
<!--设置任务最大下载速度,0表示不限速,单位为:kb-->
|
||||
<maxSpeed value="0"/>
|
||||
|
||||
<!--
|
||||
多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用
|
||||
注意:
|
||||
1、使用分块模式,在读写性能底下的手机上,合并文件需要的时间会更加长;
|
||||
2、优点是使用多线程的块下载,初始化时,文件初始化时将不会预占用对应长度的空间;
|
||||
3、只对新的多线程下载任务有效
|
||||
4、只对多线程的任务有效
|
||||
-->
|
||||
<useBlock value="true"/>
|
||||
|
||||
<!--设置下载线程数,下载线程数不能小于1
|
||||
注意:
|
||||
1、线程下载数改变后,新的下载任务才会生效;
|
||||
2、如果任务大小小于1m,该设置不会生效;
|
||||
3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间;
|
||||
对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式;
|
||||
-->
|
||||
<threadNum value="1"/>
|
||||
|
||||
<!--设置下载队列最大任务数, 默认为2-->
|
||||
<maxTaskNum value="1"/>
|
||||
|
||||
<!--设置下载失败,重试次数,默认为10-->
|
||||
<reTryNum value="5"/>
|
||||
|
||||
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
|
||||
<reTryInterval value="5000"/>
|
||||
|
||||
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
|
||||
<connectTimeOut value="5000"/>
|
||||
|
||||
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
|
||||
<iOTimeOut value="10000"/>
|
||||
|
||||
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
|
||||
<buffSize value="8192"/>
|
||||
|
||||
<!--设置https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
|
||||
<ca name="" path=""/>
|
||||
|
||||
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
|
||||
<convertSpeed value="true"/>
|
||||
|
||||
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
|
||||
<queueMod value="wait"/>
|
||||
|
||||
<!--进度更新更新间隔,默认1000毫秒-->
|
||||
<updateInterval value="1000"/>
|
||||
|
||||
</download>
|
||||
|
||||
<!--普通上传任务-->
|
||||
<upload>
|
||||
<!--设置任务最大上传速度,0表示不限速,单位为:kb-->
|
||||
<maxSpeed value="0"/>
|
||||
|
||||
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
|
||||
<iOTimeOut value="10000"/>
|
||||
|
||||
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,速度会变慢-->
|
||||
<buffSize value="8192"/>
|
||||
|
||||
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
|
||||
<convertSpeed value="true"/>
|
||||
|
||||
<!--设置上传队列最大任务数, 默认为2-->
|
||||
<maxTaskNum value="2"/>
|
||||
|
||||
<!--设置上传失败,重试次数,默认为10-->
|
||||
<reTryNum value="3"/>
|
||||
|
||||
<!--设置重试间隔,单位为毫秒-->
|
||||
<reTryInterval value="2000"/>
|
||||
|
||||
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
|
||||
<connectTimeOut value="5000"/>
|
||||
|
||||
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
|
||||
<queueMod value="wait"/>
|
||||
|
||||
<!--进度更新更新间隔,默认1000毫秒-->
|
||||
<updateInterval value="1000"/>
|
||||
|
||||
</upload>
|
||||
|
||||
<!-- 下载类组合任务 -->
|
||||
<dGroup>
|
||||
|
||||
<!--组合任务下载队列最大任务数, 默认为2-->
|
||||
<maxTaskNum value="3"/>
|
||||
|
||||
<!--设置下载失败,重试次数,默认为10-->
|
||||
<reTryNum value="5"/>
|
||||
|
||||
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
|
||||
<reTryInterval value="5000"/>
|
||||
|
||||
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为wait-->
|
||||
<queueMod value="wait"/>
|
||||
|
||||
<!--进度更新更新间隔,默认1000毫秒-->
|
||||
<updateInterval value="1000"/>
|
||||
<!--子任务失败时组任务回调stop,默认true false将回调fail-->
|
||||
<subFailAsStop value="true"/>
|
||||
|
||||
<!-- =============================以下为子任务的配置====================================-->
|
||||
|
||||
<!--能同时下载的子任务最大任务数,默认3-->
|
||||
<subMaxTaskNum value="5"/>
|
||||
|
||||
<!--子任务下载失败时的重试次数,默认为5-->
|
||||
<subReTryNum value="5"/>
|
||||
|
||||
<!--子任务下载失败时的重试间隔,单位为毫秒,默认2000毫秒-->
|
||||
<subReTryInterval value="5000"/>
|
||||
|
||||
<!--子任务url连接超时时间,单位为毫秒,默认5000毫秒-->
|
||||
<connectTimeOut value="5000"/>
|
||||
|
||||
<!--子任务IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
|
||||
<iOTimeOut value="10000"/>
|
||||
|
||||
<!--子任务写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
|
||||
<buffSize value="8192"/>
|
||||
|
||||
<!--子任务 https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
|
||||
<ca name="" path=""/>
|
||||
|
||||
<!--子任务是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
|
||||
<convertSpeed value="true"/>
|
||||
|
||||
<!--子任务的最大下载速度,0表示不限速,单位为:kb; -->
|
||||
<maxSpeed value="0"/>
|
||||
|
||||
</dGroup>
|
||||
</aria>
|
90
app/src/main/assets/help_code/FtpDownload.java
Normal file
90
app/src/main/assets/help_code/FtpDownload.java
Normal file
@ -0,0 +1,90 @@
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityTestBinding;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2019/5/28.
|
||||
* Ftp 下载
|
||||
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
|
||||
*/
|
||||
public class FtpDownload extends BaseActivity<ActivityTestBinding> {
|
||||
String TAG = "TestFTPActivity";
|
||||
private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
|
||||
private final String FILE_PATH = "/mnt/sdcard/";
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_test;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
mBar.setVisibility(View.GONE);
|
||||
Aria.download(this).register();
|
||||
}
|
||||
|
||||
@Download.onWait void onWait(DownloadTask task) {
|
||||
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
|
||||
}
|
||||
|
||||
@Download.onPre protected void onPre(DownloadTask task) {
|
||||
Log.d(TAG, "onPre");
|
||||
}
|
||||
|
||||
@Download.onTaskStart void taskStart(DownloadTask task) {
|
||||
Log.d(TAG, "onPreStart");
|
||||
}
|
||||
|
||||
@Download.onTaskRunning protected void running(DownloadTask task) {
|
||||
Log.d(TAG, "running,speed=" + task.getConvertSpeed());
|
||||
}
|
||||
|
||||
@Download.onTaskResume void taskResume(DownloadTask task) {
|
||||
Log.d(TAG, "resume");
|
||||
}
|
||||
|
||||
@Download.onTaskStop void taskStop(DownloadTask task) {
|
||||
Log.d(TAG, "stop");
|
||||
}
|
||||
|
||||
@Download.onTaskCancel void taskCancel(DownloadTask task) {
|
||||
Log.d(TAG, "cancel");
|
||||
}
|
||||
|
||||
@Download.onTaskFail void taskFail(DownloadTask task) {
|
||||
Log.d(TAG, "fail");
|
||||
}
|
||||
|
||||
@Download.onTaskComplete void taskComplete(DownloadTask task) {
|
||||
Log.d(TAG, "complete, md5 => " + CommonUtil.getFileMD5(new File(task.getKey())));
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
Aria.download(this)
|
||||
.loadFtp(URL)
|
||||
.setFilePath(FILE_PATH)
|
||||
.login("lao", "123456")
|
||||
//.asFtps() // ftps 配置
|
||||
//.setStorePath("/mnt/sdcard/Download/server.crt") //设置证书路径
|
||||
// .setAlias("www.laoyuyu.me") // 设置证书别名
|
||||
.start();
|
||||
break;
|
||||
case R.id.stop:
|
||||
Aria.download(this).loadFtp(FILE_PATH).stop();
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.download(this).loadFtp(FILE_PATH).cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
127
app/src/main/assets/help_code/FtpUpload.java
Normal file
127
app/src/main/assets/help_code/FtpUpload.java
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.Upload;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.ftp.FtpInterceptHandler;
|
||||
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.task.UploadTask;
|
||||
import com.arialyy.frame.util.FileUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2019/5/28. Ftp 文件上传demo
|
||||
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
|
||||
*/
|
||||
public class FtpUpload extends Activity {
|
||||
private static final String TAG = "FtpUpload";
|
||||
private String mFilePath = Environment.getExternalStorageDirectory().getPath() + "/AriaPrj.rar";
|
||||
private String mUrl = "ftp://172.168.1.2:2121/aa/你好";
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Aria.upload(this).register();
|
||||
// 读取历史记录信息
|
||||
UploadEntity entity = Aria.upload(this).getUploadEntity(mFilePath);
|
||||
if (entity != null) {
|
||||
// 设置界面的进度、文件大小等信息
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (Aria.upload(this).load(mFilePath).isRunning()) {
|
||||
Aria.upload(this).loadFtp(mFilePath).stop(); // 停止任务
|
||||
} else {
|
||||
Aria.upload(this)
|
||||
.loadFtp(mFilePath) // 需要上传的文件
|
||||
.setUploadUrl(mUrl) // 服务器地址
|
||||
// 如果ftp服务器端有同名文件,可通过拦截器处理是覆盖服务器端文件,还是修改文件名
|
||||
.setUploadInterceptor(
|
||||
new IFtpUploadInterceptor() {
|
||||
|
||||
@Override
|
||||
public FtpInterceptHandler onIntercept(UploadEntity entity,
|
||||
List<String> fileList) {
|
||||
FtpInterceptHandler.Builder builder = new FtpInterceptHandler.Builder();
|
||||
//builder.coverServerFile();
|
||||
builder.resetFileName("test.zip");
|
||||
return builder.build();
|
||||
}
|
||||
})
|
||||
.login("N0rI", "0qcK")
|
||||
.start();
|
||||
}
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.upload(this).loadFtp(mFilePath).cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onWait void onWait(UploadTask task) {
|
||||
Log.d(TAG, task.getTaskName() + "_wait");
|
||||
}
|
||||
|
||||
@Upload.onPre public void onPre(UploadTask task) {
|
||||
setFileSize(task.getConvertFileSize());
|
||||
}
|
||||
|
||||
@Upload.onTaskStart public void taskStart(UploadTask task) {
|
||||
Log.d(TAG, "开始上传,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
|
||||
}
|
||||
|
||||
@Upload.onTaskResume public void taskResume(UploadTask task) {
|
||||
Log.d(TAG, "恢复上传");
|
||||
}
|
||||
|
||||
@Upload.onTaskStop public void taskStop(UploadTask task) {
|
||||
setSpeed("");
|
||||
Log.d(TAG, "停止上传");
|
||||
}
|
||||
|
||||
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
|
||||
setSpeed("");
|
||||
setFileSize("");
|
||||
setProgress(0);
|
||||
Log.d(TAG, "删除任务");
|
||||
}
|
||||
|
||||
@Upload.onTaskFail public void taskFail(UploadTask task) {
|
||||
Log.d(TAG, "上传失败");
|
||||
}
|
||||
|
||||
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
|
||||
Log.d(TAG, "PP = " + task.getPercent());
|
||||
setProgress(task.getPercent());
|
||||
setSpeed(task.getConvertSpeed());
|
||||
}
|
||||
|
||||
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
|
||||
setProgress(100);
|
||||
setSpeed("");
|
||||
T.showShort(this, "文件:" + task.getEntity().getFileName() + ",上传完成");
|
||||
}
|
||||
}
|
114
app/src/main/assets/help_code/HttpDownload.java
Normal file
114
app/src/main/assets/help_code/HttpDownload.java
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.upload;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.frame.util.FileUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/28. HTTP 文件下载demo
|
||||
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
|
||||
*/
|
||||
public class FtpUpload extends Activity {
|
||||
private static final String TAG = "FtpUpload";
|
||||
private String mFilePath = Environment.getExternalStorageDirectory().getPath() + "/test.apk";
|
||||
private String mUrl = "http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Aria.download(this).register();
|
||||
// 读取历史记录信息
|
||||
DownloadEntity entity = Aria.download(this).getDownloadEntity(mFilePath);
|
||||
if (entity != null) {
|
||||
// 设置界面的进度、文件大小等信息
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (Aria.download(this).load(mUrl).isRunning()) {
|
||||
Aria.download(this).load(mUrl).stop(); // 停止任务
|
||||
} else {
|
||||
Aria.download(this)
|
||||
.load(mUrl) // 下载url
|
||||
.setFilePath(mFilePath) // 文件保存路径
|
||||
//.addHeader(key, value) // 添加头
|
||||
//.asPost() //或 asGet()
|
||||
//.setParam() // 设置参数
|
||||
.create();
|
||||
}
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.download(this).load(mUrl).cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onWait void onWait(DownloadTask task) {
|
||||
Log.d(TAG, task.getTaskName() + "_wait");
|
||||
}
|
||||
|
||||
@Download.onPre public void onPre(DownloadTask task) {
|
||||
setFileSize(task.getConvertFileSize());
|
||||
}
|
||||
|
||||
@Download.onTaskStart public void taskStart(DownloadTask task) {
|
||||
Log.d(TAG, "开始下载,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
|
||||
}
|
||||
|
||||
@Download.onTaskResume public void taskResume(DownloadTask task) {
|
||||
Log.d(TAG, "恢复下载");
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void taskStop(DownloadTask task) {
|
||||
setSpeed("");
|
||||
Log.d(TAG, "停止下载");
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void taskCancel(DownloadTask task) {
|
||||
setSpeed("");
|
||||
setFileSize("");
|
||||
setProgress(0);
|
||||
Log.d(TAG, "删除任务");
|
||||
}
|
||||
|
||||
@Download.onTaskFail public void taskFail(DownloadTask task) {
|
||||
Log.d(TAG, "下载失败");
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void taskRunning(DownloadTask task) {
|
||||
Log.d(TAG, "PP = " + task.getPercent());
|
||||
setProgress(task.getPercent());
|
||||
setSpeed(task.getConvertSpeed());
|
||||
}
|
||||
|
||||
@Download.onTaskComplete public void taskComplete(DownloadTask task) {
|
||||
setProgress(100);
|
||||
setSpeed("");
|
||||
T.showShort(this, "文件:" + task.getEntity().getFileName() + ",下载完成");
|
||||
}
|
||||
}
|
170
app/src/main/assets/help_code/KotlinHttpDownload.kt
Normal file
170
app/src/main/assets/help_code/KotlinHttpDownload.kt
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import com.arialyy.annotations.Download
|
||||
import com.arialyy.aria.core.Aria
|
||||
import com.arialyy.aria.core.download.target.HttpNormalTarget
|
||||
import com.arialyy.aria.core.task.DownloadTask
|
||||
import com.arialyy.aria.inf.IEntity
|
||||
import com.arialyy.simple.R
|
||||
import com.arialyy.simple.base.BaseActivity
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/10/23.
|
||||
*/
|
||||
class KotlinDownloadActivity : BaseActivity<ActivitySingleBinding>() {
|
||||
|
||||
private val DOWNLOAD_URL =
|
||||
"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"
|
||||
|
||||
private lateinit var mStart: Button
|
||||
private lateinit var mStop: Button
|
||||
private lateinit var mCancel: Button
|
||||
private lateinit var target: HttpNormalTarget
|
||||
|
||||
override fun setLayoutId(): Int {
|
||||
return R.layout.activity_single
|
||||
}
|
||||
|
||||
override fun init(savedInstanceState: Bundle?) {
|
||||
title = "kotlin测试"
|
||||
Aria.get(this)
|
||||
.downloadConfig.maxTaskNum = 2
|
||||
Aria.download(this)
|
||||
.register()
|
||||
mStart = findViewById(R.id.start)
|
||||
mStop = findViewById(R.id.stop)
|
||||
mCancel = findViewById(R.id.cancel)
|
||||
mStop.visibility = View.GONE
|
||||
|
||||
target = Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
binding.progress = target.percent
|
||||
if (target.taskState == com.arialyy.aria.inf.IEntity.STATE_STOP) {
|
||||
mStart.text = "恢复"
|
||||
} else if (target.isRunning) {
|
||||
mStart.text = "停止"
|
||||
}
|
||||
binding.fileSize = target.convertFileSize
|
||||
}
|
||||
|
||||
/**
|
||||
* 注解方法不能添加internal修饰符,否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: peerIndex 1 for '$a' not in range (received 0 arguments)错误
|
||||
*/
|
||||
@Download.onTaskRunning
|
||||
fun running(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
Log.d(TAG, task.percent.toString())
|
||||
val len = task.fileSize
|
||||
if (len == 0L) {
|
||||
binding.progress = 0
|
||||
} else {
|
||||
binding.progress = task.percent
|
||||
}
|
||||
binding.speed = task.convertSpeed
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
fun onWait(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
Log.d(TAG, "wait ==> " + task.downloadEntity.fileName)
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
fun onPre(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
mStart.text = "停止"
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
fun taskStart(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
binding.fileSize = task.convertFileSize
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
fun complete(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
Log.d(TAG, "完成")
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
fun taskResume(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
mStart.text = "停止"
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
fun taskStop(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
mStart.text = "恢复"
|
||||
binding.speed = ""
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
fun taskCancel(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
binding.progress = 0
|
||||
Toast.makeText(this@KotlinDownloadActivity, "取消下载", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
mStart.text = "开始"
|
||||
binding.speed = ""
|
||||
Log.d(TAG, "cancel")
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
fun taskFail(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == DOWNLOAD_URL) {
|
||||
Toast.makeText(this@KotlinDownloadActivity, "下载失败", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
mStart.text = "开始"
|
||||
}
|
||||
}
|
||||
|
||||
fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.start -> {
|
||||
if (target.isRunning) {
|
||||
Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.stop()
|
||||
} else {
|
||||
startD()
|
||||
}
|
||||
}
|
||||
R.id.stop -> Aria.download(this).load(DOWNLOAD_URL).stop()
|
||||
R.id.cancel -> Aria.download(this).load(DOWNLOAD_URL).cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startD() {
|
||||
Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.addHeader("groupHash", "value")
|
||||
.setFilePath(Environment.getExternalStorageDirectory().path + "/kotlin.apk")
|
||||
.start()
|
||||
}
|
||||
}
|
30
app/src/main/assets/id_rsa
Normal file
30
app/src/main/assets/id_rsa
Normal file
@ -0,0 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,8CCEACDEBFE735A306E5E8FA84E90106
|
||||
|
||||
s9LGwTfk9PmcqF50jcFNpSB0O93ehxyD9FIahADuPwYnJCEBFQ+Hm06QOagVxB7z
|
||||
44e23/SCAmo3cWes/IVXUag4+/p8UIcFZc7/CWIBlWaWKuyuP9vD4SD9EiPj6XlC
|
||||
qaAsYcWxPodLoh4RQP08Chw1TET+XkOQuf1FuOil4eEeJYHBCpILF2I9lv7ujo3m
|
||||
S3vS/LLpRUISOm7qVskpq0o1EXibdoSRRqvyzl7hzv+4ik7pDBl1Xun+E05So8Bz
|
||||
aQP6Y8MpuowcFn0Q/OP10vcMm0tT8HwCz2qhfwN+3QQ/MdpePUw9DxCKsFS6cR6u
|
||||
zILuS4a+/huQ2v2ebgTJK4gH/FYaHDP7jIVLKTB6lu4vxABHOrP19gz/Th7ZA/4i
|
||||
JW3wR1VmYpSaGYVRnvzQ9sn/sYjntVOcXfOADHxy7VK2k7Ejwot88OJ96kkNCt26
|
||||
REcb3wM0AFu1sJSpDKLBqAvZEwOMhrbQW6KIorfKLYtywfEkwVdHa8JQY35Z5RrZ
|
||||
qV5XvdW4LVyD0W4yjaeaeWVDShts2e7T+M9BV7LqYS+IKLrVWdQbn+7ymhi69UT8
|
||||
mLbiuLshyBDmjMqltS0Wa1Ejd3MTI2pmzgO5G8qTDL7oa2OiUO4aNCy9sy87fogH
|
||||
iuE+tXrxmFeb8kSmFlblyrOi3EyRSkQEcg+JdooWZMTrxaIQUhYhlA+10JU2pc5w
|
||||
cPg//c1Z2Hlgrx9tlecxDafPgH7AnLuG6J3AgZBnE1511h21iprnEKafMC9h+Lp8
|
||||
JmIeFnI3wLgfAz1olKeoRa/aHZGUiiD+GQxI21Q+XEXChAYf9vR7MuKFWqTI8jk7
|
||||
OfUMPXnKSvPBgTyNyTR8Kf3YBvm0HoWWSQr0YS7CbxsWNzdwpsnKn/qhwdiCt5kK
|
||||
T1gS+yKTk6F/Z2+D0yBSaopOTumNYEDmDW3Er+r2fvM+UBTYdvYNCkaUysX1BK94
|
||||
4jmpeZZtagfppNlcQePuPv2zgckBjfeAdn4oQQqwyDS10ovWnTVEqn9yO0njZjXy
|
||||
PhFZTX2R4Cn6UrW3AlLGCCdl3ogeybuoFF4dYMh6TiMgkD45XbsUrNq+iEBHSiFz
|
||||
YRK4o40lMGvBxSa2bhZHtyoQlUJkptyFriCt9cH4WDbEIafLe/N29AP7ZUOQUOD8
|
||||
ZgyyUmER270uBzQig8hRXBJADZXYKqT3hUrosOt64tjw2CNIkMJPz/KVDOM66prb
|
||||
WiiMV2l+xGnu0tLMCgp7TcCclBEPTlGfpsuP/iFu70j8u4vDjxNwWr3QyuqX0Krs
|
||||
M6pfLHp4RSfUN9AbrjoSAu4XBVE5d8JNf7YGpx2D+HIV1hAEux9IWj+/lAA9eAEq
|
||||
DnzI3JeYlWRCCF8Jg2VGt8fwQDsgTtFsHcaCuZqTPXGwsT3EIi/+9wQJshDyP/D4
|
||||
OWa8HFvkuluLeEDTW7B2u3+AFS01Gt92/fPcY06j+OJL4atW1c5XCF8inlt8Thop
|
||||
+a33yUHpN8uGzkmKUz/onLxvMLYcTDDAXS2dtslij0ldSNC484GpWPHmLfW1jQCv
|
||||
99FqBUbzGMy2RHP1xRHvqK2kV1N72QMde5fDLUP+vygtWFh/Nobi/guPR5OuO60R
|
||||
-----END RSA PRIVATE KEY-----
|
1
app/src/main/assets/id_rsa.pub
Normal file
1
app/src/main/assets/id_rsa.pub
Normal file
@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBlgTuAhvU/Z0ni2PszmIXkDvANMWNYHfiCfvOxRKoK/jCGmKw/TDF1Z49P5M5CMpKwTaQKDxfolYeCgvH9eBmY1NiE26COWexgoqxrw4pWE9/h2Thx7cVWjGWZZ4iwyYfT19/5SgPNujiW9cWGV9N8VXAKe6Sl7v+6TtjLHNCNEn7B90m6sRIYHXsAQ7W7TBlUD5S6wcAsL6v6RVMVVBoIXykNW+zQK6prAWPCtPWcEw3WwfCIUQfJLS8gMC++Ox/bT9gqR+uZTk8MGxafxa9lrvIvpcZh8uVzaP428E3mlSkJnhTAzk43VoKAKxDA1Z+Qehig7VP9GsSn2HGuYE7 AriaL@DESKTOP-BBML2VA
|
71
app/src/main/java/com/arialyy/simple/DbTestActivity.java
Normal file
71
app/src/main/java/com/arialyy/simple/DbTestActivity.java
Normal file
@ -0,0 +1,71 @@
|
||||
package com.arialyy.simple;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityDbTestBinding;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DbTestActivity extends BaseActivity<ActivityDbTestBinding> {
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_db_test;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.insert:
|
||||
insertManyRecord(10000);
|
||||
break;
|
||||
case R.id.search:
|
||||
break;
|
||||
case R.id.search_all:
|
||||
searchAll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void searchAll() {
|
||||
long startT = System.currentTimeMillis();
|
||||
//List<DTaskWrapper> data = DownloadEntity.findRelationData(DownloadEntity.class);
|
||||
|
||||
long endT = System.currentTimeMillis();
|
||||
Log.d(TAG, "search_time=" + (endT - startT));
|
||||
}
|
||||
|
||||
private void insertManyRecord(int len) {
|
||||
long startT = System.currentTimeMillis();
|
||||
List<DbEntity> datas = new ArrayList<>();
|
||||
for (int i = 0; i < len; i++) {
|
||||
String key = UUID.randomUUID().toString();
|
||||
String url = "https://blog.csdn.net/carefree31441/article/details/3998553";
|
||||
|
||||
DownloadEntity entity = new DownloadEntity();
|
||||
entity.setUrl(url);
|
||||
entity.setFileName("ssssssssssssssssss");
|
||||
entity.setFilePath(key);
|
||||
|
||||
DTaskWrapper dte = new DTaskWrapper(entity);
|
||||
|
||||
datas.add(entity);
|
||||
}
|
||||
|
||||
//AbsEntity.insertManyData(DownloadEntity.class, datas);
|
||||
AbsEntity.saveAll(datas);
|
||||
long endT = System.currentTimeMillis();
|
||||
|
||||
Log.d(TAG, "insert_time=" + (endT - startT));
|
||||
}
|
||||
}
|
186
app/src/main/java/com/arialyy/simple/MainActivity.java
Normal file
186
app/src/main/java/com/arialyy/simple/MainActivity.java
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.frame.permission.OnPermissionCallback;
|
||||
import com.arialyy.frame.permission.PermissionManager;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.core.download.DownloadActivity;
|
||||
import com.arialyy.simple.core.download.FtpDownloadActivity;
|
||||
import com.arialyy.simple.core.download.SFtpDownloadActivity;
|
||||
import com.arialyy.simple.core.download.group.DownloadGroupActivity;
|
||||
import com.arialyy.simple.core.download.group.FTPDirDownloadActivity;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8LiveDLoadActivity;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8VodDLoadActivity;
|
||||
import com.arialyy.simple.core.upload.FtpUploadActivity;
|
||||
import com.arialyy.simple.core.upload.HttpUploadActivity;
|
||||
import com.arialyy.simple.core.upload.SFtpUploadActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMainBinding;
|
||||
import com.arialyy.simple.modlue.CommonModule;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/3/1.
|
||||
* 首页
|
||||
*/
|
||||
public class MainActivity extends BaseActivity<ActivityMainBinding> {
|
||||
public static final String KEY_MAIN_DATA = "KEY_MAIN_DATA";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setSupportActionBar(mBar);
|
||||
mBar.setTitle("Aria Demo");
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
|
||||
getBinding().list.setLayoutManager(new LinearLayoutManager(this));
|
||||
final List<NormalTo> data = new ArrayList<>();
|
||||
final Adapter adapter = new Adapter(this, data);
|
||||
getBinding().list.setAdapter(adapter);
|
||||
getBinding().list.addItemDecoration(
|
||||
new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
|
||||
|
||||
final CommonModule module = ViewModelProviders.of(this).get(CommonModule.class);
|
||||
module.getMainData(this).observe(this, new Observer<List<NormalTo>>() {
|
||||
@Override public void onChanged(@Nullable List<NormalTo> normalTos) {
|
||||
if (normalTos != null) {
|
||||
data.addAll(normalTos);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
|
||||
new RvItemClickSupport.OnItemClickListener() {
|
||||
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
DownloadActivity.class);
|
||||
break;
|
||||
case 1:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
HttpUploadActivity.class);
|
||||
break;
|
||||
case 2:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
DownloadGroupActivity.class);
|
||||
break;
|
||||
case 3:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
FtpDownloadActivity.class);
|
||||
break;
|
||||
case 4:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
FTPDirDownloadActivity.class);
|
||||
break;
|
||||
case 5:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
FtpUploadActivity.class);
|
||||
break;
|
||||
case 6:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
M3U8VodDLoadActivity.class);
|
||||
break;
|
||||
case 7:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
M3U8LiveDLoadActivity.class);
|
||||
break;
|
||||
case 8: // d_sftp
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
SFtpDownloadActivity.class);
|
||||
break;
|
||||
case 9: // u_sftp
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
SFtpUploadActivity.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
boolean hasPermission = PermissionManager.getInstance()
|
||||
.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
if (!hasPermission) {
|
||||
PermissionManager.getInstance().requestPermission(this, new OnPermissionCallback() {
|
||||
@Override public void onSuccess(String... permissions) {
|
||||
}
|
||||
|
||||
@Override public void onFail(String... permissions) {
|
||||
T.showShort(MainActivity.this, "没有文件读写权限");
|
||||
finish();
|
||||
}
|
||||
}, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_main;
|
||||
}
|
||||
|
||||
private static class Adapter extends AbsRVAdapter<NormalTo, Adapter.Holder> {
|
||||
|
||||
Adapter(Context context, List<NormalTo> data) {
|
||||
super(context, data);
|
||||
}
|
||||
|
||||
@Override protected Holder getViewHolder(View convertView, int viewType) {
|
||||
return new Holder(convertView);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId(int type) {
|
||||
return R.layout.item_main;
|
||||
}
|
||||
|
||||
@Override protected void bindData(Holder holder, int position, NormalTo item) {
|
||||
holder.title.setText(item.title);
|
||||
holder.desc.setText(item.desc);
|
||||
holder.image.setImageResource(item.icon);
|
||||
}
|
||||
|
||||
private static class Holder extends AbsHolder {
|
||||
TextView title, desc;
|
||||
AppCompatImageView image;
|
||||
|
||||
Holder(View itemView) {
|
||||
super(itemView);
|
||||
title = findViewById(R.id.title);
|
||||
desc = findViewById(R.id.desc);
|
||||
image = findViewById(R.id.image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
81
app/src/main/java/com/arialyy/simple/base/BaseActivity.java
Normal file
81
app/src/main/java/com/arialyy/simple/base/BaseActivity.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import com.arialyy.frame.core.AbsActivity;
|
||||
import com.arialyy.frame.util.AndroidVersionUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.common.MsgDialog;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public abstract class BaseActivity<VB extends ViewDataBinding> extends AbsActivity<VB>
|
||||
implements Toolbar.OnMenuItemClickListener {
|
||||
|
||||
protected Toolbar mBar;
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (AndroidVersionUtil.hasLollipop()) {
|
||||
getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
mBar = findViewById(R.id.toolbar);
|
||||
if (mBar != null) {
|
||||
setSupportActionBar(mBar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
mBar.setOnMenuItemClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTile(String title) {
|
||||
if (mBar == null) {
|
||||
mBar = findViewById(R.id.toolbar);
|
||||
}
|
||||
mBar.setTitle(title);
|
||||
}
|
||||
|
||||
protected void showMsgDialog(String title, String msg) {
|
||||
MsgDialog dialog = new MsgDialog(this, title, msg);
|
||||
dialog.show(getSupportFragmentManager(), "msg_dialog");
|
||||
}
|
||||
|
||||
@Override public boolean onMenuItemClick(MenuItem item) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.base;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.StrictMode;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.frame.core.AbsFrame;
|
||||
import com.arialyy.simple.BuildConfig;
|
||||
//import com.squareup.leakcanary.LeakCanary;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class BaseApplication extends Application {
|
||||
|
||||
private static BaseApplication INSTANCE;
|
||||
|
||||
@Override public void onCreate() {
|
||||
super.onCreate();
|
||||
INSTANCE = this;
|
||||
AbsFrame.init(this);
|
||||
Aria.init(this);
|
||||
if (BuildConfig.DEBUG) {
|
||||
//StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
|
||||
// .detectAll()
|
||||
// .penaltyLog()
|
||||
// .build());
|
||||
//StrictMode.setThreadPolicy(
|
||||
// new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
|
||||
//if (LeakCanary.isInAnalyzerProcess(this)) {//1
|
||||
// //This process is dedicated to LeakCanary for heap analysis.
|
||||
// //You should not init your app in this process.
|
||||
// return;
|
||||
//}
|
||||
//LeakCanary.install(this);
|
||||
}
|
||||
|
||||
//registerReceiver(new ConnectionChangeReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
}
|
||||
|
||||
public static BaseApplication getApp() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
super.onTerminate();
|
||||
}
|
||||
}
|
39
app/src/main/java/com/arialyy/simple/base/BaseDialog.java
Normal file
39
app/src/main/java/com/arialyy/simple/base/BaseDialog.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.base;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import android.os.Bundle;
|
||||
import com.arialyy.frame.core.AbsDialogFragment;
|
||||
|
||||
/**
|
||||
* Created by “AriaLyy@outlook.com” on 2016/11/14.
|
||||
*/
|
||||
public abstract class BaseDialog<VB extends ViewDataBinding> extends AbsDialogFragment<VB> {
|
||||
|
||||
protected BaseDialog(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
|
||||
}
|
||||
}
|
29
app/src/main/java/com/arialyy/simple/base/BaseModule.java
Normal file
29
app/src/main/java/com/arialyy/simple/base/BaseModule.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.base;
|
||||
|
||||
import android.content.Context;
|
||||
import com.arialyy.frame.module.AbsModule;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class BaseModule extends AbsModule {
|
||||
public BaseModule(Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.base.adapter;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2015/12/3.
|
||||
* 通用Holder
|
||||
*/
|
||||
public class AbsHolder extends RecyclerView.ViewHolder {
|
||||
private View mView;
|
||||
private SparseArray<View> mViews = new SparseArray<>();
|
||||
|
||||
public AbsHolder(View itemView) {
|
||||
super(itemView);
|
||||
mView = itemView;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends View> T findViewById(@IdRes int id) {
|
||||
View view = mViews.get(id);
|
||||
if (view == null) {
|
||||
view = mView.findViewById(id);
|
||||
mViews.put(id, view);
|
||||
}
|
||||
return (T) view;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.base.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2015/12/3.
|
||||
* RecyclerView 通用Adapter
|
||||
*/
|
||||
public abstract class AbsRVAdapter<T, Holder extends AbsHolder>
|
||||
extends RecyclerView.Adapter<Holder> {
|
||||
protected String TAG;
|
||||
protected List<T> mData = new ArrayList<>();
|
||||
protected Context mContext;
|
||||
Holder holder;
|
||||
|
||||
public AbsRVAdapter(Context context, List<T> data) {
|
||||
mData = data;
|
||||
mContext = context;
|
||||
String arrays[] = getClass().getName().split("\\.");
|
||||
TAG = arrays[arrays.length - 1];
|
||||
}
|
||||
|
||||
@Override public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view =
|
||||
LayoutInflater.from(parent.getContext()).inflate(setLayoutId(viewType), parent, false);
|
||||
//LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
//VD binding = DataBindingUtil.inflate(inflater, setLayoutId(viewType), parent, false);
|
||||
//;
|
||||
holder = getViewHolder(view, viewType);
|
||||
return holder;
|
||||
}
|
||||
|
||||
protected abstract Holder getViewHolder(View convertView, int viewType);
|
||||
|
||||
@Override public void onBindViewHolder(Holder holder, int position) {
|
||||
bindData(holder, position, mData.get(position));
|
||||
}
|
||||
|
||||
@Override public void onBindViewHolder(Holder holder, int position, List<Object> payloads) {
|
||||
if (payloads == null || payloads.isEmpty()) {
|
||||
bindData(holder, position, mData.get(position));
|
||||
} else {
|
||||
bindData(holder, position, mData.get(position), payloads);
|
||||
}
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
@Override public int getItemCount() {
|
||||
return mData.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* item 的type
|
||||
*/
|
||||
protected abstract int setLayoutId(int type);
|
||||
|
||||
protected abstract void bindData(Holder holder, int position, T item);
|
||||
|
||||
protected void bindData(Holder holder, int position, T item, List<Object> payloads) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.base.adapter;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.simple.R;
|
||||
|
||||
/*
|
||||
* RecyclerView item 事件监听帮助类
|
||||
* RvItemClickSupport.addTo(recyclerView).setOnItemClickListener(new RvItemClickSupport.OnItemClickListener() {
|
||||
*
|
||||
* @Override
|
||||
* public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
* //处理你的事件
|
||||
* });
|
||||
*/
|
||||
public class RvItemClickSupport {
|
||||
private final RecyclerView mRecyclerView;
|
||||
private OnItemClickListener mOnItemClickListener;
|
||||
private OnItemLongClickListener mOnItemLongClickListener;
|
||||
private OnItemTouchListener mOnItemTouchListener;
|
||||
private OnItemFocusChangeListener mOnItemFocusChangeListener;
|
||||
private OnItemKeyListener mOnItemKeyListener;
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClicked(RecyclerView recyclerView, int position, View v);
|
||||
}
|
||||
|
||||
public interface OnItemLongClickListener {
|
||||
boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
|
||||
}
|
||||
|
||||
public interface OnItemTouchListener {
|
||||
public void onTouchEvent(RecyclerView rv, MotionEvent e, int position, View v);
|
||||
}
|
||||
|
||||
public interface OnItemFocusChangeListener {
|
||||
public void onFocusChange(View v, int position, boolean hasFocus);
|
||||
}
|
||||
|
||||
public interface OnItemKeyListener {
|
||||
public boolean onKey(View v, int keyCode, int position, KeyEvent event);
|
||||
}
|
||||
|
||||
private View.OnFocusChangeListener mOnFocusChangeListener = new View.OnFocusChangeListener() {
|
||||
|
||||
@Override public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (mOnItemFocusChangeListener != null) {
|
||||
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
|
||||
mOnItemFocusChangeListener.onFocusChange(v, holder.getAdapterPosition(),
|
||||
holder.itemView.hasFocus());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
if (mOnItemClickListener != null) {
|
||||
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
|
||||
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
|
||||
@Override public boolean onLongClick(View v) {
|
||||
if (mOnItemLongClickListener != null) {
|
||||
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
|
||||
return mOnItemLongClickListener.onItemLongClicked(mRecyclerView,
|
||||
holder.getAdapterPosition(), v);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
|
||||
@Override public boolean onTouch(View v, MotionEvent event) {
|
||||
if (mOnItemTouchListener != null) {
|
||||
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
|
||||
mOnItemTouchListener.onTouchEvent(mRecyclerView, event, holder.getAdapterPosition(), v);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private View.OnKeyListener mOnKeyListener = new View.OnKeyListener() {
|
||||
@Override public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (mOnItemKeyListener != null) {
|
||||
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
|
||||
return mOnItemKeyListener.onKey(v, keyCode, holder.getAdapterPosition(), event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private RecyclerView.OnChildAttachStateChangeListener mAttachListener =
|
||||
new RecyclerView.OnChildAttachStateChangeListener() {
|
||||
@Override public void onChildViewAttachedToWindow(View view) {
|
||||
if (mOnItemClickListener != null) {
|
||||
view.setOnClickListener(mOnClickListener);
|
||||
}
|
||||
if (mOnItemLongClickListener != null) {
|
||||
view.setOnLongClickListener(mOnLongClickListener);
|
||||
}
|
||||
if (mOnItemTouchListener != null) {
|
||||
view.setOnTouchListener(mOnTouchListener);
|
||||
}
|
||||
if (mOnItemFocusChangeListener != null) {
|
||||
view.setOnFocusChangeListener(mOnFocusChangeListener);
|
||||
}
|
||||
if (mOnItemKeyListener != null) {
|
||||
view.setOnKeyListener(mOnKeyListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onChildViewDetachedFromWindow(View view) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private RvItemClickSupport(RecyclerView recyclerView) {
|
||||
mRecyclerView = recyclerView;
|
||||
mRecyclerView.setTag(R.id.item_click_support, this);
|
||||
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
|
||||
}
|
||||
|
||||
public static RvItemClickSupport addTo(RecyclerView view) {
|
||||
RvItemClickSupport support = (RvItemClickSupport) view.getTag(R.id.item_click_support);
|
||||
if (support == null) {
|
||||
support = new RvItemClickSupport(view);
|
||||
}
|
||||
return support;
|
||||
}
|
||||
|
||||
public static RvItemClickSupport removeFrom(RecyclerView view) {
|
||||
RvItemClickSupport support = (RvItemClickSupport) view.getTag(R.id.item_click_support);
|
||||
if (support != null) {
|
||||
support.detach(view);
|
||||
}
|
||||
return support;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置按键监听
|
||||
*/
|
||||
public RvItemClickSupport setOnItemKeyListenr(OnItemKeyListener onItemKeyListener) {
|
||||
mOnItemKeyListener = onItemKeyListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置焦点监听
|
||||
*/
|
||||
public RvItemClickSupport setOnItemFocusChangeListener(
|
||||
OnItemFocusChangeListener onItemFocusChangeListener) {
|
||||
mOnItemFocusChangeListener = onItemFocusChangeListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置触摸监听
|
||||
*/
|
||||
public RvItemClickSupport setOnItemTouchListener(OnItemTouchListener onItemTouchListener) {
|
||||
mOnItemTouchListener = onItemTouchListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置点击监听
|
||||
*/
|
||||
public RvItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
|
||||
mOnItemClickListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置长按监听
|
||||
*/
|
||||
public RvItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
|
||||
mOnItemLongClickListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void detach(RecyclerView view) {
|
||||
view.removeOnChildAttachStateChangeListener(mAttachListener);
|
||||
view.setTag(R.id.item_click_support, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
|
||||
public class ConnectionChangeReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = ConnectionChangeReceiver.class.getSimpleName();
|
||||
|
||||
@Override public void onReceive(Context context, Intent intent) {
|
||||
|
||||
/**
|
||||
* 获得网络连接服务
|
||||
*/
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo.State state =
|
||||
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
|
||||
|
||||
//if (NetworkInfo.State.CONNECTED == state) {
|
||||
// Aria.download(this).resumeAllTask();
|
||||
// Log.w(TAG, "恢复所有任务");
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//Aria.download(this).stopAllTask();
|
||||
//Log.w(TAG, "停止所有任务");
|
||||
//state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
|
||||
//if (NetworkInfo.State.CONNECTED == state) {
|
||||
//
|
||||
//}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DialogModule extends BaseViewModule {
|
||||
|
||||
private MutableLiveData<List<File>> mDirs = new MutableLiveData<>();
|
||||
|
||||
/**
|
||||
* 获取指定目录下的文件夹
|
||||
*
|
||||
* @param path 指定路径
|
||||
*/
|
||||
LiveData<List<File>> getDirs(String path) {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
ALog.e(TAG, "路径为空");
|
||||
return mDirs;
|
||||
}
|
||||
if (!path.startsWith("/")) {
|
||||
ALog.e(TAG, "路径错误");
|
||||
return mDirs;
|
||||
}
|
||||
File file = new File(path);
|
||||
File[] files = file.listFiles();
|
||||
List<File> data = new ArrayList<>();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
data.add(f);
|
||||
}
|
||||
}
|
||||
mDirs.postValue(data);
|
||||
|
||||
return mDirs;
|
||||
}
|
||||
}
|
173
app/src/main/java/com/arialyy/simple/common/DirChooseDialog.java
Normal file
173
app/src/main/java/com/arialyy/simple/common/DirChooseDialog.java
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.databinding.DialogChooseDirBinding;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2019/5/28.
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class DirChooseDialog
|
||||
extends BaseDialog<DialogChooseDirBinding> {
|
||||
public static final int DIR_CHOOSE_DIALOG_RESULT = 0xB2;
|
||||
private String mCurrentPath = Environment.getExternalStorageDirectory().getPath();
|
||||
private List<File> mData = new ArrayList<>();
|
||||
private DialogModule mModule;
|
||||
|
||||
public DirChooseDialog(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
getBinding().list.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
getBinding().list.addItemDecoration(
|
||||
new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
|
||||
final Adapter adapter = new Adapter(getContext(), mData);
|
||||
getBinding().list.setAdapter(adapter);
|
||||
getBinding().setCurrentPath(mCurrentPath);
|
||||
|
||||
mModule = ViewModelProviders.of(this).get(DialogModule.class);
|
||||
mModule.getDirs(mCurrentPath).observe(this, new Observer<List<File>>() {
|
||||
@Override public void onChanged(@Nullable List<File> files) {
|
||||
mData.clear();
|
||||
if (files != null && !files.isEmpty()) {
|
||||
mData.addAll(files);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
if (mCurrentPath.equals(Environment.getExternalStorageDirectory().getPath())) {
|
||||
getBinding().up.setVisibility(View.GONE);
|
||||
}
|
||||
getBinding().setCurrentPath(mCurrentPath);
|
||||
getBinding().currentPath.setSelected(true);
|
||||
}
|
||||
});
|
||||
|
||||
getBinding().up.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
up();
|
||||
}
|
||||
});
|
||||
|
||||
getBinding().enter.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
getSimplerModule().onDialog(DIR_CHOOSE_DIALOG_RESULT, mCurrentPath);
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
|
||||
new RvItemClickSupport.OnItemClickListener() {
|
||||
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
getBinding().up.setVisibility(View.VISIBLE);
|
||||
mCurrentPath = mCurrentPath.concat("/").concat(mData.get(position).getName());
|
||||
mModule.getDirs(mCurrentPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void up() {
|
||||
int endIndex = mCurrentPath.lastIndexOf("/");
|
||||
mCurrentPath = mCurrentPath.substring(0, endIndex);
|
||||
mModule.getDirs(mCurrentPath);
|
||||
}
|
||||
|
||||
@Override public void onStart() {
|
||||
super.onStart();
|
||||
Dialog dialog = getDialog();
|
||||
if (dialog != null) {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
dialog.getWindow()
|
||||
.setLayout((dm.widthPixels), ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
// 拦截返回键
|
||||
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (mCurrentPath.equals(Environment.getExternalStorageDirectory().getPath())) {
|
||||
dismiss();
|
||||
} else {
|
||||
up();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_choose_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 适配器
|
||||
*/
|
||||
private class Adapter extends AbsRVAdapter<File, Adapter.Holder> {
|
||||
|
||||
Adapter(Context context, List<File> data) {
|
||||
super(context, data);
|
||||
}
|
||||
|
||||
@Override protected Holder getViewHolder(View convertView, int viewType) {
|
||||
return new Holder(convertView);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId(int type) {
|
||||
return R.layout.item_choose_dir;
|
||||
}
|
||||
|
||||
@Override protected void bindData(Holder holder, int position, File item) {
|
||||
holder.text.setSelected(true);
|
||||
holder.text.setText(item.getName());
|
||||
}
|
||||
|
||||
private class Holder extends AbsHolder {
|
||||
private TextView text;
|
||||
|
||||
Holder(View itemView) {
|
||||
super(itemView);
|
||||
text = findViewById(R.id.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import com.arialyy.frame.util.DensityUtils;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogLoadingBinding;
|
||||
|
||||
@SuppressLint("ValidFragment") public class LoadingDialog extends BaseDialog<DialogLoadingBinding> {
|
||||
public LoadingDialog(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_loading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Dialog dialog = getDialog();
|
||||
if (dialog != null) {
|
||||
dialog.getWindow().setLayout(DensityUtils.dp2px(120), DensityUtils.dp2px(120));
|
||||
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
getDialog().setCanceledOnTouchOutside(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogModifyPathBinding;
|
||||
import com.arialyy.simple.databinding.DialogMsgBinding;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2019/5/28.
|
||||
* 修改文件路径
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class ModifyPathDialog
|
||||
extends BaseDialog<DialogModifyPathBinding> {
|
||||
public static final int MODIFY_PATH_RESULT = 0xB3;
|
||||
|
||||
private String mTitle, mFilePath, mDir;
|
||||
|
||||
public ModifyPathDialog(Object obj, String title, String filePath) {
|
||||
super(obj);
|
||||
mTitle = title;
|
||||
mFilePath = filePath;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
getBinding().setTitle(mTitle);
|
||||
getBinding().setViewModel(this);
|
||||
final File temp = new File(mFilePath);
|
||||
mDir = temp.getParent();
|
||||
getBinding().setDir(mDir);
|
||||
getBinding().setName(temp.getName());
|
||||
getBinding().edit.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
getBinding().edit.setSelection(temp.getName().length());
|
||||
}
|
||||
});
|
||||
getBinding().enter.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
if (TextUtils.isEmpty(getBinding().getName())) {
|
||||
Toast.makeText(getContext(), getString(R.string.error_file_name_null), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
mFilePath = mDir + "/" + getBinding().getName();
|
||||
getSimplerModule().onDialog(MODIFY_PATH_RESULT, mFilePath);
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
getBinding().cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void chooseDir() {
|
||||
DirChooseDialog dirChooseDialog = new DirChooseDialog(this);
|
||||
dirChooseDialog.show(getChildFragmentManager(), "DirChooseDialog");
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_modify_path;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == DirChooseDialog.DIR_CHOOSE_DIALOG_RESULT) {
|
||||
mDir = String.valueOf(data);
|
||||
getBinding().setDir(mDir);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogModifyUrlBinding;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2019/5/27.
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class ModifyUrlDialog
|
||||
extends BaseDialog<DialogModifyUrlBinding> {
|
||||
public static final int MODIFY_URL_DIALOG_RESULT = 0xA1;
|
||||
|
||||
private String mTitle, mText;
|
||||
|
||||
public ModifyUrlDialog(Object obj, String title, String defaultText) {
|
||||
super(obj);
|
||||
mTitle = title;
|
||||
mText = defaultText;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
getBinding().setTitle(mTitle);
|
||||
getBinding().setText(mText);
|
||||
getBinding().cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
getBinding().enter.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
mText = getBinding().getText();
|
||||
getSimplerModule().onDialog(MODIFY_URL_DIALOG_RESULT, mText);
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
getBinding().edit.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
getBinding().edit.setSelection(mText.length());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_modify_url;
|
||||
}
|
||||
}
|
52
app/src/main/java/com/arialyy/simple/common/MsgDialog.java
Normal file
52
app/src/main/java/com/arialyy/simple/common/MsgDialog.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogMsgBinding;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/6/3.
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class MsgDialog extends BaseDialog<DialogMsgBinding> {
|
||||
|
||||
private String mTitle, mMsg;
|
||||
|
||||
public MsgDialog(Object obj, String title, String msg) {
|
||||
super(obj);
|
||||
mTitle = title;
|
||||
mMsg = msg;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
getBinding().setTitle(mTitle);
|
||||
getBinding().setMsg(mMsg);
|
||||
getBinding().enter.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_msg;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.arialyy.simple.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* normalto实体对应的简单适配器
|
||||
*/
|
||||
public class NormalToAdapter extends AbsRVAdapter<NormalTo, NormalToAdapter.Holder> {
|
||||
|
||||
public NormalToAdapter(Context context, List<NormalTo> data) {
|
||||
super(context, data);
|
||||
}
|
||||
|
||||
@Override protected NormalToAdapter.Holder getViewHolder(View convertView, int viewType) {
|
||||
return new NormalToAdapter.Holder(convertView);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId(int type) {
|
||||
return R.layout.item_download;
|
||||
}
|
||||
|
||||
@Override protected void bindData(NormalToAdapter.Holder holder, int position, NormalTo item) {
|
||||
holder.text.setText(item.title);
|
||||
holder.image.setImageResource(item.icon);
|
||||
}
|
||||
|
||||
class Holder extends AbsHolder {
|
||||
TextView text;
|
||||
AppCompatImageView image;
|
||||
|
||||
Holder(View itemView) {
|
||||
super(itemView);
|
||||
text = findViewById(R.id.title);
|
||||
image = findViewById(R.id.image);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core;
|
||||
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityFullScreenCodeBinding;
|
||||
import com.pddstudio.highlightjs.models.Language;
|
||||
import com.pddstudio.highlightjs.models.Theme;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 全是显示代码的actiivty
|
||||
*/
|
||||
public class FullScreenCodeActivity extends BaseActivity<ActivityFullScreenCodeBinding> {
|
||||
private static final String TAG = "FullScreenCodeActivity";
|
||||
public static final String KEY_FILE_PATH = "KEY_FILE_PATH";
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_full_screen_code;
|
||||
}
|
||||
|
||||
@Override protected void onCreate(Bundle savedInstanceState) {
|
||||
//去除标题栏
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
//去除状态栏
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
String filePath = getIntent().getStringExtra(KEY_FILE_PATH);
|
||||
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
ALog.e(TAG, "代码的文件路径为空");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
getBinding().codeView.setZoomSupportEnabled(true);
|
||||
getBinding().codeView.setHighlightLanguage(Language.JAVA);
|
||||
getBinding().codeView.setTheme(Theme.ANDROID_STUDIO);
|
||||
getBinding().codeView.setSource(new File(filePath));
|
||||
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.simple.MainActivity;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.common.NormalToAdapter;
|
||||
import com.arialyy.simple.core.download.fragment.FragmentActivity;
|
||||
import com.arialyy.simple.databinding.ActivityComponentBinding;
|
||||
import com.arialyy.simple.modlue.CommonModule;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ComponentActivity extends BaseActivity<ActivityComponentBinding> {
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_component;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
NormalTo to = getIntent().getParcelableExtra(MainActivity.KEY_MAIN_DATA);
|
||||
setTitle(to.title);
|
||||
|
||||
final List<NormalTo> data = new ArrayList<>();
|
||||
getBinding().list.setLayoutManager(new GridLayoutManager(this, 2));
|
||||
final NormalToAdapter adapter = new NormalToAdapter(this, data);
|
||||
getBinding().list.setAdapter(adapter);
|
||||
final CommonModule module = ViewModelProviders.of(this).get(CommonModule.class);
|
||||
|
||||
module.getComponentData(this).observe(this,
|
||||
new Observer<List<NormalTo>>() {
|
||||
@Override public void onChanged(@Nullable List<NormalTo> normalTos) {
|
||||
if (normalTos != null) {
|
||||
data.addAll(normalTos);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
|
||||
new RvItemClickSupport.OnItemClickListener() {
|
||||
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
module.startNextActivity(ComponentActivity.this, data.get(position),
|
||||
FragmentActivity.class);
|
||||
break;
|
||||
case 1:
|
||||
DownloadDialog dialog = new DownloadDialog(ComponentActivity.this);
|
||||
dialog.show();
|
||||
break;
|
||||
case 2:
|
||||
new DownloadDialogFragment(ComponentActivity.this).show(getSupportFragmentManager(),
|
||||
"df");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.simple.MainActivity;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.common.NormalToAdapter;
|
||||
import com.arialyy.simple.core.download.fragment.MultiFragmentActivity;
|
||||
import com.arialyy.simple.core.download.mutil.MultiTaskListActivity;
|
||||
import com.arialyy.simple.databinding.ActivityDownloadMeanBinding;
|
||||
import com.arialyy.simple.modlue.CommonModule;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/10/13.
|
||||
*/
|
||||
public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding> {
|
||||
private NormalTo mTo;
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_download_mean;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
mTo = getIntent().getParcelableExtra(MainActivity.KEY_MAIN_DATA);
|
||||
setTitle(mTo.title);
|
||||
|
||||
final List<NormalTo> data = new ArrayList<>();
|
||||
getBinding().list.setLayoutManager(new GridLayoutManager(this, 2));
|
||||
final NormalToAdapter adapter = new NormalToAdapter(this, data);
|
||||
getBinding().list.setAdapter(adapter);
|
||||
final CommonModule module = ViewModelProviders.of(this).get(CommonModule.class);
|
||||
|
||||
module.getDownloadData(this).observe(this,
|
||||
new Observer<List<NormalTo>>() {
|
||||
@Override public void onChanged(@Nullable List<NormalTo> normalTos) {
|
||||
if (normalTos != null) {
|
||||
data.addAll(normalTos);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
|
||||
new RvItemClickSupport.OnItemClickListener() {
|
||||
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
SingleTaskActivity.class);
|
||||
break;
|
||||
case 1:
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
MultiTaskListActivity.class);
|
||||
break;
|
||||
case 2:
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
HighestPriorityActivity.class);
|
||||
break;
|
||||
case 3:
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
KotlinDownloadActivity.class);
|
||||
break;
|
||||
case 4:
|
||||
// 多fragment
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
MultiFragmentActivity.class);
|
||||
break;
|
||||
case 5:
|
||||
// 组件中使用
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
ComponentActivity.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.core.AbsDialog;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/2.
|
||||
*/
|
||||
public class DownloadDialog extends AbsDialog implements View.OnClickListener {
|
||||
private HorizontalProgressBarWithNumber mPb;
|
||||
private Button mStart;
|
||||
private Button mCancel;
|
||||
private TextView mSize;
|
||||
private TextView mSpeed;
|
||||
private long mTaskId = -1;
|
||||
|
||||
private static final String DOWNLOAD_URL =
|
||||
"http://sdkdown.muzhiwan.com/openfile/2019/07/12/com.nswj.acing.mzw_5d283abee9a3c.apk";
|
||||
|
||||
public DownloadDialog(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_download;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Aria.download(this).register();
|
||||
mPb = findViewById(R.id.progressBar);
|
||||
mStart = findViewById(R.id.start);
|
||||
mCancel = findViewById(R.id.cancel);
|
||||
mSize = findViewById(R.id.size);
|
||||
mSpeed = findViewById(R.id.speed);
|
||||
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
|
||||
if (entity != null) {
|
||||
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
|
||||
int p = (int) (entity.getCurrentProgress() * 100 / entity.getFileSize());
|
||||
mPb.setProgress(p);
|
||||
int state = entity.getState();
|
||||
mTaskId = entity.getId();
|
||||
}
|
||||
mStart.setOnClickListener(this);
|
||||
mCancel.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (mTaskId == -1) {
|
||||
mTaskId = Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/女神危机.apk")
|
||||
.create();
|
||||
mStart.setText(getContext().getString(R.string.stop));
|
||||
break;
|
||||
}
|
||||
if (Aria.download(this).load(mTaskId).isRunning()) {
|
||||
Aria.download(this).load(mTaskId).stop();
|
||||
mStart.setText(getContext().getString(R.string.resume));
|
||||
} else {
|
||||
Aria.download(this).load(mTaskId).resume();
|
||||
mStart.setText(getContext().getString(R.string.stop));
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
Aria.download(this).load(mTaskId).cancel();
|
||||
mTaskId = -1;
|
||||
mStart.setText(getContext().getString(R.string.start));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
|
||||
mSize.setText(CommonUtil.formatFileSize(task.getFileSize()));
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
mSpeed.setText(task.getConvertSpeed());
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
mPb.setProgress(0);
|
||||
mSpeed.setText(task.getConvertSpeed());
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
mPb.setProgress(task.getPercent());
|
||||
mSpeed.setText(task.getConvertSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object obj) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogFragmentDownloadBinding;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/8/8.
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class DownloadDialogFragment
|
||||
extends BaseDialog<DialogFragmentDownloadBinding> implements View.OnClickListener {
|
||||
|
||||
private DownloadEntity mEntity;
|
||||
|
||||
private static final String DOWNLOAD_URL =
|
||||
"http://res3.d.cn/android/new/game/2/78702/fzjh_1499390260312.apk?f=web_1";
|
||||
|
||||
protected DownloadDialogFragment(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.download(this).register();
|
||||
mEntity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
|
||||
if (mEntity != null) {
|
||||
if (mEntity.getState() == IEntity.STATE_RUNNING) {
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
} else {
|
||||
getBinding().setStateStr(getString(R.string.resume));
|
||||
}
|
||||
|
||||
getBinding().setFileSize(CommonUtil.formatFileSize(mEntity.getFileSize()));
|
||||
getBinding().setProgress((int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize()));
|
||||
}
|
||||
mRootView.findViewById(R.id.start).setOnClickListener(this);
|
||||
mRootView.findViewById(R.id.cancel).setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_fragment_download;
|
||||
}
|
||||
|
||||
@Override public void onDestroy() {
|
||||
super.onDestroy();
|
||||
Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
@Download.onPre(DOWNLOAD_URL) protected void onPre(DownloadTask task) {
|
||||
}
|
||||
|
||||
@Download.onTaskStart(DOWNLOAD_URL) void taskStart(DownloadTask task) {
|
||||
getBinding().setFileSize(task.getConvertFileSize());
|
||||
}
|
||||
|
||||
@Download.onTaskRunning(DOWNLOAD_URL) protected void running(DownloadTask task) {
|
||||
long len = task.getFileSize();
|
||||
if (len == 0) {
|
||||
getBinding().setProgress(0);
|
||||
} else {
|
||||
getBinding().setProgress(task.getPercent());
|
||||
}
|
||||
getBinding().setSpeed(task.getConvertSpeed());
|
||||
}
|
||||
|
||||
@Download.onTaskResume(DOWNLOAD_URL) void taskResume(DownloadTask task) {
|
||||
}
|
||||
|
||||
@Download.onTaskStop(DOWNLOAD_URL) void taskStop(DownloadTask task) {
|
||||
getBinding().setSpeed("");
|
||||
}
|
||||
|
||||
@Download.onTaskCancel(DOWNLOAD_URL) void taskCancel(DownloadTask task) {
|
||||
getBinding().setProgress(0);
|
||||
Toast.makeText(getContext(), "取消下载", Toast.LENGTH_SHORT).show();
|
||||
getBinding().setSpeed("");
|
||||
}
|
||||
|
||||
@Download.onTaskFail(DOWNLOAD_URL) void taskFail(DownloadTask task) {
|
||||
Toast.makeText(getContext(), "下载失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Download.onTaskComplete(DOWNLOAD_URL) void taskComplete(DownloadTask task) {
|
||||
getBinding().setProgress(100);
|
||||
Toast.makeText(getContext(), "下载完成", Toast.LENGTH_SHORT).show();
|
||||
getBinding().setSpeed("");
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (!AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/放置江湖.apk")
|
||||
.create();
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
break;
|
||||
}
|
||||
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
|
||||
Aria.download(this).load(mEntity.getId()).stop();
|
||||
getBinding().setStateStr(getString(R.string.resume));
|
||||
} else {
|
||||
Aria.download(this).load(mEntity.getId()).resume();
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this).load(mEntity.getId()).cancel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Environment;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseModule;
|
||||
import com.arialyy.simple.core.download.mutil.FileListEntity;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class DownloadModule extends BaseModule {
|
||||
|
||||
public DownloadModule(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 最高优先级任务测试列表
|
||||
*/
|
||||
public List<DownloadEntity> getHighestTestList() {
|
||||
List<DownloadEntity> list = new LinkedList<>();
|
||||
Resources res = getContext().getResources();
|
||||
String[] urls = res.getStringArray(R.array.highest_urls);
|
||||
String[] names = res.getStringArray(R.array.highest_names);
|
||||
for (int i = 0, len = urls.length; i < len; i++) {
|
||||
list.add(createDownloadEntity(urls[i], names[i]));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载地址
|
||||
*/
|
||||
public List<FileListEntity> createMultiTestList() {
|
||||
String[] names = getStringArray(R.array.file_nams);
|
||||
String[] downloadUrl = getStringArray(R.array.download_url);
|
||||
List<FileListEntity> list = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (String name : names) {
|
||||
FileListEntity entity = new FileListEntity();
|
||||
entity.name = name;
|
||||
entity.key = downloadUrl[i];
|
||||
entity.downloadPath = Environment.getExternalStorageDirectory() + "/Download/" + name;
|
||||
list.add(entity);
|
||||
i++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建m3u8下载地址
|
||||
*/
|
||||
public List<FileListEntity> createM3u8TestList(){
|
||||
String[] names = new String[]{"m3u8test1.ts", "m3u8test2.ts"};
|
||||
String[] urls = new String[]{
|
||||
"http://qn.shytong.cn/b83137769ff6b555/11b0c9970f9a3fa0.mp4.m3u8",
|
||||
"http://qn.shytong.cn/8f4011f2a31bd347da42b54fe37a7ba8-transcode.m3u8"
|
||||
};
|
||||
List<FileListEntity> list = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (String name : names) {
|
||||
FileListEntity entity = new FileListEntity();
|
||||
entity.name = name;
|
||||
entity.key = urls[i];
|
||||
entity.type = 2;
|
||||
entity.downloadPath = Environment.getExternalStorageDirectory() + "/Download/" + name;
|
||||
list.add(entity);
|
||||
i++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private String[] getStringArray(int array) {
|
||||
return getContext().getResources().getStringArray(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建任务组
|
||||
*/
|
||||
public List<FileListEntity> createGroupTestList() {
|
||||
List<FileListEntity> list = new ArrayList<>();
|
||||
list.add(createGroupEntity(R.array.group_urls, R.array.group_names, "任务组_0"));
|
||||
list.add(createGroupEntity(R.array.group_urls_1, R.array.group_names_1, "任务组_1"));
|
||||
list.add(createGroupEntity(R.array.group_urls_2, R.array.group_names_2, "任务组_2"));
|
||||
list.add(createGroupEntity(R.array.group_urls_3, R.array.group_names_3, "任务组_3"));
|
||||
return list;
|
||||
}
|
||||
|
||||
private FileListEntity createGroupEntity(int urls, int names, String alias) {
|
||||
FileListEntity entity = new FileListEntity();
|
||||
entity.urls = getStringArray(urls);
|
||||
entity.names = getStringArray(names);
|
||||
entity.type = 1;
|
||||
entity.name = alias;
|
||||
entity.key = CommonUtil.getMd5Code(Arrays.asList(entity.urls));
|
||||
entity.downloadPath = Environment.getExternalStorageDirectory() + "/Download/" + alias;
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载实体,Aria也可以通过下载实体启动下载
|
||||
*/
|
||||
private DownloadEntity createDownloadEntity(String downloadUrl, String name) {
|
||||
String path = Environment.getExternalStorageDirectory() + "/download/" + name + ".apk";
|
||||
DownloadEntity entity = new DownloadEntity();
|
||||
entity.setFileName(name);
|
||||
entity.setUrl(downloadUrl);
|
||||
entity.setFilePath(path);
|
||||
return entity;
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.core.AbsPopupWindow;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/2.
|
||||
*/
|
||||
public class DownloadPopupWindow extends AbsPopupWindow implements View.OnClickListener {
|
||||
private HorizontalProgressBarWithNumber mPb;
|
||||
private Button mStart;
|
||||
private Button mCancel;
|
||||
private TextView mSize;
|
||||
private TextView mSpeed;
|
||||
private long mTaskId = -1;
|
||||
|
||||
private static final String DOWNLOAD_URL =
|
||||
"http://static.gaoshouyou.com/d/25/57/2e25bd9d4557ba31e9beebacfaf9e804.apk";
|
||||
|
||||
public DownloadPopupWindow(Context context) {
|
||||
super(context, new ColorDrawable(Color.WHITE));
|
||||
initWidget();
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_download;
|
||||
}
|
||||
|
||||
private void initWidget() {
|
||||
mPb = mView.findViewById(R.id.progressBar);
|
||||
mStart = mView.findViewById(R.id.start);
|
||||
mCancel = mView.findViewById(R.id.cancel);
|
||||
mSize = mView.findViewById(R.id.size);
|
||||
mSpeed = mView.findViewById(R.id.speed);
|
||||
|
||||
mStart.setOnClickListener(this);
|
||||
mCancel.setOnClickListener(this);
|
||||
|
||||
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
|
||||
if (entity != null) {
|
||||
mPb.setProgress(entity.getPercent());
|
||||
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
|
||||
if (entity.getState() == IEntity.STATE_RUNNING) {
|
||||
mStart.setText(getContext().getString(R.string.stop));
|
||||
} else {
|
||||
mStart.setText(getContext().getString(R.string.resume));
|
||||
}
|
||||
mTaskId = entity.getId();
|
||||
} else {
|
||||
mStart.setText(getContext().getString(R.string.start));
|
||||
}
|
||||
Aria.download(this).register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (mTaskId != -1) {
|
||||
Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/消消乐.apk")
|
||||
.create();
|
||||
mStart.setText(getContext().getString(R.string.stop));
|
||||
break;
|
||||
}
|
||||
if (Aria.download(this).load(mTaskId).isRunning()) {
|
||||
Aria.download(this).load(mTaskId).stop();
|
||||
mStart.setText(getContext().getString(R.string.resume));
|
||||
} else {
|
||||
Aria.download(this).load(mTaskId).resume();
|
||||
mStart.setText(getContext().getString(R.string.stop));
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
|
||||
Aria.download(this).load(mTaskId).cancel();
|
||||
mStart.setText(getContext().getResources().getString(R.string.start));
|
||||
mTaskId = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object obj) {
|
||||
|
||||
}
|
||||
|
||||
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
|
||||
mSize.setText(CommonUtil.formatFileSize(task.getFileSize()));
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
mSpeed.setText("0.0kb/s");
|
||||
mStart.setText(getContext().getString(R.string.resume));
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
mPb.setProgress(0);
|
||||
mSpeed.setText("0.0kb/s");
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
long current = task.getCurrentProgress();
|
||||
long len = task.getFileSize();
|
||||
if (len == 0) {
|
||||
mPb.setProgress(0);
|
||||
} else {
|
||||
mPb.setProgress((int) ((current * 100) / len));
|
||||
}
|
||||
mSpeed.setText(task.getConvertSpeed());
|
||||
}
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/25.
|
||||
* Ftp下载
|
||||
*/
|
||||
public class FtpDownloadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
private String mUrl, mFilePath;
|
||||
private FtpDownloadModule mModule;
|
||||
private long mTaskId;
|
||||
private String user = "lao", passw = "123456";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle("FTP文件下载");
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(FtpDownloadModule.class);
|
||||
|
||||
mModule.getFtpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTaskId = entity.getId();
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
getBinding().pl.setInfo(entity);
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.download(this).loadFtp(mUrl)
|
||||
.setFilePath(mFilePath)
|
||||
.ignoreFilePathOccupy()
|
||||
.option(getFtpOption())
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadFtp(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.loadFtp(mTaskId)
|
||||
.option(getFtpOption())
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadFtp(mTaskId).cancel();
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private FtpOption getFtpOption() {
|
||||
FtpOption option = new FtpOption();
|
||||
option.login(user, passw);
|
||||
//option.setServerIdentifier(FtpOption.FTPServerIdentifier.SYST_NT);
|
||||
//option.setConnectionMode(FtpConnectionMode.DATA_CONNECTION_MODE_ACTIVITY);
|
||||
return option;
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
void taskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
void taskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
mTaskId = -1;
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
ALog.d(TAG, "下载失败");
|
||||
Toast.makeText(this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
if (task != null && task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_single;
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class FtpDownloadModule extends BaseViewModule {
|
||||
private final String FTP_URL_KEY = "FTP_URL_KEY";
|
||||
private final String FTP_PATH_KEY = "FTP_PATH_KEY";
|
||||
|
||||
private final String ftpDefUrl = "ftp://192.168.0.104:2121/qqqq.exe";
|
||||
private final String ftpDefPath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
|
||||
|
||||
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
|
||||
private DownloadEntity singDownloadInfo;
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getFtpDownloadInfo(Context context) {
|
||||
//String url = AppUtil.getConfigValue(context, FTP_URL_KEY, ftpDefUrl);
|
||||
//String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY, ftpDefPath);
|
||||
//String url = "ftp://9.9.9.72:2121/Cyberduck-6.9.4.30164.zip";
|
||||
|
||||
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(ftpDefUrl);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(ftpDefUrl);
|
||||
String name = getFileName(ftpDefUrl);
|
||||
singDownloadInfo.setFileName(name);
|
||||
singDownloadInfo.setFilePath(ftpDefPath + name);
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, FTP_PATH_KEY, singDownloadInfo.getFilePath());
|
||||
AppUtil.setConfigValue(context, FTP_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getSftpDownloadInfo(Context context) {
|
||||
//String url = AppUtil.getConfigValue(context, FTP_URL_KEY, ftpDefUrl);
|
||||
//String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY, ftpDefPath);
|
||||
String url = "ftp://9.9.9.72:22/Cyberduck-6.9.4.30164.zip";
|
||||
|
||||
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
String name = getFileName(ftpDefUrl);
|
||||
singDownloadInfo.setFileName(name);
|
||||
singDownloadInfo.setFilePath(ftpDefPath + name);
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, FTP_PATH_KEY, singDownloadInfo.getFilePath());
|
||||
AppUtil.setConfigValue(context, FTP_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件保存路径
|
||||
*
|
||||
* @param dirPath 文件保存文件夹
|
||||
*/
|
||||
void updateFilePath(Context context, String dirPath) {
|
||||
if (TextUtils.isEmpty(dirPath)) {
|
||||
ALog.e(TAG, "文件保存路径为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, FTP_PATH_KEY, dirPath);
|
||||
singDownloadInfo.setFilePath(dirPath + singDownloadInfo.getFileName());
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新url
|
||||
*/
|
||||
void uploadUrl(Context context, String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ALog.e(TAG, "下载地址为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, FTP_URL_KEY, url);
|
||||
File file = new File(singDownloadInfo.getFilePath());
|
||||
String name = getFileName(url);
|
||||
singDownloadInfo.setFilePath(file.getParent() + name);
|
||||
singDownloadInfo.setFileName(name);
|
||||
singDownloadInfo.setUrl(url);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过url获取文件名
|
||||
*
|
||||
* @param url ftp地址
|
||||
* @return "/aria.text"
|
||||
*/
|
||||
private String getFileName(String url) {
|
||||
Uri uri = Uri.parse(url);
|
||||
String path = uri.getPath();
|
||||
int index = path.lastIndexOf("/");
|
||||
return path.substring(index);
|
||||
}
|
||||
}
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.core.download.mutil.DownloadAdapter;
|
||||
import com.arialyy.simple.databinding.ActivityHighestPriorityBinding;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/6/2.
|
||||
* 最高优先级任务Demo
|
||||
*/
|
||||
public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorityBinding> {
|
||||
private HorizontalProgressBarWithNumber mPb;
|
||||
private Button mStart;
|
||||
private Button mStop;
|
||||
private Button mCancel;
|
||||
private TextView mSize;
|
||||
private TextView mSpeed;
|
||||
private RecyclerView mList;
|
||||
private DownloadEntity mEntity;
|
||||
|
||||
private String mTaskName = "光明大陆";
|
||||
private static final String DOWNLOAD_URL =
|
||||
"https://res5.d.cn/6f78ee3bcfdd033e64892a8553a95814cf5b4a62b12a76d9eb2a694905f0dc30fa5c7f728806a4ee0b3479e7b26a38707dac92b136add91191ac1219aadb4a3aa70bfa6d06d2d8db.apk";
|
||||
private DownloadAdapter mAdapter;
|
||||
private List<AbsEntity> mData = new ArrayList<>();
|
||||
private Set<String> mRecord = new HashSet<>();
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_highest_priority;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
mPb = findViewById(R.id.progressBar);
|
||||
mStart = findViewById(R.id.start);
|
||||
mStop = findViewById(R.id.stop);
|
||||
mCancel = findViewById(R.id.cancel);
|
||||
mSize = findViewById(R.id.size);
|
||||
mSpeed = findViewById(R.id.speed);
|
||||
mList = findViewById(R.id.list);
|
||||
|
||||
setTitle("最高优先级任务");
|
||||
getBinding().setTaskName("任务名:" + mTaskName + " (最高优先级任务)");
|
||||
initWidget();
|
||||
Aria.download(this).register();
|
||||
}
|
||||
|
||||
private void initWidget() {
|
||||
mEntity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
|
||||
|
||||
if (mEntity != null) {
|
||||
mPb.setProgress(mEntity.getPercent());
|
||||
if (mEntity.getState() == IEntity.STATE_STOP) {
|
||||
mStart.setText("恢复");
|
||||
mStart.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
|
||||
setBtState(true);
|
||||
} else if (mEntity.getState() == IEntity.STATE_RUNNING) {
|
||||
setBtState(false);
|
||||
}
|
||||
mSize.setText(mEntity.getConvertFileSize());
|
||||
}
|
||||
|
||||
List<DownloadEntity> temp = Aria.download(this).getTaskList();
|
||||
if (temp != null && !temp.isEmpty()) {
|
||||
for (DownloadEntity entity : temp) {
|
||||
if (entity.getUrl().equals(DOWNLOAD_URL)) continue;
|
||||
mData.add(entity);
|
||||
mRecord.add(entity.getUrl());
|
||||
}
|
||||
}
|
||||
mAdapter = new DownloadAdapter(this, mData);
|
||||
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@Override public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_highest_priority, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.add_task:
|
||||
List<DownloadEntity> temp = getModule(DownloadModule.class).getHighestTestList();
|
||||
for (DownloadEntity entity : temp) {
|
||||
String url = entity.getUrl();
|
||||
if (mRecord.contains(url)) {
|
||||
continue;
|
||||
}
|
||||
mAdapter.addDownloadEntity(entity);
|
||||
mRecord.add(url);
|
||||
}
|
||||
mAdapter.notifyDataSetChanged();
|
||||
break;
|
||||
case R.id.help:
|
||||
String title = "最高优先级任务介绍";
|
||||
String msg = " 将任务设置为最高优先级任务,最高优先级任务有以下特点:\n"
|
||||
+ " 1、在下载队列中,有且只有一个最高优先级任务\n"
|
||||
+ " 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成\n"
|
||||
+ " 3、任务调度器不会暂停最高优先级任务\n"
|
||||
+ " 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效\n"
|
||||
+ " 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行\n"
|
||||
+ " 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务";
|
||||
showMsgDialog(title, msg);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
String text = ((TextView) view).getText().toString();
|
||||
if (text.equals("重新开始?") || text.equals("开始")) {
|
||||
} else {
|
||||
Aria.download(this).load(mEntity.getId()).resume();
|
||||
}
|
||||
}
|
||||
((TextView) view).setText(getString(R.string.stop));
|
||||
break;
|
||||
case R.id.stop:
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this).load(mEntity.getId()).stop();
|
||||
}
|
||||
((TextView) view).setText(getString(R.string.resume));
|
||||
break;
|
||||
case R.id.cancel:
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this).load(mEntity.getId()).cancel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置start 和 stop 按钮状态
|
||||
*/
|
||||
private void setBtState(boolean state) {
|
||||
mStart.setEnabled(state);
|
||||
mStop.setEnabled(!state);
|
||||
}
|
||||
|
||||
@Download.onPre public void onPre(DownloadTask task) {
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
mSize.setText(task.getConvertFileSize());
|
||||
}
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskStart public void onTaskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(false);
|
||||
}
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskResume public void onTaskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(false);
|
||||
}
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(true);
|
||||
mStart.setText("恢复");
|
||||
mStart.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
|
||||
}
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(true);
|
||||
mStart.setText("开始");
|
||||
mPb.setProgress(0);
|
||||
}
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskFail public void onTaskFail(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(true);
|
||||
} else {
|
||||
L.d(TAG, "download fail【" + task.getKey() + "】");
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete public void onTaskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(true);
|
||||
mStart.setText("重新开始");
|
||||
mStart.setTextColor(getResources().getColor(android.R.color.holo_green_light));
|
||||
mPb.setProgress(100);
|
||||
}
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
mPb.setProgress(task.getPercent());
|
||||
mSpeed.setText(task.getConvertSpeed());
|
||||
}
|
||||
mAdapter.setProgress(task.getDownloadEntity());
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class HttpDownloadModule extends BaseViewModule {
|
||||
private final String HTTP_URL_KEY = "HTTP_URL_KEY";
|
||||
private final String HTTP_PATH_KEY = "HTTP_PATH_KEY";
|
||||
|
||||
private final String defUrl =
|
||||
"http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
|
||||
//"https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
|
||||
//"http://9.9.9.205:5000/download/Cyberduck-6.9.4.30164.zip";
|
||||
//"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk";
|
||||
private final String defFilePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
+ "/update.zip";
|
||||
|
||||
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
|
||||
private DownloadEntity singDownloadInfo;
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getHttpDownloadInfo(Context context) {
|
||||
//String url = AppUtil.getConfigValue(context, HTTP_URL_KEY, defUrl);
|
||||
//String url = "http://fdfs.speedata.cn:9989/group1/M00/00/05/rBGFrl3fdAKAVJwfMtSa9R18wLU139.zip";
|
||||
//String url = "http://9.9.9.28:8088/files/update.zip";
|
||||
String url = "https://y.qq.com/download/import/QQMusic-import-1.2.1.zip";
|
||||
//String url = "https://gitee.com/huang-junhua/iptv/raw/master/guonei.m3u8";
|
||||
//String url = "http://v.kjjl100.com/kz/zx/cj/2020cjswxdb/1.mp4";
|
||||
//String url = "https://static.runoob.com/images/demo/demo2.jpg";
|
||||
String filePath = "/mnt/sdcard/qq.zip";
|
||||
|
||||
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
File file = new File(filePath);
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
singDownloadInfo.setFileName(file.getName());
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, HTTP_PATH_KEY, singDownloadInfo.getFilePath());
|
||||
AppUtil.setConfigValue(context, HTTP_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件保存路径
|
||||
*
|
||||
* @param filePath 文件保存路径
|
||||
*/
|
||||
void updateFilePath(Context context, String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
ALog.e(TAG, "文件保存路径为空");
|
||||
return;
|
||||
}
|
||||
File temp = new File(filePath);
|
||||
AppUtil.setConfigValue(context, HTTP_PATH_KEY, filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新url
|
||||
*/
|
||||
void uploadUrl(Context context, String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ALog.e(TAG, "下载地址为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, HTTP_URL_KEY, url);
|
||||
singDownloadInfo.setUrl(url);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
}
|
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.arialyy.annotations.Download
|
||||
import com.arialyy.aria.core.Aria
|
||||
import com.arialyy.aria.core.download.DownloadEntity
|
||||
import com.arialyy.aria.core.inf.IEntity
|
||||
import com.arialyy.aria.core.listener.ISchedulers
|
||||
import com.arialyy.aria.util.ALog
|
||||
import com.arialyy.aria.util.CommonUtil
|
||||
import com.arialyy.frame.util.show.T
|
||||
import com.arialyy.simple.R
|
||||
import com.arialyy.simple.R.string
|
||||
import com.arialyy.simple.base.BaseActivity
|
||||
import com.arialyy.simple.common.ModifyPathDialog
|
||||
import com.arialyy.simple.common.ModifyUrlDialog
|
||||
import com.arialyy.simple.databinding.ActivitySingleKotlinBinding
|
||||
import com.arialyy.simple.util.AppUtil
|
||||
import com.pddstudio.highlightjs.models.Language
|
||||
import java.io.IOException
|
||||
|
||||
class KotlinDownloadActivity : BaseActivity<ActivitySingleKotlinBinding>() {
|
||||
|
||||
private var mUrl: String? = null
|
||||
private var mFilePath: String? = null
|
||||
private var mModule: HttpDownloadModule? = null
|
||||
private var mTaskId: Long = -1
|
||||
|
||||
internal var receiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(
|
||||
context: Context,
|
||||
intent: Intent
|
||||
) {
|
||||
if (intent.action == ISchedulers.ARIA_TASK_INFO_ACTION) {
|
||||
ALog.d(
|
||||
TAG,
|
||||
"state = " + intent.getIntExtra(ISchedulers.TASK_STATE, -1)
|
||||
)
|
||||
ALog.d(
|
||||
TAG, "type = " + intent.getIntExtra(ISchedulers.TASK_TYPE, -1)
|
||||
)
|
||||
ALog.d(
|
||||
TAG,
|
||||
"speed = " + intent.getLongExtra(ISchedulers.TASK_SPEED, -1)
|
||||
)
|
||||
ALog.d(
|
||||
TAG, "percent = " + intent.getIntExtra(
|
||||
ISchedulers.TASK_PERCENT, -1
|
||||
)
|
||||
)
|
||||
ALog.d(
|
||||
TAG, "entity = " + intent.getParcelableExtra<DownloadEntity>(
|
||||
ISchedulers.TASK_ENTITY
|
||||
).toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
//registerReceiver(receiver, new IntentFilter(ISchedulers.ARIA_TASK_INFO_ACTION));
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
//unregisterReceiver(receiver);
|
||||
Aria.download(this)
|
||||
.unRegister()
|
||||
}
|
||||
|
||||
override fun init(savedInstanceState: Bundle?) {
|
||||
super.init(savedInstanceState)
|
||||
title = "单任务下载"
|
||||
Aria.download(this)
|
||||
.register()
|
||||
mModule = ViewModelProviders.of(this)
|
||||
.get(HttpDownloadModule::class.java)
|
||||
mModule!!.getHttpDownloadInfo(this)
|
||||
.observe(this, Observer { entity ->
|
||||
if (entity == null) {
|
||||
return@Observer
|
||||
}
|
||||
if (entity.state == IEntity.STATE_STOP) {
|
||||
binding.stateStr = getString(string.resume)
|
||||
}
|
||||
|
||||
if (Aria.download(this).load(entity.id).isRunning) {
|
||||
binding.stateStr = getString(string.stop)
|
||||
}
|
||||
|
||||
if (entity.fileSize != 0L) {
|
||||
binding.fileSize = CommonUtil.formatFileSize(entity.fileSize.toDouble())
|
||||
binding.progress = if (entity.isComplete)
|
||||
100
|
||||
else
|
||||
(entity.currentProgress * 100 / entity.fileSize).toInt()
|
||||
}
|
||||
binding.url = entity.url
|
||||
binding.filePath = entity.filePath
|
||||
mUrl = entity.url
|
||||
mFilePath = entity.filePath
|
||||
})
|
||||
binding.viewModel = this
|
||||
try {
|
||||
binding.codeView.setSource(AppUtil.getHelpCode(this, "KotlinHttpDownload.kt"), Language.JAVA)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun chooseUrl() {
|
||||
val dialog = ModifyUrlDialog(this, getString(R.string.modify_url_dialog_title), mUrl)
|
||||
dialog.show(supportFragmentManager, "ModifyUrlDialog")
|
||||
}
|
||||
|
||||
fun chooseFilePath() {
|
||||
val dialog = ModifyPathDialog(this, getString(R.string.modify_file_path), mFilePath)
|
||||
dialog.show(supportFragmentManager, "ModifyPathDialog")
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_single_task_activity, menu)
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
var speed = -1
|
||||
var msg = ""
|
||||
when (item.itemId) {
|
||||
R.id.help -> {
|
||||
msg = ("一些小知识点:\n"
|
||||
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
|
||||
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
|
||||
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据")
|
||||
showMsgDialog("tip", msg)
|
||||
}
|
||||
R.id.speed_0 -> speed = 0
|
||||
R.id.speed_128 -> speed = 128
|
||||
R.id.speed_256 -> speed = 256
|
||||
R.id.speed_512 -> speed = 512
|
||||
R.id.speed_1m -> speed = 1024
|
||||
}
|
||||
if (speed > -1) {
|
||||
msg = item.title.toString()
|
||||
Aria.download(this)
|
||||
.setMaxSpeed(speed)
|
||||
T.showShort(this, msg)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
fun onWait(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
Log.d(TAG, "wait ==> " + task.downloadEntity.fileName)
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
fun onPre(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
binding.stateStr = getString(R.string.stop)
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
fun taskStart(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
binding.fileSize = task.convertFileSize
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
fun running(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
//Log.d(TAG, task.getKey());
|
||||
val len = task.fileSize
|
||||
if (len == 0L) {
|
||||
binding.progress = 0
|
||||
} else {
|
||||
binding.progress = task.percent
|
||||
}
|
||||
binding.speed = task.convertSpeed
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
fun taskResume(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
binding.stateStr = getString(R.string.stop)
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
fun taskStop(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
binding.stateStr = getString(R.string.resume)
|
||||
binding.speed = ""
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
fun taskCancel(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
if (task.key == mUrl) {
|
||||
binding.progress = 0
|
||||
binding.stateStr = getString(R.string.start)
|
||||
binding.speed = ""
|
||||
Log.d(TAG, "cancel")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Download.onTaskFail
|
||||
fun taskFail(
|
||||
task: com.arialyy.aria.core.task.DownloadTask,
|
||||
e: Exception
|
||||
) {
|
||||
if (task.key == mUrl) {
|
||||
Toast.makeText(this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
binding.stateStr = getString(R.string.start)
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
fun taskComplete(task: com.arialyy.aria.core.task.DownloadTask) {
|
||||
|
||||
if (task.key == mUrl) {
|
||||
binding.progress = 100
|
||||
Toast.makeText(
|
||||
this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
binding.stateStr = getString(R.string.re_start)
|
||||
binding.speed = ""
|
||||
}
|
||||
}
|
||||
|
||||
override fun setLayoutId(): Int {
|
||||
return R.layout.activity_single_kotlin
|
||||
}
|
||||
|
||||
fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.start -> if (Aria.download(this).load(mTaskId).isRunning) {
|
||||
Aria.download(this)
|
||||
.load(mTaskId)
|
||||
.stop()
|
||||
} else {
|
||||
startD()
|
||||
}
|
||||
R.id.stop -> Aria.download(this).load(mTaskId).stop()
|
||||
R.id.cancel -> Aria.download(this).load(mTaskId).cancel(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startD() {
|
||||
if (mTaskId == -1L) {
|
||||
|
||||
mTaskId = Aria.download(this)
|
||||
.load(mUrl!!)
|
||||
//.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
|
||||
//.addHeader("Accept-Encoding", "gzip, deflate")
|
||||
//.addHeader("DNT", "1")
|
||||
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
|
||||
.setFilePath(mFilePath!!, true)
|
||||
.create()
|
||||
} else {
|
||||
Aria.download(this)
|
||||
.load(mTaskId)
|
||||
.resume()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
//Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
override fun dataCallback(
|
||||
result: Int,
|
||||
data: Any
|
||||
) {
|
||||
super.dataCallback(result, data)
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
mModule!!.uploadUrl(this, data.toString())
|
||||
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
|
||||
mModule!!.updateFilePath(this, data.toString())
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.SFtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.common.DirChooseDialog;
|
||||
import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/25.
|
||||
* Ftp下载
|
||||
*/
|
||||
public class SFtpDownloadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
private String mUrl, mFilePath;
|
||||
private FtpDownloadModule mModule;
|
||||
private long mTaskId;
|
||||
private String user = "tester", passw = "password";
|
||||
private String prvKeyPath;
|
||||
private String pubKeyPath;
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle("FTP文件下载");
|
||||
Aria.download(this).register();
|
||||
prvKeyPath = getFilesDir().getPath() + "/id_rsa";
|
||||
pubKeyPath = getFilesDir().getPath() + "/id_rsa.pub";
|
||||
copyKey();
|
||||
mModule = ViewModelProviders.of(this).get(FtpDownloadModule.class);
|
||||
mModule.getSftpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTaskId = entity.getId();
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
getBinding().pl.setInfo(entity);
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.download(this).loadFtp(mUrl)
|
||||
.setFilePath(mFilePath)
|
||||
.ignoreFilePathOccupy()
|
||||
.sftpOption(getFtpOption())
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadFtp(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.loadFtp(mTaskId)
|
||||
.sftpOption(getFtpOption())
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadFtp(mTaskId).cancel(true);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void copyKey() {
|
||||
try {
|
||||
// 为了测试方便,每次重新覆盖证书文件
|
||||
File prvKey = new File(prvKeyPath);
|
||||
//FileUtil.deleteFile(prvKey);
|
||||
if (!prvKey.exists()) {
|
||||
FileUtil.createFileFormInputStream(getAssets().open("id_rsa"), prvKeyPath);
|
||||
}
|
||||
File pubKey = new File(pubKeyPath);
|
||||
//FileUtil.deleteFile(pubKey);
|
||||
if (!pubKey.exists()) {
|
||||
FileUtil.createFileFormInputStream(getAssets().open("id_rsa.pub"), pubKeyPath);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private SFtpOption getFtpOption() {
|
||||
SFtpOption option = new SFtpOption();
|
||||
option.login(user, passw); // 账号密码登录
|
||||
// 证书登录
|
||||
option.setPrvKey(prvKeyPath); // 设置私钥
|
||||
option.setPrvKeyPass("123456"); // 设置私钥密码(如果没有密码,可以不设置)
|
||||
option.setPubKey(pubKeyPath); // 设置公钥
|
||||
option.setKnowHostPath(getFilesDir().getPath() + "/know_hosts");
|
||||
|
||||
//option.setServerIdentifier(FtpOption.FTPServerIdentifier.SYST_NT);
|
||||
//option.setConnectionMode(FtpConnectionMode.DATA_CONNECTION_MODE_ACTIVITY);
|
||||
return option;
|
||||
}
|
||||
|
||||
public void chooseUrl() {
|
||||
ModifyUrlDialog dialog =
|
||||
new ModifyUrlDialog(this, getString(R.string.modify_url_dialog_title), mUrl);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyUrlDialog");
|
||||
}
|
||||
|
||||
public void chooseFilePath() {
|
||||
DirChooseDialog dirChooseDialog = new DirChooseDialog(this);
|
||||
dirChooseDialog.show(getSupportFragmentManager(), "DirChooseDialog");
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
void taskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
void taskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
mTaskId = -1;
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
ALog.d(TAG, "下载失败");
|
||||
Toast.makeText(this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
if (task != null && task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_single;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
mModule.uploadUrl(this, String.valueOf(data));
|
||||
} else if (result == DirChooseDialog.DIR_CHOOSE_DIALOG_RESULT) {
|
||||
mModule.updateFilePath(this, String.valueOf(data));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
///*
|
||||
// * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
// *
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// */
|
||||
//
|
||||
//package com.arialyy.simple.core.download;
|
||||
//
|
||||
//import android.app.NotificationManager;
|
||||
//import android.content.Context;
|
||||
//import android.os.Environment;
|
||||
//import android.support.v4.app.NotificationCompat;
|
||||
//import com.arialyy.annotations.Download;
|
||||
//import com.arialyy.aria.core.Aria;
|
||||
//import com.arialyy.aria.core.task.DownloadTask;
|
||||
//import com.arialyy.simple.R;
|
||||
//
|
||||
///**
|
||||
// * Created by lyy on 2017/1/18.
|
||||
// */
|
||||
//
|
||||
//public class SimpleNotification {
|
||||
// private static final String DOWNLOAD_URL =
|
||||
// "http://static.gaoshouyou.com/d/cb/38/f0cb1b2c57388fe14342eecd64bbae65.apk";
|
||||
//
|
||||
// private NotificationManager mManager;
|
||||
// private Context mContext;
|
||||
// private NotificationCompat.Builder mBuilder;
|
||||
// private static final int mNotifiyId = 0;
|
||||
//
|
||||
// public SimpleNotification(Context context) {
|
||||
// mContext = context;
|
||||
// init();
|
||||
// }
|
||||
//
|
||||
// private void init() {
|
||||
// mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
// mBuilder = new NotificationCompat.Builder(mContext);
|
||||
// mBuilder.setContentTitle("Aria Download Test")
|
||||
// .setContentText("进度条")
|
||||
// .setProgress(100, 0, false)
|
||||
// .setSmallIcon(R.mipmap.ic_launcher);
|
||||
// mManager.notify(mNotifiyId, mBuilder.build());
|
||||
// Aria.download(this).register();
|
||||
// }
|
||||
//
|
||||
// public void create() {
|
||||
// Aria.download(this)
|
||||
// .load(DOWNLOAD_URL)
|
||||
// .setFilePath(Environment.getExternalStorageDirectory() + "/Download/消灭星星.apk")
|
||||
// .create();
|
||||
// }
|
||||
//
|
||||
// public void stop() {
|
||||
// Aria.download(this).load(DOWNLOAD_URL).stop();
|
||||
// }
|
||||
//
|
||||
// public void destory() {
|
||||
// Aria.download(this).unRegister();
|
||||
// }
|
||||
//
|
||||
// @Download.onTaskStart public void onTaskStart(DownloadTask task) {
|
||||
// }
|
||||
//
|
||||
// @Download.onTaskPre public void onTaskPre(DownloadTask task) {
|
||||
// }
|
||||
//
|
||||
// @Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
// }
|
||||
//
|
||||
// @Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
// long len = task.getFileSize();
|
||||
// int p = (int) (task.getCurrentProgress() * 100 / len);
|
||||
// if (mBuilder != null) {
|
||||
// mBuilder.setProgress(100, p, false);
|
||||
// mManager.notify(mNotifiyId, mBuilder.build());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Download.onTaskComplete public void onTaskComplete(DownloadTask task) {
|
||||
// if (mBuilder != null) {
|
||||
// mBuilder.setProgress(100, 100, false);
|
||||
// mManager.notify(mNotifiyId, mBuilder.build());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
// }
|
||||
//}
|
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadTaskListener;
|
||||
import com.arialyy.aria.core.download.target.HttpNormalTarget;
|
||||
import com.arialyy.aria.core.listener.ISchedulers;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.scheduler.NormalTaskListenerInterface;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
private String mUrl;
|
||||
private String mFilePath;
|
||||
private HttpDownloadModule mModule;
|
||||
private long mTaskId = -1;
|
||||
|
||||
BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(ISchedulers.ARIA_TASK_INFO_ACTION)) {
|
||||
ALog.d(TAG, "state = " + intent.getIntExtra(ISchedulers.TASK_STATE, -1));
|
||||
ALog.d(TAG, "type = " + intent.getIntExtra(ISchedulers.TASK_TYPE, -1));
|
||||
ALog.d(TAG, "speed = " + intent.getLongExtra(ISchedulers.TASK_SPEED, -1));
|
||||
ALog.d(TAG, "percent = " + intent.getIntExtra(ISchedulers.TASK_PERCENT, -1));
|
||||
ALog.d(TAG, "entity = " + intent.getParcelableExtra(ISchedulers.TASK_ENTITY).toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
//registerReceiver(receiver, new IntentFilter(ISchedulers.ARIA_TASK_INFO_ACTION));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
//unregisterReceiver(receiver);
|
||||
Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle("单任务下载");
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(HttpDownloadModule.class);
|
||||
mModule.getHttpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTaskId = entity.getId();
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
getBinding().pl.setInfo(entity);
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
startD();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.load(mTaskId)
|
||||
.stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId)
|
||||
//.updateUrl(mUrl)
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).cancel(false);
|
||||
// //1. 删除本地文件目录
|
||||
// File localDirFile = new File(mFilePath);
|
||||
// if (localDirFile.exists()) {
|
||||
// FileUtil.deleteDir(localDirFile.getParentFile());
|
||||
// }
|
||||
//
|
||||
// //2. 删除记录
|
||||
// HttpNormalTarget target = Aria.download(SingleTaskActivity.this).load(mTaskId);
|
||||
// if (target != null) {
|
||||
// // target.cancel();
|
||||
// target.removeRecord();
|
||||
// }
|
||||
//
|
||||
// List<DownloadEntity> notCompleteTask = Aria.download(SingleTaskActivity.this).getAllNotCompleteTask();
|
||||
// if (notCompleteTask == null){
|
||||
// Log.d(TAG, "未完成的任务数:0");
|
||||
// return;
|
||||
// }
|
||||
// Log.d(TAG, "未完成的任务数:" + notCompleteTask.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int speed = -1;
|
||||
String msg = "";
|
||||
switch (item.getItemId()) {
|
||||
case R.id.help:
|
||||
msg = "一些小知识点:\n"
|
||||
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
|
||||
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
|
||||
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据";
|
||||
showMsgDialog("tip", msg);
|
||||
break;
|
||||
case R.id.speed_0:
|
||||
speed = 0;
|
||||
break;
|
||||
case R.id.speed_128:
|
||||
speed = 128;
|
||||
break;
|
||||
case R.id.speed_256:
|
||||
speed = 256;
|
||||
break;
|
||||
case R.id.speed_512:
|
||||
speed = 512;
|
||||
break;
|
||||
case R.id.speed_1m:
|
||||
speed = 1024;
|
||||
break;
|
||||
}
|
||||
if (speed > -1) {
|
||||
msg = item.getTitle().toString();
|
||||
T.showShort(this, msg);
|
||||
Aria.get(this).getDownloadConfig().setMaxSpeed(speed);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
public void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
public void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
//@Override public void onTaskPre(DownloadTask task) {
|
||||
//
|
||||
//}
|
||||
|
||||
@Download.onTaskStart
|
||||
public void onTaskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
public void onTaskRunning(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
//ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
//@Override public void onNoSupportBreakPoint(DownloadTask task) {
|
||||
//
|
||||
//}
|
||||
|
||||
@Download.onTaskResume
|
||||
public void onTaskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
public void onTaskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
public void onTaskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
mTaskId = -1;
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
public void onTaskFail(DownloadTask task, Exception e) {
|
||||
ALog.d(TAG, "下载失败");
|
||||
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
if (task != null && task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
public void onTaskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "文件md5: e088677570afe2e9f847cc8159b932dd");
|
||||
ALog.d(TAG, "下载完成的文件md5: " + CommonUtil.getFileMD5(new File(task.getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
getBinding().pl.setProgress(100);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_single;
|
||||
}
|
||||
|
||||
private void startD() {
|
||||
HttpOption option = new HttpOption();
|
||||
option.useServerFileName(true);
|
||||
option.addHeader("1", "@")
|
||||
.useServerFileName(true)
|
||||
.setFileLenAdapter(new FileLenAdapter());
|
||||
//option.setRequestType(RequestEnum.POST);
|
||||
mTaskId = Aria.download(SingleTaskActivity.this)
|
||||
.load(mUrl)
|
||||
.setFilePath(mFilePath, true)
|
||||
.option(option)
|
||||
.ignoreCheckPermissions()
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
//Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
@Override public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
static class FileLenAdapter implements IHttpFileLenAdapter {
|
||||
@Override public long handleFileLen(Map<String, List<String>> headers) {
|
||||
|
||||
List<String> sLength = headers.get("Content-Length");
|
||||
if (sLength == null || sLength.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
String temp = sLength.get(0);
|
||||
|
||||
return Long.parseLong(temp);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.frame.core.AbsFragment;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.databinding.FragmentDownloadBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/1/4.
|
||||
*/
|
||||
public class DownloadFragment extends AbsFragment<FragmentDownloadBinding> {
|
||||
private long mTaskId = -1;
|
||||
|
||||
private static final String DOWNLOAD_URL =
|
||||
"https://res5.d.cn/2137e42d610b3488d9420c6421529386eee5bdbfd9be1fafe0a05d6dabaec8c156ddbd00581055bbaeac03904fb63310e80010680235d16bd4c040b50096a0c20dd1c4b0854529a1.apk";
|
||||
private static final String FILE_NAME = "王者军团";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
Aria.download(this).register();
|
||||
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
|
||||
if (entity == null){
|
||||
entity = new DownloadEntity();
|
||||
entity.setUrl(DOWNLOAD_URL);
|
||||
}
|
||||
getBinding().pl.setInfo(entity);
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setFilePath(
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
.getPath() + String.format("/%s.apk",
|
||||
FILE_NAME))
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.load(mTaskId)
|
||||
.stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId)
|
||||
//.updateUrl(mUrl)
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).cancel(false);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
long len = task.getFileSize();
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Override protected void onDelayLoad() {
|
||||
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.fragment_download;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object obj) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.simple.MainActivity;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.FragmentDownloadBinding;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/1/4.
|
||||
*/
|
||||
|
||||
public class FragmentActivity extends BaseActivity<FragmentDownloadBinding> {
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_fragment;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
|
||||
final NormalTo to = getIntent().getParcelableExtra(MainActivity.KEY_MAIN_DATA);
|
||||
setTitle(to.title);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.arialyy.simple.core.download.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentPagerAdapter
|
||||
import com.arialyy.simple.R
|
||||
import com.arialyy.simple.base.BaseActivity
|
||||
import com.arialyy.simple.databinding.ActivityMultiFragmentActivityBinding
|
||||
|
||||
class MultiFragmentActivity : BaseActivity<ActivityMultiFragmentActivityBinding>() {
|
||||
|
||||
private val urls = arrayListOf(
|
||||
"http://cpsdown.muzhiwan.com/2020/07/23/com.suyou.xjhx.syad_5f195b471dff6.apk",
|
||||
"http://60.174.135.183:88/sdkdown.muzhiwan.com/2020/01/13/com.supercell.clashroyale.ewan.mzw_5e1bc4eb4313e.apk",
|
||||
"http://60.174.135.183:88/sdkdown.muzhiwan.com/openfile/2020/08/06/com.maoer.m282_5f2b79232a8b1.apk"
|
||||
)
|
||||
private val names = arrayListOf(
|
||||
"星界幻想",
|
||||
"皇室战争",
|
||||
"无双帝国"
|
||||
)
|
||||
|
||||
override fun setLayoutId(): Int {
|
||||
return R.layout.activity_multi_fragment_activity
|
||||
}
|
||||
|
||||
override fun init(savedInstanceState: Bundle?) {
|
||||
super.init(savedInstanceState)
|
||||
val fragmentList = arrayListOf<MultiItemFragment>()
|
||||
urls.forEachIndexed { index, url ->
|
||||
fragmentList.add(MultiItemFragment(url, names[index]))
|
||||
}
|
||||
binding.vpPage.adapter = PGAdapter(fragmentList, supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
|
||||
binding.tabLayout.setupWithViewPager(binding.vpPage)
|
||||
binding.tabLayout.getTabAt(0)!!.text = "fm1"
|
||||
binding.tabLayout.getTabAt(1)!!.text = "fm2"
|
||||
binding.tabLayout.getTabAt(2)!!.text = "fm3"
|
||||
}
|
||||
|
||||
private class PGAdapter(
|
||||
val fragments: List<MultiItemFragment>,
|
||||
fm: FragmentManager,
|
||||
state: Int
|
||||
) : FragmentPagerAdapter(fm, state) {
|
||||
override fun getItem(position: Int): Fragment {
|
||||
return fragments[position]
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return fragments.size
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.frame.core.AbsFragment;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.databinding.FragmentDownloadBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/1/4.
|
||||
*/
|
||||
public class MultiItemFragment extends AbsFragment<FragmentDownloadBinding> {
|
||||
private long mTaskId = -1;
|
||||
|
||||
private String DOWNLOAD_URL;
|
||||
private String FILE_NAME;
|
||||
|
||||
public MultiItemFragment(String url, String fileName) {
|
||||
DOWNLOAD_URL = url;
|
||||
FILE_NAME = fileName;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
Aria.download(this).register();
|
||||
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
|
||||
if (entity == null) {
|
||||
entity = new DownloadEntity();
|
||||
entity.setUrl(DOWNLOAD_URL);
|
||||
}
|
||||
getBinding().pl.setInfo(entity);
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setFilePath(
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
.getPath() + String.format("/%s.apk",
|
||||
FILE_NAME))
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.load(mTaskId)
|
||||
.stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId)
|
||||
//.updateUrl(mUrl)
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).cancel(false);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
|
||||
if (!task.getKey().equals(DOWNLOAD_URL)){
|
||||
return;
|
||||
}
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
if (!task.getKey().equals(DOWNLOAD_URL)){
|
||||
return;
|
||||
}
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
if (!task.getKey().equals(DOWNLOAD_URL)){
|
||||
return;
|
||||
}
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
if (!task.getKey().equals(DOWNLOAD_URL)){
|
||||
return;
|
||||
}
|
||||
long len = task.getFileSize();
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Override protected void onDelayLoad() {
|
||||
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.fragment_download;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object obj) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.group;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
import com.arialyy.annotations.DownloadGroup;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogSubTaskHandlerBinding;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/9/5.
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class ChildHandleDialog
|
||||
extends BaseDialog<DialogSubTaskHandlerBinding> implements View.OnClickListener {
|
||||
TextView mSub;
|
||||
TextView mGroup;
|
||||
HorizontalProgressBarWithNumber mPb;
|
||||
private String mGroupHash;
|
||||
private String mChildName;
|
||||
private List<String> mUrls;
|
||||
private DownloadEntity mChildEntity;
|
||||
|
||||
public ChildHandleDialog(Context context, List<String> urls, DownloadEntity childEntity) {
|
||||
super(context);
|
||||
setStyle(STYLE_NO_TITLE, R.style.Theme_Light_Dialog);
|
||||
mChildEntity = childEntity;
|
||||
mGroupHash = "任务组测试";
|
||||
mUrls = urls;
|
||||
mChildName = childEntity.getFileName();
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.download(getContext()).register();
|
||||
initWidget();
|
||||
}
|
||||
|
||||
@Override public void onDestroy() {
|
||||
super.onDestroy();
|
||||
Aria.download(getContext()).unRegister();
|
||||
}
|
||||
|
||||
private void initWidget() {
|
||||
mSub = findViewById(R.id.sub_task);
|
||||
mGroup = findViewById(R.id.task_group);
|
||||
mPb = findViewById(R.id.pb);
|
||||
|
||||
findViewById(R.id.stop).setOnClickListener(this);
|
||||
findViewById(R.id.start).setOnClickListener(this);
|
||||
//findViewById(R.id.cancel).setOnClickListener(this);
|
||||
mGroup.setText("任务组:" + mGroupHash);
|
||||
mSub.setText("子任务:" + mChildName);
|
||||
mPb.setProgress((int) (mChildEntity.getCurrentProgress() * 100 / mChildEntity.getFileSize()));
|
||||
|
||||
Window window = getDialog().getWindow();
|
||||
window.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
|
||||
WindowManager.LayoutParams p = window.getAttributes();
|
||||
p.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
window.setAttributes(p);
|
||||
window.setWindowAnimations(R.style.dialogStyle);
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskRunning void onSubTaskRunning(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return;
|
||||
mPb.setProgress(subEntity.getPercent());
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskPre void onSubTaskPre(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return;
|
||||
L.d(TAG, subEntity.getPercent() + "");
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskStop void onSubTaskStop(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return;
|
||||
mSub.setText("子任务:" + mChildName + ",状态:任务停止");
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskStart void onSubTaskStart(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return;
|
||||
mSub.setText("子任务:" + mChildName + ",状态:下载中");
|
||||
}
|
||||
|
||||
//@DownloadGroup.onSubTaskCancel void onSubTaskCancel(DownloadGroupTask groupTask,
|
||||
// DownloadEntity subEntity) {
|
||||
// Log.d(TAG, "new Size: " + groupTask.getConvertFileSize());
|
||||
// mSub.setText("子任务:" + mChildName + ",状态:取消下载");
|
||||
//}
|
||||
|
||||
@DownloadGroup.onSubTaskComplete void onSubTaskComplete(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return;
|
||||
mSub.setText("子任务:" + mChildName + ",状态:任务完成");
|
||||
mPb.setProgress(100);
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskFail void onSubTaskFail(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return;
|
||||
L.d(TAG, subEntity.getPercent() + "");
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_sub_task_handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
Aria.download(getContext())
|
||||
.loadGroup(mUrls)
|
||||
.getSubTaskManager()
|
||||
.startSubTask(mChildEntity.getUrl());
|
||||
break;
|
||||
case R.id.stop:
|
||||
Aria.download(getContext())
|
||||
.loadGroup(mUrls)
|
||||
.getSubTaskManager()
|
||||
.stopSubTask(mChildEntity.getUrl());
|
||||
break;
|
||||
//case R.id.cancel:
|
||||
// Aria.download(this).load(mUrls).getSubTaskManager().cancelSubTask(mChildEntity.getUrl());
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object obj) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.group;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.DownloadGroup;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityDownloadGroupBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import com.arialyy.simple.widget.SubStateLinearLayout;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/6.
|
||||
*/
|
||||
public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBinding> {
|
||||
|
||||
private SubStateLinearLayout mChildList;
|
||||
private List<String> mUrls;
|
||||
private long mTaskId = -1;
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.download(this).register();
|
||||
setTitle("任务组");
|
||||
|
||||
mChildList = getBinding().childList;
|
||||
mUrls = getModule(GroupModule.class).getUrls();
|
||||
DownloadGroupEntity entity = Aria.download(this).getGroupEntity(mUrls);
|
||||
if (entity != null) {
|
||||
mTaskId = entity.getId();
|
||||
mChildList.addData(entity.getSubEntities());
|
||||
ALog.d(TAG,
|
||||
"size = " + entity.getSubEntities().size() + "; len = " + entity.getConvertFileSize());
|
||||
}else {
|
||||
entity = new DownloadGroupEntity();
|
||||
}
|
||||
getBinding().pl.setInfo(entity);
|
||||
|
||||
mChildList.setOnItemClickListener(new SubStateLinearLayout.OnItemClickListener() {
|
||||
@Override public void onItemClick(int position, View view) {
|
||||
showPopupWindow(position);
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.download(this)
|
||||
.loadGroup(mUrls)
|
||||
.setDirPath(
|
||||
Environment.getExternalStorageDirectory().getPath() + "/Download/group_imgs1")
|
||||
//.setSubFileName(getModule(GroupModule.class).getSubName2())
|
||||
.setSubFileName(getModule(GroupModule.class).getSubName())
|
||||
.unknownSize()
|
||||
.option(getHttpOption())
|
||||
.ignoreFilePathOccupy()
|
||||
//.setFileSize(114981416)
|
||||
//.updateUrls(temp)
|
||||
.create();
|
||||
Log.d(TAG, "taskId = " + mTaskId);
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadGroup(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadGroup(mTaskId)
|
||||
.unknownSize()
|
||||
.resume(true);
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadGroup(mTaskId).cancel(true);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showPopupWindow(int position) {
|
||||
ChildHandleDialog dialog =
|
||||
new ChildHandleDialog(this, mUrls, mChildList.getSubData().get(position));
|
||||
dialog.show(getSupportFragmentManager(), "sub_dialog");
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_download_group;
|
||||
}
|
||||
|
||||
private HttpOption getHttpOption() {
|
||||
HttpOption option = new HttpOption();
|
||||
option.setFileLenAdapter(new HttpFileLenAdapter());
|
||||
return option;
|
||||
}
|
||||
|
||||
@DownloadGroup.onWait void taskWait(DownloadGroupTask task) {
|
||||
ALog.d(TAG, task.getTaskName() + "wait");
|
||||
}
|
||||
|
||||
@DownloadGroup.onPre() protected void onPre(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group pre, p = " + task.getPercent());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskPre() protected void onTaskPre(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group task pre, p = " + task.getPercent());
|
||||
if (mChildList.getSubData().size() <= 0) {
|
||||
mChildList.addData(task.getEntity().getSubEntities());
|
||||
}
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStart() void taskStart(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group task create, p = " + task.getPercent());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group running, p = "
|
||||
+ task.getPercent()
|
||||
+ ", speed = "
|
||||
+ task.getConvertSpeed()
|
||||
+ ", current_p = "
|
||||
+ task.getCurrentProgress());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
//Log.d(TAG, "sub_len = " + task.getEntity().getSubEntities().size());
|
||||
mChildList.updateChildProgress(task.getEntity().getSubEntities());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskResume() void taskResume(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group task resume, p = " + task.getPercent());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group task stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group task cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskFail() void taskFail(DownloadGroupTask task) {
|
||||
if (task != null){
|
||||
|
||||
ALog.d(TAG, "group task fail");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskComplete() void taskComplete(DownloadGroupTask task) {
|
||||
mChildList.updateChildProgress(task.getEntity().getSubEntities());
|
||||
T.showShort(this, "任务组下载完成");
|
||||
ALog.d(TAG, "任务组下载完成");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskRunning void onSubTaskRunning(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
//Log.e(TAG, "gHash = "
|
||||
// + groupTask.getEntity().getSubEntities().get(0).hashCode()
|
||||
// + "; subHash = "
|
||||
// + groupTask.getNormalTaskWrapper().getSubTaskEntities().get(0).getEntity().hashCode() +
|
||||
// "; subHash = " + subEntity.hashCode());
|
||||
//int percent = subEntity.getPercent();
|
||||
////如果你打开了速度单位转换配置,将可以通过以下方法获取带单位的下载速度,如:1 mb/s
|
||||
//String convertSpeed = subEntity.getConvertSpeed();
|
||||
////当前下载完成的进度,长度bytes
|
||||
//long completedSize = subEntity.getCurrentProgress();
|
||||
//Log.d(TAG, "subTask名字:"
|
||||
// + subEntity.getFileName()
|
||||
// + ", "
|
||||
// + " speed:"
|
||||
// + convertSpeed
|
||||
// + ",percent: "
|
||||
// + percent
|
||||
// + "%, completedSize:"
|
||||
// + completedSize);
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskPre void onSubTaskPre(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskStop void onSubTaskStop(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskStart void onSubTaskStart(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
}
|
||||
|
||||
//@DownloadGroup.onSubTaskCancel void onSubTaskCancel(DownloadGroupTask groupTask,
|
||||
// DownloadEntity subEntity) {
|
||||
// Log.d(TAG, "new Size: " + groupTask.getConvertFileSize());
|
||||
// mSub.setText("子任务:" + mChildName + ",状态:取消下载");
|
||||
//}
|
||||
|
||||
@DownloadGroup.onSubTaskComplete void onSubTaskComplete(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
mChildList.updateChildState(subEntity);
|
||||
}
|
||||
|
||||
@DownloadGroup.onSubTaskFail void onSubTaskFail(DownloadGroupTask groupTask,
|
||||
DownloadEntity subEntity) {
|
||||
}
|
||||
|
||||
static class HttpFileLenAdapter implements IHttpFileLenAdapter {
|
||||
@Override public long handleFileLen(Map<String, List<String>> headers) {
|
||||
|
||||
List<String> sLength = headers.get("Content-Length");
|
||||
if (sLength == null || sLength.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
String temp = sLength.get(0);
|
||||
|
||||
return Long.parseLong(temp);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.group;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.DownloadGroup;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityDownloadGroupBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import com.arialyy.simple.widget.SubStateLinearLayout;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/6.
|
||||
*/
|
||||
public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBinding> {
|
||||
private static final String dir = "ftp://192.168.0.104:2121/aab/你好";
|
||||
|
||||
private SubStateLinearLayout mChildList;
|
||||
private long mTaskId = -1;
|
||||
private String user = "lao", pwd = "123456";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.download(this).register();
|
||||
setTitle("FTP文件夹下载");
|
||||
mChildList = findViewById(R.id.child_list);
|
||||
DownloadGroupEntity entity = Aria.download(this).getFtpDirEntity(dir);
|
||||
if (entity != null) {
|
||||
mTaskId = entity.getId();
|
||||
mChildList.addData(entity.getSubEntities());
|
||||
}else {
|
||||
entity = new DownloadGroupEntity();
|
||||
}
|
||||
getBinding().pl.setInfo(entity);
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.download(this)
|
||||
.loadFtpDir(dir)
|
||||
.setDirPath(
|
||||
Environment.getExternalStorageDirectory().getPath() + "/Download/ftp_dir")
|
||||
.setGroupAlias("ftp文件夹下载")
|
||||
.option(getFtpOption())
|
||||
.ignoreFilePathOccupy()
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadFtpDir(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.loadFtpDir(mTaskId)
|
||||
.option(getFtpOption())
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).loadFtpDir(mTaskId).cancel();
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_download_group;
|
||||
}
|
||||
|
||||
private FtpOption getFtpOption() {
|
||||
FtpOption option = new FtpOption();
|
||||
option.login(user, pwd);
|
||||
return option;
|
||||
}
|
||||
|
||||
@DownloadGroup.onPre protected void onPre(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir pre");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskPre protected void onTaskPre(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir task pre");
|
||||
if (mChildList.getSubData().size() <= 0) {
|
||||
mChildList.addData(task.getEntity().getSubEntities());
|
||||
}
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStart void taskStart(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir start");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskRunning protected void running(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir running, p = " + task.getPercent());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
mChildList.updateChildProgress(task.getEntity().getSubEntities());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskResume void taskResume(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir resume");
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStop void taskStop(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskCancel void taskCancel(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "ftp dir cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskFail void taskFail(DownloadGroupTask task) {
|
||||
ALog.d(TAG, "group task fail");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskComplete void taskComplete(DownloadGroupTask task) {
|
||||
mChildList.updateChildProgress(task.getEntity().getSubEntities());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
T.showShort(this, "任务组下载完成");
|
||||
ALog.d(TAG, "任务组下载完成");
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.group;
|
||||
|
||||
import android.content.Context;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseModule;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/6.
|
||||
*/
|
||||
public class GroupModule extends BaseModule {
|
||||
public GroupModule(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public List<String> getUrls() {
|
||||
List<String> urls = new ArrayList<>();
|
||||
urls.add("http://storage.jd.com/apk/newchannel/jingdongdaojia-lechuang30.apk");
|
||||
urls.add("https://appdownload.alicdn.com/publish/cainiao4android/latest/cainiao4android_1598322688221.apk");
|
||||
urls.add("https://yanxuan-dl.nosdn.127.net/yan/android/yanxuan-aos_out_3547.apk");
|
||||
return urls;
|
||||
}
|
||||
List<String> getUrls1() {
|
||||
List<String> urls = new ArrayList<>();
|
||||
//String[] str = getContext().getResources().getStringArray(R.array.group_urls);
|
||||
//Collections.addAll(urls, str);
|
||||
urls.add(
|
||||
"https://d.pcs.baidu.com/file/130335545f3f4d9cc38afe709c19af5a?fid=1411168371-250528-1010657263806840&dstime=1531134607&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-sNCujT7lC42aMcfiHcgqAzYHuw4%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4401967667009194668&dp-callid=0&r=540192514");
|
||||
return urls;
|
||||
}
|
||||
|
||||
List<String> getSubName() {
|
||||
List<String> names = new ArrayList<>();
|
||||
//String[] str = getContext().getResources().getStringArray(R.array.group_names);
|
||||
//Collections.addAll(names, str);
|
||||
names.add("京东到家.apk");
|
||||
names.add("菜鸟.apk");
|
||||
names.add("网易严选.apk");
|
||||
//names.add("4.png");
|
||||
//names.add("5.png");
|
||||
return names;
|
||||
}
|
||||
|
||||
List<String> getSubName1() {
|
||||
List<String> names = new ArrayList<>();
|
||||
String[] str = getContext().getResources().getStringArray(R.array.group_names);
|
||||
Collections.addAll(names, str);
|
||||
return names;
|
||||
}
|
||||
|
||||
List<String> getSubName2() {
|
||||
List<String> taskSubFile;
|
||||
taskSubFile = new ArrayList<>();
|
||||
//taskSubFile.add("2156.mp4");
|
||||
// taskSubFile.add("2115.mp4");
|
||||
//taskSubFile.add("2009.mp4");
|
||||
//taskSubFile.add("1893.mp4");
|
||||
taskSubFile.add("1952.mp4");
|
||||
taskSubFile.add("1958.mp4");
|
||||
taskSubFile.add("1994.mp4");
|
||||
//taskSubFile.add("2083.mp4");
|
||||
taskSubFile.add("2305.JPG");
|
||||
taskSubFile.add("2183.JPG");
|
||||
taskSubFile.add("2154.JPG");
|
||||
taskSubFile.add("2153.JPG");
|
||||
taskSubFile.add("2152.JPG");
|
||||
taskSubFile.add("2151.JPG");
|
||||
taskSubFile.add("2149.JPG");
|
||||
taskSubFile.add("2148.JPG");
|
||||
taskSubFile.add("2147.JPG");
|
||||
taskSubFile.add("2146.JPG");
|
||||
taskSubFile.add("1949.JPG");
|
||||
taskSubFile.add("1887.JPG");
|
||||
taskSubFile.add("1996.txt");
|
||||
return taskSubFile;
|
||||
}
|
||||
|
||||
public List<String> getUrls2() {
|
||||
List<String> downLoadUrls;
|
||||
downLoadUrls = new ArrayList<>();
|
||||
//downLoadUrls.add(
|
||||
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2156&clientId=A000011106034058176");
|
||||
// downLoadUrls.add("http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2115&clientId=A000011106034058176");
|
||||
//downLoadUrls.add(
|
||||
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2009&clientId=A000011106034058176");
|
||||
//downLoadUrls.add(
|
||||
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1893&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1952&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1958&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176");
|
||||
//downLoadUrls.add(
|
||||
// "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2083&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2305&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2183&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2154&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2153&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2152&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2151&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2149&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2148&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2147&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=2146&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1949&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1887&clientId=A000011106034058176");
|
||||
downLoadUrls.add(
|
||||
"http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1996&clientId=A000011106034058176");
|
||||
return downLoadUrls;
|
||||
}
|
||||
}
|
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.annotations.M3U8;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.m3u8.M3U8LiveOption;
|
||||
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ILiveTsUrlConverter;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.common.ModifyPathDialog;
|
||||
import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivityM3u8LiveBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding> {
|
||||
|
||||
private String mUrl;
|
||||
private String mFilePath;
|
||||
private M3U8LiveModule mModule;
|
||||
private long mTaskId;
|
||||
|
||||
@Override
|
||||
protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle(getString(R.string.m3u8_live));
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(M3U8LiveModule.class);
|
||||
mModule.getHttpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTaskId = entity.getId();
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
getBinding().pl.setInfo(entity);
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
startD();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
ALog.d(TAG, "m3u8 live 不支持恢复");
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).cancel(true);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int speed = -1;
|
||||
String msg = "";
|
||||
switch (item.getItemId()) {
|
||||
case R.id.help:
|
||||
msg = "一些小知识点:\n"
|
||||
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
|
||||
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
|
||||
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据";
|
||||
showMsgDialog("tip", msg);
|
||||
break;
|
||||
case R.id.speed_0:
|
||||
speed = 0;
|
||||
break;
|
||||
case R.id.speed_128:
|
||||
speed = 128;
|
||||
break;
|
||||
case R.id.speed_256:
|
||||
speed = 256;
|
||||
break;
|
||||
case R.id.speed_512:
|
||||
speed = 512;
|
||||
break;
|
||||
case R.id.speed_1m:
|
||||
speed = 1024;
|
||||
break;
|
||||
}
|
||||
if (speed > -1) {
|
||||
msg = item.getTitle().toString();
|
||||
Aria.download(this).setMaxSpeed(speed);
|
||||
T.showShort(this, msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@M3U8.onPeerStart
|
||||
void onPeerStart(String m3u8Url, String peerPath, int peerIndex) {
|
||||
//ALog.d(TAG, "peer create, path: " + peerPath + ", index: " + peerIndex);
|
||||
}
|
||||
|
||||
@M3U8.onPeerComplete
|
||||
void onPeerComplete(String m3u8Url, String peerPath, int peerIndex) {
|
||||
//ALog.d(TAG, "peer complete, path: " + peerPath + ", index: " + peerIndex);
|
||||
//mVideoFragment.addPlayer(peerIndex, peerPath);
|
||||
}
|
||||
|
||||
@M3U8.onPeerFail
|
||||
void onPeerFail(String m3u8Url, String peerPath, int peerIndex) {
|
||||
//ALog.d(TAG, "peer fail, path: " + peerPath + ", index: " + peerIndex);
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "pre");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
void taskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG,
|
||||
"m3u8 void running, p = " + task.getPercent() + ", speed = " + task.getConvertSpeed());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "m3u8 vod resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
void taskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.download_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
Log.d(TAG, "fail");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_m3u8_live;
|
||||
}
|
||||
|
||||
private void startD() {
|
||||
mTaskId = Aria.download(M3U8LiveDLoadActivity.this)
|
||||
.load(mUrl)
|
||||
.setFilePath(mFilePath)
|
||||
.ignoreFilePathOccupy()
|
||||
.m3u8LiveOption(getLiveoption())
|
||||
.create();
|
||||
}
|
||||
|
||||
private M3U8LiveOption getLiveoption() {
|
||||
M3U8LiveOption option = new M3U8LiveOption();
|
||||
option
|
||||
//.generateIndexFile()
|
||||
.setLiveTsUrlConvert(new LiveTsUrlConverter());
|
||||
//.setBandWidthUrlConverter(new BandWidthUrlConverter(mUrl));
|
||||
return option;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
mModule.uploadUrl(this, String.valueOf(data));
|
||||
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
|
||||
mModule.updateFilePath(this, String.valueOf(data));
|
||||
}
|
||||
}
|
||||
|
||||
static class LiveTsUrlConverter implements ILiveTsUrlConverter {
|
||||
@Override public String convert(String m3u8Url, String tsUrl) {
|
||||
int index = m3u8Url.lastIndexOf("/");
|
||||
String parentUrl = m3u8Url.substring(0, index + 1);
|
||||
return parentUrl + tsUrl;
|
||||
}
|
||||
}
|
||||
|
||||
static class BandWidthUrlConverter implements IBandWidthUrlConverter {
|
||||
|
||||
@Override public String convert(String m3u8Url, String bandWidthUrl) {
|
||||
int peerIndex = m3u8Url.lastIndexOf("/");
|
||||
return m3u8Url.substring(0, peerIndex + 1) + bandWidthUrl;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8LiveModule extends BaseViewModule {
|
||||
private final String M3U8_LIVE_URL_KEY = "M3U8_LIVE_URL_KEY";
|
||||
private final String M3U8_LIVE_PATH_KEY = "M3U8_LIVE_PATH_KEY";
|
||||
// 多码率地址:
|
||||
private final String defUrl = "http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8";
|
||||
private final String filePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
+ "/live.ts";
|
||||
|
||||
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
|
||||
private DownloadEntity singDownloadInfo;
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getHttpDownloadInfo(Context context) {
|
||||
String url = AppUtil.getConfigValue(context, M3U8_LIVE_URL_KEY, defUrl);
|
||||
String filePath = AppUtil.getConfigValue(context, M3U8_LIVE_PATH_KEY, this.filePath);
|
||||
|
||||
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
File temp = new File(this.filePath);
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_PATH_KEY, singDownloadInfo.getFilePath());
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件保存路径
|
||||
*
|
||||
* @param filePath 文件保存路径
|
||||
*/
|
||||
void updateFilePath(Context context, String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
ALog.e(TAG, "文件保存路径为空");
|
||||
return;
|
||||
}
|
||||
File temp = new File(filePath);
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_PATH_KEY, filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新url
|
||||
*/
|
||||
void uploadUrl(Context context, String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ALog.e(TAG, "下载地址为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_URL_KEY, url);
|
||||
singDownloadInfo.setUrl(url);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
}
|
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.annotations.M3U8;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.M3U8Entity;
|
||||
import com.arialyy.aria.core.download.m3u8.M3U8VodOption;
|
||||
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.processor.IKeyUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ITsMergeHandler;
|
||||
import com.arialyy.aria.core.processor.IVodTsUrlConverter;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.common.ModifyPathDialog;
|
||||
import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivityM3u8VodBinding;
|
||||
import com.arialyy.simple.to.PeerIndex;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
|
||||
|
||||
private String mUrl;
|
||||
private String mFilePath;
|
||||
private M3U8VodModule mModule;
|
||||
private VideoPlayerFragment mVideoFragment;
|
||||
private long mTaskId;
|
||||
|
||||
@Override
|
||||
protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle(getString(R.string.m3u8_file));
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(M3U8VodModule.class);
|
||||
mModule.getHttpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
if (entity.getM3U8Entity() != null) {
|
||||
getBinding().seekBar.setMax(entity.getM3U8Entity().getPeerNum());
|
||||
}
|
||||
mTaskId = entity.getId();
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
getBinding().pl.setInfo(entity);
|
||||
//mVideoFragment = new VideoPlayerFragment(0, entity);
|
||||
//FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
//ft.add(R.id.video_content, mVideoFragment);
|
||||
//ft.commit();
|
||||
}
|
||||
});
|
||||
getBinding().seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
Aria.download(this).load(mTaskId).m3u8VodOption().jumPeerIndex(seekBar.getProgress());
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
startD();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.download(this)
|
||||
.load(mTaskId)
|
||||
.m3u8VodOption(getM3U8Option())
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).cancel(true);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void chooseUrl() {
|
||||
ModifyUrlDialog dialog =
|
||||
new ModifyUrlDialog(this, getString(R.string.modify_url_dialog_title), mUrl);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyUrlDialog");
|
||||
}
|
||||
|
||||
public void chooseFilePath() {
|
||||
ModifyPathDialog dialog =
|
||||
new ModifyPathDialog(this, getString(R.string.modify_file_path), mFilePath);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyPathDialog");
|
||||
}
|
||||
|
||||
@Override protected void onStart() {
|
||||
super.onStart();
|
||||
EventBus.getDefault().register(this);
|
||||
}
|
||||
|
||||
@Override protected void onStop() {
|
||||
super.onStop();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void jumpIndex(PeerIndex index) {
|
||||
Aria.download(this).load(mTaskId).m3u8VodOption().jumPeerIndex(index.index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int speed = -1;
|
||||
String msg = "";
|
||||
switch (item.getItemId()) {
|
||||
case R.id.help:
|
||||
msg = "一些小知识点:\n"
|
||||
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
|
||||
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
|
||||
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据";
|
||||
showMsgDialog("tip", msg);
|
||||
break;
|
||||
case R.id.speed_0:
|
||||
speed = 0;
|
||||
break;
|
||||
case R.id.speed_128:
|
||||
speed = 128;
|
||||
break;
|
||||
case R.id.speed_256:
|
||||
speed = 256;
|
||||
break;
|
||||
case R.id.speed_512:
|
||||
speed = 512;
|
||||
break;
|
||||
case R.id.speed_1m:
|
||||
speed = 1024;
|
||||
break;
|
||||
}
|
||||
if (speed > -1) {
|
||||
msg = item.getTitle().toString();
|
||||
Aria.download(this).setMaxSpeed(speed);
|
||||
T.showShort(this, msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@M3U8.onPeerStart
|
||||
void onPeerStart(String m3u8Url, String peerPath, int peerIndex) {
|
||||
//ALog.d(TAG, "peer create, path: " + peerPath + ", index: " + peerIndex);
|
||||
}
|
||||
|
||||
@M3U8.onPeerComplete
|
||||
void onPeerComplete(String m3u8Url, String peerPath, int peerIndex) {
|
||||
//ALog.d(TAG, "peer complete, path: " + peerPath + ", index: " + peerIndex);
|
||||
//mVideoFragment.addPlayer(peerIndex, peerPath);
|
||||
}
|
||||
|
||||
@M3U8.onPeerFail
|
||||
void onPeerFail(String m3u8Url, String peerPath, int peerIndex) {
|
||||
//ALog.d(TAG, "peer fail, path: " + peerPath + ", index: " + peerIndex);
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "pre");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
void taskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
getBinding().seekBar.setMax(task.getEntity().getM3U8Entity().getPeerNum());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG,
|
||||
"m3u8 void running, p = " + task.getPercent() + ", speed = " + task.getConvertSpeed());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "m3u8 vod resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
void taskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
if (task != null && task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(M3U8VodDLoadActivity.this, getString(R.string.download_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
Log.d(TAG, "fail");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(M3U8VodDLoadActivity.this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_m3u8_vod;
|
||||
}
|
||||
|
||||
private void startD() {
|
||||
mTaskId = Aria.download(M3U8VodDLoadActivity.this)
|
||||
.load(mUrl)
|
||||
.setFilePath(mFilePath)
|
||||
.ignoreFilePathOccupy()
|
||||
.m3u8VodOption(getM3U8Option())
|
||||
.create();
|
||||
}
|
||||
|
||||
private M3U8VodOption getM3U8Option() {
|
||||
M3U8VodOption option = new M3U8VodOption();
|
||||
//option.setBandWidth(200000);
|
||||
//.generateIndexFile()
|
||||
//.merge(true)
|
||||
//.setVodTsUrlConvert(new VodTsUrlConverter());
|
||||
//.setMergeHandler(new TsMergeHandler());
|
||||
option.setUseDefConvert(true);
|
||||
option.generateIndexFile();
|
||||
//option.setKeyUrlConverter(new KeyUrlConverter());
|
||||
//option.setVodTsUrlConvert(new VodTsUrlConverter());
|
||||
option.setBandWidthUrlConverter(new BandWidthUrlConverter());
|
||||
//option.setUseDefConvert(true);
|
||||
return option;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
mModule.uploadUrl(this, String.valueOf(data));
|
||||
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
|
||||
mModule.updateFilePath(this, String.valueOf(data));
|
||||
}
|
||||
}
|
||||
|
||||
static class VodTsUrlConverter implements IVodTsUrlConverter {
|
||||
@Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
|
||||
Uri uri = Uri.parse(m3u8Url);
|
||||
//String parentUrl = "http://devimages.apple.com/iphone/samples/bipbop/gear1/";
|
||||
//String parentUrl = "http://youku.cdn7-okzy.com/20200123/16815_fbe419ed/1000k/hls/";
|
||||
//String parentUrl = "http://" + uri.getHost() + "/gear1/";
|
||||
//int index = m3u8Url.lastIndexOf("/");
|
||||
//String parentUrl = m3u8Url.substring(0, index + 1);
|
||||
//String parentUrl = "https://v1.szjal.cn/20190819/Ql6UD1od/";
|
||||
//String parentUrl = "http://" + uri.getHost() + "/";
|
||||
//List<String> newUrls = new ArrayList<>();
|
||||
//for (String url : tsUrls) {
|
||||
// newUrls.add(parentUrl + url);
|
||||
//}
|
||||
|
||||
//return newUrls;
|
||||
return tsUrls;
|
||||
}
|
||||
}
|
||||
|
||||
static class TsMergeHandler implements ITsMergeHandler {
|
||||
public boolean merge(@Nullable M3U8Entity m3U8Entity, List<String> tsPath) {
|
||||
ALog.d("TsMergeHandler", "合并TS....");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class BandWidthUrlConverter implements IBandWidthUrlConverter {
|
||||
|
||||
|
||||
@Override public String convert(String m3u8Url, String bandWidthUrl) {
|
||||
int index = m3u8Url.lastIndexOf("/");
|
||||
return m3u8Url.substring(0, index + 1) + bandWidthUrl;
|
||||
}
|
||||
}
|
||||
|
||||
static class KeyUrlConverter implements IKeyUrlConverter {
|
||||
|
||||
@Override public String convert(String m3u8Url, String tsListUrl, String keyUrl) {
|
||||
ALog.d("TAG", "convertUrl....");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8VodModule extends BaseViewModule {
|
||||
private final String M3U8_URL_KEY = "M3U8_URL_KEY";
|
||||
private final String M3U8_PATH_KEY = "M3U8_PATH_KEY";
|
||||
// m3u8测试集合:http://www.voidcn.com/article/p-snaliarm-ct.html
|
||||
//private final String defUrl = "https://www.gaoya123.cn/2019/1557993797897.m3u8";
|
||||
// 多码率地址:
|
||||
//private final String defUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
|
||||
private final String defUrl = "https://5.voooe.cn/cache/youku/4e00b49a6e4f11155967c2cb3385a2ab.m3u8";
|
||||
//private final String defUrl = "http://pp3zvsk2n.bkt.clouddn.com/20200806/sd/15967206011811803/38475fadd55e4ecea3.m3u8";
|
||||
//private final String defUrl = "http://youku.cdn7-okzy.com/20200123/16815_fbe419ed/index.m3u8";
|
||||
|
||||
//private final String defUrl = "https://cn7.kankia.com/hls/20200108/e1eaec074274c64fe46a3bdb5d2ba487/1578488360/index.m3u8";
|
||||
//private final String defUrl = "https://youku.cdn7-okzy.com/20191213/16167_c3592a02/index.m3u8";
|
||||
//private final String defUrl = "http://qn.shytong.cn/b83137769ff6b555/11b0c9970f9a3fa0.mp4.m3u8";
|
||||
//private final String defUrl = "https://135zyv5.xw0371.com/2018/10/29/X05c7CG3VB91gi1M/playlist.m3u8";
|
||||
//private final String defUrl = "https://fangao.qfxmj.com/video/20191111/dbf7e2aa0c5f42a8b040442b54c13e3a/cloudv-transfer/555555556nr593o75556r165q86n82n0_eb3da35b8f4442808756a6ddc8ec1372_0_3.m3u8?wsSecret=d5fb403512d4cd427f18858086b35ce4&wsTime=1582197537";
|
||||
//private final String defUrl = "https://v1.szjal.cn/20190819/Ql6UD1od/index.m3u8";
|
||||
private final String filePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
//+ "/道士下山.ts";
|
||||
+ "/bb1.ts";
|
||||
|
||||
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
|
||||
private DownloadEntity singDownloadInfo;
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getHttpDownloadInfo(Context context) {
|
||||
String url = AppUtil.getConfigValue(context, M3U8_URL_KEY, defUrl);
|
||||
String filePath = AppUtil.getConfigValue(context, M3U8_PATH_KEY, this.filePath);
|
||||
|
||||
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
File temp = new File(this.filePath);
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, singDownloadInfo.getFilePath());
|
||||
AppUtil.setConfigValue(context, M3U8_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件保存路径
|
||||
*
|
||||
* @param filePath 文件保存路径
|
||||
*/
|
||||
void updateFilePath(Context context, String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
ALog.e(TAG, "文件保存路径为空");
|
||||
return;
|
||||
}
|
||||
File temp = new File(filePath);
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新url
|
||||
*/
|
||||
void uploadUrl(Context context, String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ALog.e(TAG, "下载地址为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, M3U8_URL_KEY, url);
|
||||
singDownloadInfo.setUrl(url);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
}
|
@ -0,0 +1,288 @@
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
import android.widget.SeekBar;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.M3U8Entity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseFragment;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.common.LoadingDialog;
|
||||
import com.arialyy.simple.databinding.FragmentVideoPlayerBinding;
|
||||
import com.arialyy.simple.to.PeerIndex;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
@SuppressLint("ValidFragment")
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
|
||||
public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding> {
|
||||
|
||||
private M3U8VodModule mModule;
|
||||
private DownloadEntity mEntity;
|
||||
private int mPeerIndex;
|
||||
private SparseArray<String> mPlayers = new SparseArray<>();
|
||||
private SurfaceHolder mSurfaceHolder;
|
||||
private NextMediaPlayer mNextPlayer;
|
||||
private MediaPlayer mCurrentPlayer;
|
||||
private LoadingDialog mLoadingDialog;
|
||||
private int mJumpIndex = -1;
|
||||
private boolean needPaint= true;
|
||||
|
||||
VideoPlayerFragment(int peerIndex, DownloadEntity entity) {
|
||||
mEntity = entity;
|
||||
mPeerIndex = peerIndex;
|
||||
M3U8Entity m3U8Entity = entity.getM3U8Entity();
|
||||
if (m3U8Entity == null) {
|
||||
return;
|
||||
}
|
||||
List<M3U8Entity.PeerInfo> peerInfos = m3U8Entity.getCompletedPeer();
|
||||
if (peerInfos != null) {
|
||||
for (M3U8Entity.PeerInfo info : peerInfos) {
|
||||
mPlayers.put(info.peerId, info.peerPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
mModule = ViewModelProviders.of(this).get(M3U8VodModule.class);
|
||||
|
||||
getBinding().surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
||||
@Override public void surfaceCreated(SurfaceHolder holder) {
|
||||
mSurfaceHolder = holder;
|
||||
//if (needPaint){
|
||||
// needPaint = false;
|
||||
// Canvas canvas = holder.lockCanvas();
|
||||
// canvas.drawColor(Color.BLACK);
|
||||
// holder.unlockCanvasAndPost(canvas);
|
||||
//}
|
||||
startNewPlayer(mPlayers.valueAt(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
if (mCurrentPlayer != null) {
|
||||
mCurrentPlayer.release();
|
||||
}
|
||||
if (mNextPlayer != null) {
|
||||
mNextPlayer.getPlayer().release();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (mEntity.getM3U8Entity() != null) {
|
||||
getBinding().seekBar.setMax(mEntity.getM3U8Entity().getPeerNum());
|
||||
}
|
||||
getBinding().seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
PeerIndex index = new PeerIndex();
|
||||
index.index = seekBar.getProgress();
|
||||
mJumpIndex = index.index;
|
||||
EventBus.getDefault().post(index);
|
||||
if (mCurrentPlayer != null && mCurrentPlayer.isPlaying()) {
|
||||
mCurrentPlayer.stop();
|
||||
mCurrentPlayer.setDisplay(null);
|
||||
mCurrentPlayer.release();
|
||||
}
|
||||
showLoadingDialog();
|
||||
}
|
||||
});
|
||||
|
||||
getBinding().controlBt.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
if (mCurrentPlayer != null) {
|
||||
if (mCurrentPlayer.isPlaying()) {
|
||||
getBinding().controlBt.setSelected(true);
|
||||
mCurrentPlayer.start();
|
||||
} else {
|
||||
getBinding().controlBt.setSelected(false);
|
||||
mCurrentPlayer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startNewPlayer(String source) {
|
||||
if (TextUtils.isEmpty(source)) {
|
||||
ALog.e(TAG, "资源路径为空");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCurrentPlayer = new MediaPlayer();
|
||||
mCurrentPlayer.setScreenOnWhilePlaying(true);
|
||||
mCurrentPlayer.setSurface(mSurfaceHolder.getSurface());
|
||||
mCurrentPlayer.setDataSource(source);
|
||||
mCurrentPlayer.prepareAsync();
|
||||
mCurrentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override public void onPrepared(MediaPlayer mp) {
|
||||
mp.start();
|
||||
setNextMediaPlayer(mp);
|
||||
}
|
||||
});
|
||||
|
||||
mCurrentPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||
@Override public void onCompletion(MediaPlayer mp) {
|
||||
mp.setDisplay(null);
|
||||
mNextPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
|
||||
mNextPlayer.start();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置下一个分片
|
||||
*/
|
||||
private void setNextMediaPlayer(final MediaPlayer lastPlayer) {
|
||||
mPeerIndex++;
|
||||
String nextPeerPath = mPlayers.get(mPeerIndex);
|
||||
if (!TextUtils.isEmpty(nextPeerPath)) {
|
||||
mNextPlayer = new NextMediaPlayer(nextPeerPath);
|
||||
mNextPlayer.prepareAsync();
|
||||
|
||||
mNextPlayer.setListener(new NextMediaPlayer.StateListener() {
|
||||
@Override public void onStart(MediaPlayer mp) {
|
||||
mCurrentPlayer = mp;
|
||||
setNextMediaPlayer(mp);
|
||||
}
|
||||
|
||||
@Override public void onCompletion(MediaPlayer mp) {
|
||||
//mp.setDisplay(null);
|
||||
//mNextPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
|
||||
mNextPlayer.start();
|
||||
}
|
||||
|
||||
@Override public void onPrepared(MediaPlayer mp) {
|
||||
lastPlayer.setNextMediaPlayer(mNextPlayer.getPlayer());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void showLoadingDialog() {
|
||||
if (mLoadingDialog == null) {
|
||||
mLoadingDialog = new LoadingDialog(this);
|
||||
}
|
||||
if (!mLoadingDialog.isHidden()) {
|
||||
mLoadingDialog.show(getChildFragmentManager(), "mLoadingDialog");
|
||||
}
|
||||
}
|
||||
|
||||
private void dismissDialog() {
|
||||
if (mLoadingDialog != null) {
|
||||
mLoadingDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.fragment_video_player;
|
||||
}
|
||||
|
||||
public void addPlayer(int peerIndex, String peerPath) {
|
||||
mPlayers.put(peerIndex, peerPath);
|
||||
if (mJumpIndex != -1 && mJumpIndex == peerIndex) {
|
||||
startNewPlayer(mPlayers.get(peerIndex));
|
||||
dismissDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private static class NextMediaPlayer implements MediaPlayer.OnPreparedListener,
|
||||
MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
|
||||
private StateListener listener;
|
||||
|
||||
public interface StateListener {
|
||||
void onStart(MediaPlayer mp);
|
||||
|
||||
void onCompletion(MediaPlayer mp);
|
||||
|
||||
void onPrepared(MediaPlayer mp);
|
||||
}
|
||||
|
||||
private MediaPlayer player;
|
||||
private String videoPath;
|
||||
|
||||
private NextMediaPlayer(String videoPath) {
|
||||
player = new MediaPlayer();
|
||||
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
player.setOnPreparedListener(this);
|
||||
player.setOnErrorListener(this);
|
||||
player.setOnCompletionListener(this);
|
||||
player.setScreenOnWhilePlaying(true);
|
||||
this.videoPath = videoPath;
|
||||
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override public void onPrepared(MediaPlayer mp) {
|
||||
if (listener != null) {
|
||||
listener.onPrepared(mp);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void prepareAsync() {
|
||||
try {
|
||||
player.setDataSource(videoPath);
|
||||
player.prepareAsync();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(StateListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public String getVideoPath() {
|
||||
return videoPath;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
player.start();
|
||||
if (listener != null) {
|
||||
listener.onStart(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onCompletion(MediaPlayer mp) {
|
||||
if (listener != null) {
|
||||
listener.onCompletion(mp);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean onError(MediaPlayer mp, int what, int extra) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public void onPrepared(MediaPlayer mp) {
|
||||
}
|
||||
|
||||
private MediaPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
||||
import com.arialyy.simple.widget.SubStateLinearLayout;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
* 下载列表适配器
|
||||
*/
|
||||
public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.SimpleHolder> {
|
||||
private static final String TAG = "DownloadAdapter";
|
||||
private Map<String, Integer> mPositions = new ConcurrentHashMap<>();
|
||||
|
||||
public DownloadAdapter(Context context, List<AbsEntity> data) {
|
||||
super(context, data);
|
||||
int i = 0;
|
||||
for (AbsEntity entity : data) {
|
||||
mPositions.put(getKey(entity), i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private String getKey(AbsEntity entity) {
|
||||
if (entity instanceof DownloadEntity) {
|
||||
return ((DownloadEntity) entity).getUrl();
|
||||
} else if (entity instanceof DownloadGroupEntity) {
|
||||
return ((DownloadGroupEntity) entity).getGroupHash();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override protected SimpleHolder getViewHolder(View convertView, int viewType) {
|
||||
if (viewType == 1) return new SimpleHolder(convertView);
|
||||
if (viewType == 2) return new GroupHolder(convertView);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addDownloadEntity(DownloadEntity entity) {
|
||||
mData.add(entity);
|
||||
mPositions.put(entity.getUrl(), mPositions.size());
|
||||
}
|
||||
|
||||
public int getItemViewType(int position) {
|
||||
AbsEntity entity = mData.get(position);
|
||||
if (entity instanceof DownloadEntity) return 1;
|
||||
if (entity instanceof DownloadGroupEntity) return 2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId(int type) {
|
||||
if (type == 1) {
|
||||
return R.layout.item_simple_download;
|
||||
} else if (type == 2) {
|
||||
return R.layout.item_group_download;
|
||||
}
|
||||
return android.R.layout.simple_list_item_2;
|
||||
}
|
||||
|
||||
public synchronized void updateState(AbsEntity entity) {
|
||||
if (entity.getState() == IEntity.STATE_CANCEL) {
|
||||
mData.remove(entity);
|
||||
mPositions.clear();
|
||||
int i = 0;
|
||||
for (AbsEntity entity_1 : mData) {
|
||||
mPositions.put(getKey(entity_1), i);
|
||||
i++;
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
} else {
|
||||
int position = indexItem(getKey(entity));
|
||||
if (position == -1 || position >= mData.size()) {
|
||||
return;
|
||||
}
|
||||
mData.set(position, entity);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新进度
|
||||
*/
|
||||
public synchronized void setProgress(AbsEntity entity) {
|
||||
String url = entity.getKey();
|
||||
int position = indexItem(url);
|
||||
if (position == -1 || position >= mData.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mData.set(position, entity);
|
||||
notifyItemChanged(position, entity);
|
||||
}
|
||||
|
||||
private synchronized int indexItem(String url) {
|
||||
Set<String> keys = mPositions.keySet();
|
||||
for (String key : keys) {
|
||||
if (key.equals(url)) {
|
||||
return mPositions.get(key);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override protected void bindData(SimpleHolder holder, int position, final AbsEntity item) {
|
||||
handleProgress(holder, item);
|
||||
}
|
||||
|
||||
@Override protected void bindData(SimpleHolder holder, int position, AbsEntity item,
|
||||
List<Object> payloads) {
|
||||
AbsEntity entity = (AbsEntity) payloads.get(0);
|
||||
updateSpeed(holder, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 只更新速度
|
||||
*/
|
||||
private void updateSpeed(SimpleHolder holder, final AbsEntity entity) {
|
||||
|
||||
holder.speed.setText(entity.getConvertSpeed());
|
||||
if (entity.getTaskType() == ITaskWrapper.M3U8_VOD
|
||||
|| entity.getTaskType() == ITaskWrapper.M3U8_LIVE) {
|
||||
holder.progress.setProgress(entity.getPercent());
|
||||
holder.fileSize.setVisibility(View.GONE);
|
||||
} else {
|
||||
long size = entity.getFileSize();
|
||||
long progress = entity.getCurrentProgress();
|
||||
int current = size == 0 ? 0 : (int) (progress * 100 / size);
|
||||
holder.fileSize.setText(covertCurrentSize(progress) + "/" + CommonUtil.formatFileSize(size));
|
||||
holder.progress.setProgress(current);
|
||||
}
|
||||
//if (holder instanceof GroupHolder){
|
||||
// handleSubChild((GroupHolder) holder, entity);
|
||||
//}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void handleProgress(SimpleHolder holder, final AbsEntity entity) {
|
||||
String str = "";
|
||||
int color = android.R.color.holo_green_light;
|
||||
switch (entity.getState()) {
|
||||
case IEntity.STATE_WAIT:
|
||||
str = "等待中";
|
||||
break;
|
||||
case IEntity.STATE_OTHER:
|
||||
case IEntity.STATE_FAIL:
|
||||
str = "开始";
|
||||
break;
|
||||
case IEntity.STATE_STOP:
|
||||
str = "恢复";
|
||||
color = android.R.color.holo_blue_light;
|
||||
break;
|
||||
case IEntity.STATE_PRE:
|
||||
case IEntity.STATE_POST_PRE:
|
||||
case IEntity.STATE_RUNNING:
|
||||
str = "暂停";
|
||||
color = android.R.color.holo_red_light;
|
||||
break;
|
||||
case IEntity.STATE_COMPLETE:
|
||||
str = "完成";
|
||||
holder.progress.setProgress(100);
|
||||
break;
|
||||
}
|
||||
long size = entity.getFileSize();
|
||||
long progress = entity.getCurrentProgress();
|
||||
int current = size == 0 ? 0 : (int) (progress * 100 / size);
|
||||
holder.bt.setText(str);
|
||||
holder.bt.setTextColor(getColor(color));
|
||||
holder.progress.setProgress(current);
|
||||
|
||||
BtClickListener listener = new BtClickListener(entity);
|
||||
holder.bt.setOnClickListener(listener);
|
||||
String name = (isSimpleDownload(entity) ? ((DownloadEntity) entity).getFileName()
|
||||
: ((DownloadGroupEntity) entity).getAlias());
|
||||
holder.name.setText("文件名:" + name);
|
||||
holder.speed.setText(entity.getConvertSpeed());
|
||||
holder.fileSize.setText(covertCurrentSize(progress) + "/" + CommonUtil.formatFileSize(size));
|
||||
//删除按钮事件
|
||||
holder.cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
mData.remove(entity);
|
||||
notifyDataSetChanged();
|
||||
cancel(entity);
|
||||
//stop(entity);
|
||||
}
|
||||
});
|
||||
//if (holder instanceof GroupHolder){
|
||||
// handleSubChild((GroupHolder) holder, entity);
|
||||
//}
|
||||
}
|
||||
|
||||
private void handleSubChild(GroupHolder holder, final AbsEntity entity) {
|
||||
if (holder.childList.getSubData().size() > 0) {
|
||||
holder.childList.updateChildProgress(((DownloadGroupEntity) entity).getSubEntities());
|
||||
} else {
|
||||
holder.childList.addData(((DownloadGroupEntity) entity).getSubEntities());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSimpleDownload(AbsEntity entity) {
|
||||
return entity instanceof DownloadEntity;
|
||||
}
|
||||
|
||||
private String covertCurrentSize(long currentSize) {
|
||||
if (currentSize < 0) return "0";
|
||||
return CommonUtil.formatFileSize(currentSize);
|
||||
}
|
||||
|
||||
private int getColor(int color) {
|
||||
return Resources.getSystem().getColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按钮事件
|
||||
*/
|
||||
private class BtClickListener implements View.OnClickListener {
|
||||
private AbsEntity entity;
|
||||
|
||||
BtClickListener(AbsEntity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override public void onClick(View v) {
|
||||
switch (entity.getState()) {
|
||||
case IEntity.STATE_WAIT:
|
||||
case IEntity.STATE_OTHER:
|
||||
case IEntity.STATE_FAIL:
|
||||
case IEntity.STATE_STOP:
|
||||
case IEntity.STATE_PRE:
|
||||
case IEntity.STATE_POST_PRE:
|
||||
if (entity.getId() < 0) {
|
||||
start(entity);
|
||||
} else {
|
||||
resume(entity);
|
||||
}
|
||||
break;
|
||||
case IEntity.STATE_RUNNING:
|
||||
stop(entity);
|
||||
break;
|
||||
case IEntity.STATE_COMPLETE:
|
||||
Log.d(TAG, "任务已完成");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancel(AbsEntity entity) {
|
||||
if (!AppUtil.chekEntityValid(entity)) {
|
||||
return;
|
||||
}
|
||||
switch (entity.getTaskType()) {
|
||||
case ITaskWrapper.D_FTP:
|
||||
Aria.download(getContext())
|
||||
.loadFtp(entity.getId())
|
||||
//.login("lao", "123456")
|
||||
.cancel(true);
|
||||
break;
|
||||
case ITaskWrapper.D_FTP_DIR:
|
||||
Aria.download(getContext()).loadFtpDir(entity.getId()).cancel(true);
|
||||
break;
|
||||
case ITaskWrapper.D_HTTP:
|
||||
case ITaskWrapper.M3U8_VOD:
|
||||
Aria.download(getContext()).load(entity.getId()).cancel(true);
|
||||
break;
|
||||
case ITaskWrapper.DG_HTTP:
|
||||
Aria.download(getContext()).loadGroup(entity.getId()).cancel(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void resume(AbsEntity entity) {
|
||||
switch (entity.getTaskType()) {
|
||||
case ITaskWrapper.D_FTP:
|
||||
//Aria.download(getContext()).loadFtp((DownloadEntity) entity).login("lao", "123456").create();
|
||||
Aria.download(getContext()).loadFtp(entity.getId()).resume(true);
|
||||
break;
|
||||
case ITaskWrapper.D_FTP_DIR:
|
||||
Aria.download(getContext()).loadFtpDir(entity.getId()).resume(true);
|
||||
break;
|
||||
case ITaskWrapper.D_HTTP:
|
||||
case ITaskWrapper.M3U8_VOD:
|
||||
Aria.download(getContext()).load(entity.getId()).resume(true);
|
||||
break;
|
||||
case ITaskWrapper.DG_HTTP:
|
||||
Aria.download(getContext()).loadGroup(entity.getId()).resume(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void start(AbsEntity entity) {
|
||||
switch (entity.getTaskType()) {
|
||||
case ITaskWrapper.D_FTP:
|
||||
//Aria.download(getContext()).loadFtp((DownloadEntity) entity).login("lao", "123456").create();
|
||||
Aria.download(getContext()).loadFtp(entity.getKey()).create();
|
||||
break;
|
||||
case ITaskWrapper.D_FTP_DIR:
|
||||
break;
|
||||
case ITaskWrapper.D_HTTP:
|
||||
case ITaskWrapper.M3U8_VOD:
|
||||
Aria.download(getContext()).load(entity.getKey()).create();
|
||||
break;
|
||||
case ITaskWrapper.DG_HTTP:
|
||||
Aria.download(getContext()).loadGroup(((DownloadGroupEntity) entity).getUrls()).create();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void stop(AbsEntity entity) {
|
||||
if (!AppUtil.chekEntityValid(entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (entity.getTaskType()) {
|
||||
case ITaskWrapper.D_FTP:
|
||||
Aria.download(getContext()).loadFtp(entity.getId()).stop();
|
||||
break;
|
||||
case ITaskWrapper.D_FTP_DIR:
|
||||
break;
|
||||
case ITaskWrapper.D_HTTP:
|
||||
case ITaskWrapper.M3U8_VOD:
|
||||
Aria.download(getContext()).load(entity.getId()).stop();
|
||||
break;
|
||||
case ITaskWrapper.DG_HTTP:
|
||||
Aria.download(getContext()).loadGroup(entity.getId()).stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleHolder extends AbsHolder {
|
||||
HorizontalProgressBarWithNumber progress;
|
||||
Button bt;
|
||||
TextView speed;
|
||||
TextView fileSize;
|
||||
TextView cancel;
|
||||
TextView name;
|
||||
|
||||
SimpleHolder(View itemView) {
|
||||
super(itemView);
|
||||
progress = itemView.findViewById(R.id.progressBar);
|
||||
bt = itemView.findViewById(R.id.bt);
|
||||
speed = itemView.findViewById(R.id.speed);
|
||||
fileSize = itemView.findViewById(R.id.fileSize);
|
||||
cancel = itemView.findViewById(R.id.del);
|
||||
name = itemView.findViewById(R.id.name);
|
||||
}
|
||||
}
|
||||
|
||||
class GroupHolder extends SimpleHolder {
|
||||
SubStateLinearLayout childList;
|
||||
|
||||
GroupHolder(View itemView) {
|
||||
super(itemView);
|
||||
childList = itemView.findViewById(R.id.child_list);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseDialog;
|
||||
import com.arialyy.simple.databinding.DialogDownloadNumBinding;
|
||||
|
||||
/**
|
||||
* Created by “AriaLyy@outlook.com” on 2016/11/14.
|
||||
* 设置下载数量对话框
|
||||
*/
|
||||
@SuppressLint("ValidFragment") public class DownloadNumDialog
|
||||
extends BaseDialog<DialogDownloadNumBinding> implements RadioGroup.OnCheckedChangeListener {
|
||||
public static final int RESULT_CODE = 1001;
|
||||
Button mCancel;
|
||||
RadioGroup mRg;
|
||||
|
||||
public DownloadNumDialog(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.dialog_download_num;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
mCancel = findViewById(R.id.cancel);
|
||||
mRg = findViewById(R.id.rg);
|
||||
|
||||
mCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
for (int i = 0, count = mRg.getChildCount(); i < count; i++) {
|
||||
RadioButton rb = (RadioButton) mRg.getChildAt(i);
|
||||
rb.setId(i);
|
||||
}
|
||||
mRg.setOnCheckedChangeListener(this);
|
||||
}
|
||||
|
||||
@Override public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||
RadioButton rb = (RadioButton) group.getChildAt(checkedId);
|
||||
if (rb.isChecked()) {
|
||||
getSimplerModule().onDialog(RESULT_CODE, rb.getTag());
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.m3u8.M3U8VodOption;
|
||||
import com.arialyy.aria.core.processor.IVodTsUrlConverter;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8VodDLoadActivity;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/6.
|
||||
*/
|
||||
final class FileListAdapter extends AbsRVAdapter<FileListEntity, FileListAdapter.FileListHolder> {
|
||||
|
||||
//SparseBooleanArray mBtStates = new SparseBooleanArray();
|
||||
Map<String, Boolean> mBtStates = new ConcurrentHashMap<>();
|
||||
private Map<String, Integer> mPositions = new ConcurrentHashMap<>();
|
||||
|
||||
public FileListAdapter(Context context, List<FileListEntity> data) {
|
||||
super(context, data);
|
||||
for (int i = 0, len = data.size(); i < len; i++) {
|
||||
mBtStates.put(data.get(i).key, true);
|
||||
mPositions.put(data.get(i).key, i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected FileListHolder getViewHolder(View convertView, int viewType) {
|
||||
return new FileListHolder(convertView);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId(int type) {
|
||||
return R.layout.item_file_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindData(FileListHolder holder, int position, final FileListEntity item) {
|
||||
holder.name.setText("文件名:" + item.name);
|
||||
holder.url.setText("下载地址:" + item.key);
|
||||
if (item.type == 1) {
|
||||
holder.url.setVisibility(View.GONE);
|
||||
}
|
||||
holder.path.setText("保存路径:" + item.downloadPath);
|
||||
if (mBtStates.get(item.key)) {
|
||||
holder.bt.setEnabled(true);
|
||||
holder.bt.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
Toast.makeText(getContext(), "开始下载:" + item.name, Toast.LENGTH_SHORT).show();
|
||||
switch (item.type) {
|
||||
case 0:
|
||||
Aria.download(getContext())
|
||||
.load(item.key)
|
||||
.setFilePath(item.downloadPath)
|
||||
.create();
|
||||
break;
|
||||
case 1:
|
||||
Aria.download(getContext())
|
||||
.loadGroup(Arrays.asList(item.urls))
|
||||
.setSubFileName(Arrays.asList(item.names))
|
||||
.setDirPath(item.downloadPath)
|
||||
.setGroupAlias(item.name)
|
||||
.unknownSize()
|
||||
.create();
|
||||
ALog.d(TAG, "getGroupTaskList = " + Aria.download(this).getGroupTaskList().size());
|
||||
break;
|
||||
case 2:
|
||||
M3U8VodOption option = new M3U8VodOption();
|
||||
option.setVodTsUrlConvert(new IVodTs());
|
||||
option.generateIndexFile();
|
||||
|
||||
Aria.download(getContext())
|
||||
.load(item.key)
|
||||
.setFilePath(item.downloadPath, true)
|
||||
.m3u8VodOption(option)
|
||||
.create();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
holder.bt.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBtState(String downloadUrl, boolean able) {
|
||||
Set<String> keys = mBtStates.keySet();
|
||||
for (String key : keys) {
|
||||
if (key.equals(downloadUrl)) {
|
||||
mBtStates.put(downloadUrl, able);
|
||||
notifyItemChanged(indexItem(downloadUrl));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized int indexItem(String url) {
|
||||
Set<String> keys = mPositions.keySet();
|
||||
for (String key : keys) {
|
||||
if (key.equals(url)) {
|
||||
int index = mPositions.get(key);
|
||||
//Log.d(TAG, "peerIndex ==> " + peerIndex);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
class FileListHolder extends AbsHolder {
|
||||
TextView name;
|
||||
TextView url;
|
||||
TextView path;
|
||||
Button bt;
|
||||
|
||||
FileListHolder(View itemView) {
|
||||
super(itemView);
|
||||
name = findViewById(R.id.name);
|
||||
url = findViewById(R.id.download_url);
|
||||
path = findViewById(R.id.download_path);
|
||||
bt = findViewById(R.id.bt);
|
||||
}
|
||||
}
|
||||
static class IVodTs implements IVodTsUrlConverter{
|
||||
|
||||
@Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
|
||||
List<String> temp = new ArrayList<>();
|
||||
for (String tsUrl : tsUrls){
|
||||
temp.add("http://qn.shytong.cn" + tsUrl);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/6.
|
||||
*/
|
||||
|
||||
public class FileListEntity {
|
||||
public String name, key, downloadPath;
|
||||
|
||||
/**
|
||||
* 0:普通任务
|
||||
* 1:组合任务
|
||||
* 2:m3u8任务
|
||||
*/
|
||||
public int type = 0;
|
||||
|
||||
public String[] urls, names;
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.annotations.DownloadGroup;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMultiDownloadBinding;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/6.
|
||||
*/
|
||||
public class MultiDownloadActivity extends BaseActivity<ActivityMultiDownloadBinding> {
|
||||
RecyclerView mList;
|
||||
private DownloadAdapter mAdapter;
|
||||
private List<AbsEntity> mData = new ArrayList<>();
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_multi_download;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.download(this).register();
|
||||
setTitle("下载列表");
|
||||
List<AbsEntity> temps = Aria.download(this).getTotalTaskList();
|
||||
if (temps != null && !temps.isEmpty()) {
|
||||
|
||||
for (AbsEntity temp : temps) {
|
||||
ALog.d(TAG, "state = " + temp.getState());
|
||||
}
|
||||
mData.addAll(temps);
|
||||
}
|
||||
mAdapter = new DownloadAdapter(this, mData);
|
||||
mList = getBinding().list;
|
||||
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@Override public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_mutil_task, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override public boolean onMenuItemClick(MenuItem item) {
|
||||
Aria.download(this).resumeAllTask();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Download.onPre void onPre(DownloadTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
Log.d(TAG, task.getTaskName() + ", " + task.getState());
|
||||
}
|
||||
|
||||
@Download.onWait void onWait(DownloadTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskStart void taskStart(DownloadTask task) {
|
||||
Log.d(TAG, task.getTaskName() + ", " + task.getState());
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskResume void taskResume(DownloadTask task) {
|
||||
Log.d(TAG, task.getTaskName() + ", " + task.getState());
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskStop void taskStop(DownloadTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskCancel void taskCancel(DownloadTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
List<DownloadEntity> tasks = Aria.download(this).getAllNotCompleteTask();
|
||||
if (tasks != null){
|
||||
ALog.d(TAG, "未完成的任务数:" + tasks.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail void taskFail(DownloadTask task) {
|
||||
if (task == null || task.getEntity() == null){
|
||||
return;
|
||||
}
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskComplete void taskComplete(DownloadTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@Download.onTaskRunning void taskRunning(DownloadTask task) {
|
||||
mAdapter.setProgress(task.getEntity());
|
||||
}
|
||||
|
||||
//////////////////////////////////// 下面为任务组的处理 /////////////////////////////////////////
|
||||
|
||||
@DownloadGroup.onPre void onGroupPre(DownloadGroupTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStart void groupTaskStart(DownloadGroupTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onWait void groupTaskWait(DownloadGroupTask task) {
|
||||
ALog.d(TAG, String.format("group【%s】wait---", task.getTaskName()));
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskResume void groupTaskResume(DownloadGroupTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStop void groupTaskStop(DownloadGroupTask task) {
|
||||
ALog.d(TAG, String.format("group【%s】stop", task.getTaskName()));
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskCancel void groupTaskCancel(DownloadGroupTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskFail void groupTaskFail(DownloadGroupTask task) {
|
||||
if (task != null) {
|
||||
ALog.d(TAG, String.format("group【%s】fail", task.getTaskName()));
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskComplete void groupTaskComplete(DownloadGroupTask task) {
|
||||
mAdapter.updateState(task.getEntity());
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskRunning() void groupTaskRunning(DownloadGroupTask task) {
|
||||
ALog.d(TAG, String.format("group【%s】running", task.getTaskName()));
|
||||
mAdapter.setProgress(task.getEntity());
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
//Aria.download(this).unRegister();
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/14.
|
||||
*/
|
||||
public class MultiEntity {
|
||||
public static final int SIMPLE_DOWNLOAD = 0xa1;
|
||||
public static final int GROUP_DOWNLOAD = 0xa2;
|
||||
|
||||
DownloadEntity simpleEntity;
|
||||
DownloadGroupEntity groupEntity;
|
||||
String key;
|
||||
|
||||
int type = -1;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import android.content.Context;
|
||||
import com.arialyy.simple.base.BaseModule;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/14.
|
||||
*/
|
||||
public class MultiModule extends BaseModule{
|
||||
public MultiModule(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.mutil;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.annotations.DownloadGroup;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.util.FileUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.core.download.DownloadModule;
|
||||
import com.arialyy.simple.databinding.ActivityMultiBinding;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class MultiTaskListActivity extends BaseActivity<ActivityMultiBinding> {
|
||||
RecyclerView mList;
|
||||
Toolbar mBar;
|
||||
private FileListAdapter mAdapter;
|
||||
List<FileListEntity> mData = new ArrayList<>();
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_multi;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.download(this).register();
|
||||
setTitle("多任务下载");
|
||||
mData.addAll(getModule(DownloadModule.class).createGroupTestList());
|
||||
mData.addAll(getModule(DownloadModule.class).createMultiTestList());
|
||||
mData.addAll(getModule(DownloadModule.class).createM3u8TestList());
|
||||
mAdapter = new FileListAdapter(this, mData);
|
||||
mList = getBinding().list;
|
||||
mBar = findViewById(R.id.toolbar);
|
||||
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.num:
|
||||
DownloadNumDialog dialog = new DownloadNumDialog(this);
|
||||
dialog.show(getSupportFragmentManager(), "download_num");
|
||||
break;
|
||||
case R.id.stop_all:
|
||||
//Aria.download(this).stopAllTask();
|
||||
List<AbsEntity> list = Aria.download(this).getTotalTaskList();
|
||||
for (AbsEntity entity : list){
|
||||
Aria.download(this).load(entity.getId()).cancel(true);
|
||||
}
|
||||
//Aria.download(this).removeAllTask(false);
|
||||
break;
|
||||
case R.id.turn:
|
||||
startActivity(new Intent(this, MultiDownloadActivity.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onWait void taskWait(DownloadTask task) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
}
|
||||
|
||||
@Download.onTaskStart void taskStart(DownloadTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), false);
|
||||
}
|
||||
|
||||
@Download.onTaskResume void taskResume(DownloadTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), false);
|
||||
}
|
||||
|
||||
@Download.onTaskStop void taskStop(DownloadTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@Download.onTaskCancel void taskCancel(DownloadTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@Download.onTaskFail void taskFail(DownloadTask task) {
|
||||
if (task == null || task.getEntity() == null){
|
||||
return;
|
||||
}
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@Download.onTaskComplete void taskComplete(DownloadTask task) {
|
||||
Log.d(TAG, FileUtil.getFileMD5(new File(task.getFilePath())));
|
||||
}
|
||||
|
||||
//############################### 任务组 ##############################
|
||||
@DownloadGroup.onTaskComplete void groupTaskComplete(DownloadGroupTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStart void groupTaskStart(DownloadGroupTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), false);
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskResume void groupTaskResume(DownloadGroupTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), false);
|
||||
}
|
||||
|
||||
@DownloadGroup.onWait void groupTaskWait(DownloadGroupTask task) {
|
||||
ALog.d(TAG, String.format("group【%s】wait---", task.getTaskName()));
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskStop void groupTaskStop(DownloadGroupTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
Log.d(TAG, String.format("group【%s】stop", task.getTaskName()));
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskCancel void groupTaskCancel(DownloadGroupTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskFail void groupTaskFail(DownloadGroupTask task) {
|
||||
if (task == null) {
|
||||
return;
|
||||
}
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
Log.d(TAG, String.format("group【%s】fail", task.getTaskName()));
|
||||
}
|
||||
|
||||
@DownloadGroup.onTaskComplete void taskComplete(DownloadGroupTask task) {
|
||||
mAdapter.updateBtState(task.getKey(), true);
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == DownloadNumDialog.RESULT_CODE) {
|
||||
Aria.get(this).getDownloadConfig().setMaxTaskNum(Integer.parseInt(data + ""));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.service;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import com.arialyy.simple.R;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/1/18.
|
||||
*/
|
||||
public class DownloadNotification {
|
||||
|
||||
private NotificationManager mManager;
|
||||
private Context mContext;
|
||||
private NotificationCompat.Builder mBuilder;
|
||||
private static final int mNotifiyId = 0;
|
||||
|
||||
public DownloadNotification(Context context) {
|
||||
mContext = context;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mBuilder = new NotificationCompat.Builder(mContext);
|
||||
mBuilder.setContentTitle("Aria Download Test")
|
||||
.setContentText("进度条")
|
||||
.setProgress(100, 0, false)
|
||||
.setSmallIcon(R.mipmap.ic_launcher);
|
||||
mManager.notify(mNotifiyId, mBuilder.build());
|
||||
}
|
||||
|
||||
public void upload(int progress){
|
||||
if (mBuilder != null) {
|
||||
mBuilder.setProgress(100, progress, false);
|
||||
mManager.notify(mNotifiyId, mBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.download.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/4/5.
|
||||
* 在服务中使用 Aria进行下载
|
||||
*/
|
||||
public class DownloadService extends Service {
|
||||
private static final String DOWNLOAD_URL =
|
||||
"http://rs.0.gaoshouyou.com/d/df/db/03df9eab61dbc48a5939f671f05f1cdf.apk";
|
||||
private DownloadNotification mNotify;
|
||||
|
||||
@Nullable @Override public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
@Override public void onCreate() {
|
||||
super.onCreate();
|
||||
mNotify = new DownloadNotification(getApplicationContext());
|
||||
Aria.download(this).register();
|
||||
Aria.download(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/service_task.apk")
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void onDestroy() {
|
||||
super.onDestroy();
|
||||
Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
@Download.onNoSupportBreakPoint public void onNoSupportBreakPoint(DownloadTask task) {
|
||||
T.showShort(getApplicationContext(), "该下载链接不支持断点");
|
||||
}
|
||||
|
||||
@Download.onTaskStart public void onTaskStart(DownloadTask task) {
|
||||
T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",开始下载");
|
||||
}
|
||||
|
||||
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
|
||||
T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",停止下载");
|
||||
}
|
||||
|
||||
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
|
||||
T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",取消下载");
|
||||
}
|
||||
|
||||
@Download.onTaskFail public void onTaskFail(DownloadTask task) {
|
||||
T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",下载失败");
|
||||
}
|
||||
|
||||
@Download.onTaskComplete public void onTaskComplete(DownloadTask task) {
|
||||
T.showShort(getApplicationContext(), task.getDownloadEntity().getFileName() + ",下载完成");
|
||||
mNotify.upload(100);
|
||||
}
|
||||
|
||||
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
|
||||
long len = task.getFileSize();
|
||||
int p = (int) (task.getCurrentProgress() * 100 / len);
|
||||
mNotify.upload(p);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.arialyy.simple.core.test;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityTestBinding;
|
||||
import com.arialyy.simple.modlue.AnyRunnModule;
|
||||
|
||||
/**
|
||||
* Created by laoyuyu on 2018/4/13.
|
||||
*/
|
||||
|
||||
public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
|
||||
AnyRunnModule module;
|
||||
String[] urls;
|
||||
int index = 0;
|
||||
//String URL = "http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk";
|
||||
//String URL = "http://58.213.157.242:8081/sims_file/rest/v1/file/mshd_touchscreen_ms/guideFile/41c33556-dc4a-4d78-bb76-b9f627f94448.mp4/%E5%85%AB%E5%8D%A6%E6%B4%B2%E5%8D%97%E4%BA%AC%E5%86%9C%E4%B8%9A%E5%98%89%E5%B9%B4%E5%8D%8E0511.mp4";
|
||||
//String URL = "http://d1.showself.com/download/showself_android-s236279_release.apk";
|
||||
//String URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk";
|
||||
//private final String URL = "ftp://192.168.29.140:21/download/AriaPrj.rar";
|
||||
//String URL = "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe";
|
||||
//String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk";
|
||||
//String URL = "ftps://192.168.29.140:990/download/SDK_Demo-release.apk";
|
||||
//String URL = "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176";
|
||||
//String URL = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv";
|
||||
//String URL = "https://app-dl.byfen.com//app//201810//ef0400d637e768e9c630b4d38633ee06.zip";
|
||||
String URL = "ftps://9.9.9.59:990/download/SDK_Demo-release.apk";
|
||||
//private String URL = "https://www.bilibili.com/bangumi/play/ep77693";
|
||||
//private String URL = "http://cn-hbsjz-cmcc-v-03.acgvideo.com/upgcxcode/63/82/5108263/5108263-1-80.flv?expires=1530178500&platform=pc&ssig=vr7gLl0duyqWqSMnIpzaDA&oi=3746029570&nfa=BpfiWF+i4mNW8KzjZFHzBQ==&dynamic=1&hfa=2030547937&hfb=Yjk5ZmZjM2M1YzY4ZjAwYTMzMTIzYmIyNWY4ODJkNWI=&trid=3476be01a9254115b15f8cc7198600fe&nfc=1";
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_test;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
Aria.init(this);
|
||||
mBar.setVisibility(View.GONE);
|
||||
module = new AnyRunnModule(this);
|
||||
urls = getResources().getStringArray(R.array.group_urls);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
//module.create(URL);
|
||||
module.startFtp(URL);
|
||||
break;
|
||||
case R.id.stop:
|
||||
module.stop(URL);
|
||||
break;
|
||||
case R.id.cancel:
|
||||
module.cancel(URL);
|
||||
//String newUrl = "ftp://192.168.29.140:21/download/11SDK_Demo-release.apk";
|
||||
//Aria.download(this)
|
||||
// .loadFtp(URL)
|
||||
// .updateUrl(newUrl)
|
||||
// .login("lao", "123456")
|
||||
// .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/")
|
||||
// .create();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
module.unRegister();
|
||||
}
|
||||
}
|
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.upload;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Upload;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.processor.FtpInterceptHandler;
|
||||
import com.arialyy.aria.core.processor.IFtpUploadInterceptor;
|
||||
import com.arialyy.aria.core.task.UploadTask;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/28. Ftp 文件上传demo
|
||||
*/
|
||||
public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
private final int OPEN_FILE_MANAGER_CODE = 0xB1;
|
||||
private String mFilePath;
|
||||
private String mUrl;
|
||||
private UploadModule mModule;
|
||||
private long mTaskId = -1;
|
||||
private String user = "lao", pwd = "123456";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
setTile("D_FTP 文件上传");
|
||||
super.init(savedInstanceState);
|
||||
Aria.upload(this).register();
|
||||
|
||||
setUI();
|
||||
}
|
||||
|
||||
private void setUI() {
|
||||
mModule = ViewModelProviders.of(this).get(UploadModule.class);
|
||||
mModule.getFtpInfo(this).observe(this, new Observer<UploadEntity>() {
|
||||
@Override public void onChanged(@Nullable UploadEntity entity) {
|
||||
if (entity != null) {
|
||||
mFilePath = entity.getFilePath();
|
||||
mUrl = entity.getUrl();
|
||||
mTaskId = entity.getId();
|
||||
getBinding().pl.setInfo(entity);
|
||||
}
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.upload(this)
|
||||
.loadFtp(mFilePath)
|
||||
.setUploadUrl(mUrl)
|
||||
.option(getOption())
|
||||
.ignoreFilePathOccupy()
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.upload(this).loadFtp(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.upload(this)
|
||||
.loadFtp(mTaskId)
|
||||
.option(getOption())
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.upload(this).loadFtp(mTaskId).cancel(true);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_single;
|
||||
}
|
||||
|
||||
private void upload() {
|
||||
List<String> paths = new ArrayList<>();
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/1.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/2.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/3.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/4.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/5.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/6.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/7.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/8.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/9.jpg");
|
||||
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/10.jpg");
|
||||
for (String path : paths) {
|
||||
Aria.upload(this)
|
||||
.loadFtp(path)
|
||||
.setUploadUrl(mUrl)
|
||||
.option(getOption())
|
||||
.forceUpload()
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
private FtpOption getOption() {
|
||||
FtpOption option = new FtpOption();
|
||||
option.login(user, pwd);
|
||||
option.setUploadInterceptor(new FtpUploadInterceptor());
|
||||
return option;
|
||||
}
|
||||
|
||||
@Upload.onWait
|
||||
void onWait(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onPre
|
||||
protected void onPre(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskStart
|
||||
void taskStart(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskRunning
|
||||
protected void running(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskResume
|
||||
void taskResume(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskStop
|
||||
void taskStop(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskCancel
|
||||
void taskCancel(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
mTaskId = -1;
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskFail
|
||||
void taskFail(UploadTask task, Exception e) {
|
||||
ALog.d(TAG, "fail");
|
||||
Toast.makeText(this, getString(R.string.upload_fail), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
if (task != null && task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskComplete
|
||||
void taskComplete(UploadTask task) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.upload_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getEntity().getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
private static class FtpUploadInterceptor implements IFtpUploadInterceptor {
|
||||
@Override public FtpInterceptHandler onIntercept(UploadEntity entity, List<String> fileList) {
|
||||
FtpInterceptHandler.Builder builder = new FtpInterceptHandler.Builder();
|
||||
//builder.coverServerFile(); // 覆盖远端同名文件
|
||||
builder.resetFileName("test12.zip"); //修改上传到远端服务器的文件名
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.upload;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import com.arialyy.annotations.Upload;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.common.RequestEnum;
|
||||
import com.arialyy.aria.core.task.UploadTask;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.util.FileUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/2/9.
|
||||
*/
|
||||
public class HttpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
private static final String TAG = "HttpUploadActivity";
|
||||
|
||||
//private final String FILE_PATH = "/mnt/sdcard/QQMusic-import-1.2.1.zip";
|
||||
private final String FILE_PATH = "/mnt/sdcard/update.jpg";
|
||||
//private final String FILE_PATH =
|
||||
// Environment.getExternalStorageDirectory().getPath() + "/Download/QQMusic-import-1.2.1.zip";
|
||||
private UploadEntity mEntity;
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_single;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
setTile("D_HTTP 上传");
|
||||
super.init(savedInstanceState);
|
||||
Aria.upload(this).getTaskList();
|
||||
|
||||
mEntity = Aria.upload(this).getFirstUploadEntity(FILE_PATH);
|
||||
if (mEntity == null) {
|
||||
mEntity = new UploadEntity();
|
||||
mEntity.setFilePath(FILE_PATH);
|
||||
}
|
||||
getBinding().pl.setInfo(mEntity);
|
||||
Aria.upload(this).register();
|
||||
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
upload();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
HttpUploadActivity.this.stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
upload();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void upload() {
|
||||
HttpOption option = new HttpOption();
|
||||
option.setRequestType(RequestEnum.POST);
|
||||
option.setParam("params", "bbbbbbbb");
|
||||
option.setAttachment("file");
|
||||
Aria.upload(HttpUploadActivity.this).load(FILE_PATH)
|
||||
//.setUploadUrl("http://lib-test.xzxyun.com:8042/Api/upload?data={\"type\":\"1\",\"fileType\":\".apk\"}")
|
||||
.setUploadUrl("http://172.16.0.91:5000/upload/")
|
||||
.ignoreFilePathOccupy()
|
||||
//.setTempUrl("http://192.168.1.6:8080/upload/sign_file/").setAttachment("file")
|
||||
//.addHeader("iplanetdirectorypro", "11a09102fb934ad0bc206f9c611d7933")
|
||||
.option(option)
|
||||
.create();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.upload(this).load(mEntity.getId()).stop();
|
||||
}
|
||||
}
|
||||
|
||||
void remove() {
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.upload(this).load(mEntity.getId()).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onPre public void onPre(UploadTask task) {
|
||||
}
|
||||
|
||||
@Upload.onTaskStart public void taskStart(UploadTask task) {
|
||||
ALog.d(TAG,
|
||||
"upload create,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Upload.onTaskStop public void taskStop(UploadTask task) {
|
||||
ALog.d(TAG, "upload stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
|
||||
ALog.d(TAG, "upload cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
|
||||
ALog.d(TAG, "running, P = " + task.getPercent());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
|
||||
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
|
||||
ALog.d(TAG, "上传完成");
|
||||
ALog.d(TAG, "上传成功服务端返回数据(如果有的话):" + task.getEntity().getResponseStr());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.core.upload;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import com.arialyy.annotations.Upload;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.SFtpOption;
|
||||
import com.arialyy.aria.core.task.UploadTask;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.widget.ProgressLayout;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/28. Ftp 文件上传demo
|
||||
*/
|
||||
public class SFtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
private final int OPEN_FILE_MANAGER_CODE = 0xB1;
|
||||
private String mFilePath;
|
||||
private String mUrl;
|
||||
private UploadModule mModule;
|
||||
private long mTaskId = -1;
|
||||
private String user = "tester", pwd = "password";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
setTile("D_FTP 文件上传");
|
||||
super.init(savedInstanceState);
|
||||
Aria.upload(this).register();
|
||||
|
||||
setUI();
|
||||
}
|
||||
|
||||
private void setUI() {
|
||||
mModule = ViewModelProviders.of(this).get(UploadModule.class);
|
||||
mModule.getSFtpInfo(this).observe(this, new Observer<UploadEntity>() {
|
||||
@Override public void onChanged(@Nullable UploadEntity entity) {
|
||||
if (entity != null) {
|
||||
mTaskId = entity.getId();
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
getBinding().pl.setInfo(entity);
|
||||
}
|
||||
}
|
||||
});
|
||||
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
|
||||
@Override public void create(View v, AbsEntity entity) {
|
||||
mTaskId = Aria.upload(this)
|
||||
.loadFtp(mFilePath)
|
||||
.setUploadUrl(mUrl)
|
||||
.sftpOption(getOption())
|
||||
.ignoreFilePathOccupy()
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override public void stop(View v, AbsEntity entity) {
|
||||
Aria.upload(this).loadFtp(mTaskId).stop();
|
||||
}
|
||||
|
||||
@Override public void resume(View v, AbsEntity entity) {
|
||||
Aria.upload(this)
|
||||
.loadFtp(mTaskId)
|
||||
.sftpOption(getOption())
|
||||
.resume();
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.upload(this).loadFtp(mTaskId).cancel(false);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_single;
|
||||
}
|
||||
|
||||
private SFtpOption getOption() {
|
||||
SFtpOption option = new SFtpOption();
|
||||
option.login(user, pwd);
|
||||
return option;
|
||||
}
|
||||
|
||||
@Upload.onWait
|
||||
void onWait(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onPre
|
||||
protected void onPre(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskStart
|
||||
void taskStart(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskRunning
|
||||
protected void running(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskResume
|
||||
void taskResume(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskStop
|
||||
void taskStop(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskCancel
|
||||
void taskCancel(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
mTaskId = -1;
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskFail
|
||||
void taskFail(UploadTask task, Exception e) {
|
||||
ALog.d(TAG, "fail");
|
||||
Toast.makeText(this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
if (task != null && task.getKey().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskComplete
|
||||
void taskComplete(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getEntity().getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.upload;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
|
||||
public class UploadModule extends BaseViewModule {
|
||||
private final String FTP_URL_KEY = "FTP_URL_KEY";
|
||||
private final String FTP_PATH_KEY = "FTP_PATH_KEY";
|
||||
private MutableLiveData<UploadEntity> liveData = new MutableLiveData<>();
|
||||
UploadEntity uploadInfo;
|
||||
|
||||
/**
|
||||
* 获取Ftp上传信息
|
||||
*/
|
||||
LiveData<UploadEntity> getFtpInfo(Context context) {
|
||||
//String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.72:2121/aab/你好");
|
||||
//String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
|
||||
// Environment.getExternalStorageDirectory().getPath() + "/Download/AndroidAria.db");
|
||||
String url = "ftp://192.168.0.105:2121/aab/你好";
|
||||
String filePath = "/mnt/sdcard/QQMusic-import-1.2.1.zip";
|
||||
|
||||
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);
|
||||
if (entity != null) {
|
||||
uploadInfo = entity;
|
||||
AppUtil.setConfigValue(context, FTP_URL_KEY, uploadInfo.getUrl());
|
||||
AppUtil.setConfigValue(context, FTP_PATH_KEY, uploadInfo.getFilePath());
|
||||
} else {
|
||||
uploadInfo = new UploadEntity();
|
||||
uploadInfo.setUrl(url);
|
||||
uploadInfo.setFilePath(filePath);
|
||||
}
|
||||
|
||||
liveData.postValue(uploadInfo);
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Ftp上传信息
|
||||
*/
|
||||
LiveData<UploadEntity> getSFtpInfo(Context context) {
|
||||
//String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.72:2121/aab/你好");
|
||||
//String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
|
||||
// Environment.getExternalStorageDirectory().getPath() + "/Download/AndroidAria.db");
|
||||
String url = "ftp://9.9.9.72:22/aab/你好";
|
||||
String filePath = "/mnt/sdcard/QQMusic-import-1.2.1.zip";
|
||||
|
||||
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);
|
||||
if (entity != null) {
|
||||
uploadInfo = entity;
|
||||
AppUtil.setConfigValue(context, FTP_URL_KEY, uploadInfo.getUrl());
|
||||
AppUtil.setConfigValue(context, FTP_PATH_KEY, uploadInfo.getFilePath());
|
||||
} else {
|
||||
uploadInfo = new UploadEntity();
|
||||
uploadInfo.setUrl(url);
|
||||
uploadInfo.setFilePath(filePath);
|
||||
}
|
||||
|
||||
liveData.postValue(uploadInfo);
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新Url
|
||||
*/
|
||||
void updateFtpUrl(Context context, String url) {
|
||||
uploadInfo.setUrl(url);
|
||||
AppUtil.setConfigValue(context, FTP_URL_KEY, url);
|
||||
liveData.postValue(uploadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件路径
|
||||
*/
|
||||
void updateFtpFilePath(Context context, String filePath) {
|
||||
uploadInfo.setFilePath(filePath);
|
||||
AppUtil.setConfigValue(context, FTP_PATH_KEY, filePath);
|
||||
liveData.postValue(uploadInfo);
|
||||
}
|
||||
}
|
141
app/src/main/java/com/arialyy/simple/modlue/AnyRunnModule.java
Normal file
141
app/src/main/java/com/arialyy/simple/modlue/AnyRunnModule.java
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.modlue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by laoyuyu on 2018/4/13.
|
||||
*/
|
||||
|
||||
public class AnyRunnModule {
|
||||
String TAG = "AnyRunnModule";
|
||||
private Context mContext;
|
||||
private String mUrl;
|
||||
private DownloadEntity mEntity;
|
||||
|
||||
public AnyRunnModule(Context context) {
|
||||
Aria.download(this).register();
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Download.onWait void onWait(DownloadTask task) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
}
|
||||
|
||||
@Download.onPre protected void onPre(DownloadTask task) {
|
||||
Log.d(TAG, "onPre");
|
||||
}
|
||||
|
||||
@Download.onTaskStart void taskStart(DownloadTask task) {
|
||||
Log.d(TAG, "onPreStart");
|
||||
}
|
||||
|
||||
@Download.onTaskRunning protected void running(DownloadTask task) {
|
||||
Log.d(TAG, "running;Percent = " + task.getPercent());
|
||||
}
|
||||
|
||||
@Download.onTaskResume void taskResume(DownloadTask task) {
|
||||
Log.d(TAG, "resume");
|
||||
}
|
||||
|
||||
@Download.onTaskStop void taskStop(DownloadTask task) {
|
||||
Log.d(TAG, "stop");
|
||||
}
|
||||
|
||||
@Download.onTaskCancel void taskCancel(DownloadTask task) {
|
||||
Log.d(TAG, "cancel");
|
||||
}
|
||||
|
||||
@Download.onTaskFail void taskFail(DownloadTask task) {
|
||||
Log.d(TAG, "fail");
|
||||
}
|
||||
|
||||
@Download.onTaskComplete void taskComplete(DownloadTask task) {
|
||||
L.d(TAG, "path ==> " + task.getDownloadEntity().getFilePath());
|
||||
L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getFilePath())));
|
||||
}
|
||||
|
||||
public void start(String url) {
|
||||
mUrl = url;
|
||||
if (mEntity == null) {
|
||||
mEntity = Aria.download(this).getFirstDownloadEntity(url);
|
||||
}
|
||||
if (!AppUtil.chekEntityValid(mEntity)) {
|
||||
|
||||
String path = Environment.getExternalStorageDirectory().getPath() + "/mmm2.mp4";
|
||||
Aria.download(this)
|
||||
.load(url)
|
||||
.setFilePath(path)
|
||||
.resetState()
|
||||
.create();
|
||||
} else {
|
||||
Aria.download(this).load(mEntity.getId()).resume();
|
||||
}
|
||||
}
|
||||
|
||||
public void startFtp(String url) {
|
||||
mUrl = url;
|
||||
|
||||
if (mEntity == null) {
|
||||
mEntity = Aria.download(this).getFirstDownloadEntity(url);
|
||||
}
|
||||
if (!AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this)
|
||||
.loadFtp(url)
|
||||
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/Download/")
|
||||
.option(getFtpOption())
|
||||
.create();
|
||||
} else {
|
||||
Aria.download(this).load(mEntity.getId()).resume();
|
||||
}
|
||||
}
|
||||
|
||||
private FtpOption getFtpOption() {
|
||||
FtpOption option = new FtpOption();
|
||||
option.setStorePath("/mnt/sdcard/Download/server.crt")
|
||||
.setAlias("www.laoyuyu.me")
|
||||
.setStorePass("123456");
|
||||
return option;
|
||||
}
|
||||
|
||||
public void stop(String url) {
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this).load(mEntity.getId()).stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel(String url) {
|
||||
if (AppUtil.chekEntityValid(mEntity)) {
|
||||
Aria.download(this).load(mEntity.getId()).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegister() {
|
||||
Aria.download(this).unRegister();
|
||||
}
|
||||
}
|
123
app/src/main/java/com/arialyy/simple/modlue/CommonModule.java
Normal file
123
app/src/main/java/com/arialyy/simple/modlue/CommonModule.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.modlue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.MainActivity;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用Modle块
|
||||
*/
|
||||
public class CommonModule extends BaseViewModule {
|
||||
|
||||
private int mPosition;
|
||||
private MutableLiveData<List<NormalTo>> mLiveData = new MutableLiveData<>();
|
||||
|
||||
public CommonModule() {
|
||||
}
|
||||
|
||||
public void startNextActivity(Context context, NormalTo to, Class clazz) {
|
||||
Intent intent = new Intent(context, clazz);
|
||||
intent.putExtra(MainActivity.KEY_MAIN_DATA, to);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public LiveData<List<NormalTo>> getComponentData(Context context) {
|
||||
List<NormalTo> list = new ArrayList<>();
|
||||
String[] titles = context.getResources().getStringArray(R.array.component_items);
|
||||
int[] icons = new int[] {
|
||||
R.drawable.ic_fragment,
|
||||
R.drawable.ic_dialog,
|
||||
R.drawable.ic_fragment
|
||||
};
|
||||
int i = 0;
|
||||
for (String title : titles) {
|
||||
NormalTo to = new NormalTo();
|
||||
to.icon = icons[i];
|
||||
to.title = title;
|
||||
i++;
|
||||
list.add(to);
|
||||
}
|
||||
mLiveData.postValue(list);
|
||||
return mLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* http下载功能页面数据
|
||||
*/
|
||||
public LiveData<List<NormalTo>> getDownloadData(Context context) {
|
||||
List<NormalTo> list = new ArrayList<>();
|
||||
String[] titles = context.getResources().getStringArray(R.array.download_items);
|
||||
int[] icons = new int[] {
|
||||
R.drawable.ic_http,
|
||||
R.drawable.ic_http_group,
|
||||
R.drawable.ic_top,
|
||||
R.drawable.ic_kotlin,
|
||||
R.drawable.ic_server,
|
||||
R.drawable.ic_windows
|
||||
};
|
||||
int i = 0;
|
||||
for (String title : titles) {
|
||||
NormalTo to = new NormalTo();
|
||||
to.icon = icons[i];
|
||||
to.title = title;
|
||||
i++;
|
||||
list.add(to);
|
||||
}
|
||||
mLiveData.postValue(list);
|
||||
return mLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页数据
|
||||
*/
|
||||
public LiveData<List<NormalTo>> getMainData(Context context) {
|
||||
List<NormalTo> list = new ArrayList<>();
|
||||
String[] titles = context.getResources().getStringArray(R.array.main_items);
|
||||
String[] descs = context.getResources().getStringArray(R.array.main_items_desc);
|
||||
int[] icons = new int[] {
|
||||
R.drawable.ic_http,
|
||||
R.drawable.ic_http,
|
||||
R.drawable.ic_http_group,
|
||||
R.drawable.ic_ftp,
|
||||
R.drawable.ic_ftp_dir,
|
||||
R.drawable.ic_ftp,
|
||||
R.drawable.ic_ts,
|
||||
R.drawable.ic_live,
|
||||
R.drawable.ic_sftp,
|
||||
R.drawable.ic_sftp
|
||||
};
|
||||
int i = 0;
|
||||
for (String title : titles) {
|
||||
NormalTo to = new NormalTo();
|
||||
to.icon = icons[i];
|
||||
to.title = title;
|
||||
to.desc = descs[i];
|
||||
i++;
|
||||
list.add(to);
|
||||
}
|
||||
mLiveData.postValue(list);
|
||||
return mLiveData;
|
||||
}
|
||||
}
|
57
app/src/main/java/com/arialyy/simple/to/NormalTo.java
Normal file
57
app/src/main/java/com/arialyy/simple/to/NormalTo.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.to;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* 简单列表对象
|
||||
*/
|
||||
public class NormalTo implements Parcelable {
|
||||
public int icon;
|
||||
public String title;
|
||||
public String desc;
|
||||
|
||||
public NormalTo() {
|
||||
}
|
||||
|
||||
@Override public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.icon);
|
||||
dest.writeString(this.title);
|
||||
dest.writeString(this.desc);
|
||||
}
|
||||
|
||||
protected NormalTo(Parcel in) {
|
||||
this.icon = in.readInt();
|
||||
this.title = in.readString();
|
||||
this.desc = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<NormalTo> CREATOR = new Creator<NormalTo>() {
|
||||
@Override public NormalTo createFromParcel(Parcel source) {
|
||||
return new NormalTo(source);
|
||||
}
|
||||
|
||||
@Override public NormalTo[] newArray(int size) {
|
||||
return new NormalTo[size];
|
||||
}
|
||||
};
|
||||
}
|
20
app/src/main/java/com/arialyy/simple/to/PeerIndex.java
Normal file
20
app/src/main/java/com/arialyy/simple/to/PeerIndex.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.to;
|
||||
|
||||
public class PeerIndex {
|
||||
public int index;
|
||||
}
|
116
app/src/main/java/com/arialyy/simple/util/AppUtil.java
Normal file
116
app/src/main/java/com/arialyy/simple/util/AppUtil.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import androidx.core.content.FileProvider;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import com.arialyy.simple.BuildConfig;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AppUtil {
|
||||
private static final String TAG = "AppUtil";
|
||||
private static final String ARIA_SHARE_PRE_KEY = "ARIA_SHARE_PRE_KEY";
|
||||
|
||||
/**
|
||||
* 检查实体是否有效
|
||||
*
|
||||
* @return true 实体有效
|
||||
*/
|
||||
public static boolean chekEntityValid(AbsEntity entity) {
|
||||
return entity != null && entity.getId() != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* http下载示例代码
|
||||
*/
|
||||
public static File getHelpCode(Context context, String fileName) throws IOException {
|
||||
String path = String.format("%s/code/%s", context.getFilesDir().getPath(), fileName);
|
||||
File ftpCode = new File(path);
|
||||
if (!ftpCode.exists()) {
|
||||
FileUtil.createFile(ftpCode);
|
||||
FileUtil.createFileFormInputStream(context.getAssets()
|
||||
.open(String.format("help_code/%s", fileName)),
|
||||
path);
|
||||
}
|
||||
return ftpCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取配置文件字段
|
||||
*
|
||||
* @param key key
|
||||
* @param defStr 默认字符串
|
||||
*/
|
||||
public static String getConfigValue(Context context, String key, String defStr) {
|
||||
SharedPreferences preferences =
|
||||
context.getSharedPreferences(ARIA_SHARE_PRE_KEY, Context.MODE_PRIVATE);
|
||||
return preferences.getString(key, defStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* set配置文件字段
|
||||
*
|
||||
* @param key key
|
||||
* @param value 需要保存的字符串
|
||||
*/
|
||||
public static void setConfigValue(Context context, String key, String value) {
|
||||
SharedPreferences preferences =
|
||||
context.getSharedPreferences(ARIA_SHARE_PRE_KEY, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putString(key, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用系统文件管理器选择文件
|
||||
*
|
||||
* @param file 不能是文件夹
|
||||
* @param mineType android 可用的minetype
|
||||
* @param requestCode 请求码
|
||||
*/
|
||||
public static void chooseFile(Activity activity, File file, String mineType, int requestCode) {
|
||||
if (file.isDirectory()) {
|
||||
ALog.e(TAG, "不能选择文件夹");
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
Uri uri;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
uri = FileProvider.getUriForFile(activity.getApplicationContext(),
|
||||
BuildConfig.APPLICATION_ID + ".provider",
|
||||
file);
|
||||
} else {
|
||||
uri = Uri.fromFile(file);
|
||||
}
|
||||
|
||||
intent.setDataAndType(uri, TextUtils.isEmpty(mineType) ? "*/*" : mineType);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
activity.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
}
|
76
app/src/main/java/com/arialyy/simple/widget/CodeView.java
Normal file
76
app/src/main/java/com/arialyy/simple/widget/CodeView.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.core.FullScreenCodeActivity;
|
||||
import com.pddstudio.highlightjs.HighlightJsView;
|
||||
import com.pddstudio.highlightjs.models.Language;
|
||||
import com.pddstudio.highlightjs.models.Theme;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 代码高亮控件
|
||||
*/
|
||||
public class CodeView extends RelativeLayout {
|
||||
|
||||
private HighlightJsView mCodeView;
|
||||
private File mSourceFile;
|
||||
|
||||
public CodeView(Context context) {
|
||||
super(context, null);
|
||||
}
|
||||
|
||||
public CodeView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_code_demo, this, true);
|
||||
mCodeView = findViewById(R.id.js_view);
|
||||
mCodeView.setHighlightLanguage(Language.JAVA);
|
||||
mCodeView.setTheme(Theme.ANDROID_STUDIO);
|
||||
mCodeView.setZoomSupportEnabled(true);
|
||||
findViewById(R.id.full_screen).setOnClickListener(new OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
// 横屏显示代码
|
||||
Intent intent = new Intent(getContext(), FullScreenCodeActivity.class);
|
||||
intent.putExtra(FullScreenCodeActivity.KEY_FILE_PATH, mSourceFile.getPath());
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setSource(File sourceFile) {
|
||||
mSourceFile = sourceFile;
|
||||
mCodeView.setSource(sourceFile);
|
||||
}
|
||||
|
||||
|
||||
public void setSource(File sourceFile, Language language) {
|
||||
mSourceFile = sourceFile;
|
||||
mCodeView.setHighlightLanguage(language);
|
||||
mCodeView.setSource(sourceFile);
|
||||
}
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ProgressBar;
|
||||
import com.arialyy.simple.R;
|
||||
|
||||
public class HorizontalProgressBarWithNumber extends ProgressBar {
|
||||
private static final int DEFAULT_TEXT_SIZE = 10;
|
||||
private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;
|
||||
private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da;
|
||||
private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2;
|
||||
private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2;
|
||||
private static final int DEFAULT_SIZE_TEXT_OFFSET = 10;
|
||||
/**
|
||||
* painter of all drawing things
|
||||
*/
|
||||
protected Paint mPaint = new Paint();
|
||||
/**
|
||||
* color of progress number
|
||||
*/
|
||||
protected int mTextColor = DEFAULT_TEXT_COLOR;
|
||||
/**
|
||||
* size of text (sp)
|
||||
*/
|
||||
protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
|
||||
/**
|
||||
* offset of draw progress
|
||||
*/
|
||||
protected int mTextOffset = dp2px(DEFAULT_SIZE_TEXT_OFFSET);
|
||||
/**
|
||||
* height of reached progress bar
|
||||
*/
|
||||
protected int mReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR);
|
||||
/**
|
||||
* color of reached bar
|
||||
*/
|
||||
protected int mReachedBarColor = DEFAULT_TEXT_COLOR;
|
||||
/**
|
||||
* color of unreached bar
|
||||
*/
|
||||
protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR;
|
||||
/**
|
||||
* height of unreached progress bar
|
||||
*/
|
||||
protected int mUnReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR);
|
||||
/**
|
||||
* view width except padding
|
||||
*/
|
||||
protected int mRealWidth;
|
||||
protected boolean mIfDrawText = true;
|
||||
protected static final int VISIBLE = 0;
|
||||
|
||||
public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
obtainStyledAttributes(attrs);
|
||||
mPaint.setTextSize(mTextSize);
|
||||
mPaint.setColor(mTextColor);
|
||||
}
|
||||
|
||||
@Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int height = measureHeight(heightMeasureSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();
|
||||
}
|
||||
|
||||
private int measureHeight(int measureSpec) {
|
||||
int result = 0;
|
||||
int specMode = MeasureSpec.getMode(measureSpec);
|
||||
int specSize = MeasureSpec.getSize(measureSpec);
|
||||
if (specMode == MeasureSpec.EXACTLY) {
|
||||
result = specSize;
|
||||
} else {
|
||||
float textHeight = (mPaint.descent() - mPaint.ascent());
|
||||
result = (int) (getPaddingTop() + getPaddingBottom() + Math.max(
|
||||
Math.max(mReachedProgressBarHeight, mUnReachedProgressBarHeight), Math.abs(textHeight)));
|
||||
if (specMode == MeasureSpec.AT_MOST) {
|
||||
result = Math.min(result, specSize);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the styled attributes
|
||||
*/
|
||||
private void obtainStyledAttributes(AttributeSet attrs) {
|
||||
// init values from custom attributes
|
||||
final TypedArray attributes =
|
||||
getContext().obtainStyledAttributes(attrs, R.styleable.HorizontalProgressBarWithNumber);
|
||||
mTextColor =
|
||||
attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_text_color,
|
||||
DEFAULT_TEXT_COLOR);
|
||||
mTextSize = (int) attributes.getDimension(
|
||||
R.styleable.HorizontalProgressBarWithNumber_progress_text_size, mTextSize);
|
||||
mReachedBarColor =
|
||||
attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_reached_color,
|
||||
mTextColor);
|
||||
mUnReachedBarColor =
|
||||
attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_unreached_color,
|
||||
DEFAULT_COLOR_UNREACHED_COLOR);
|
||||
mReachedProgressBarHeight = (int) attributes.getDimension(
|
||||
R.styleable.HorizontalProgressBarWithNumber_progress_reached_bar_height,
|
||||
mReachedProgressBarHeight);
|
||||
mUnReachedProgressBarHeight = (int) attributes.getDimension(
|
||||
R.styleable.HorizontalProgressBarWithNumber_progress_unreached_bar_height,
|
||||
mUnReachedProgressBarHeight);
|
||||
mTextOffset = (int) attributes.getDimension(
|
||||
R.styleable.HorizontalProgressBarWithNumber_progress_text_offset, mTextOffset);
|
||||
int textVisible =
|
||||
attributes.getInt(R.styleable.HorizontalProgressBarWithNumber_progress_text_visibility,
|
||||
VISIBLE);
|
||||
if (textVisible != VISIBLE) {
|
||||
mIfDrawText = false;
|
||||
}
|
||||
attributes.recycle();
|
||||
}
|
||||
|
||||
@Override protected synchronized void onDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.translate(getPaddingLeft(), getHeight() / 2);
|
||||
boolean noNeedBg = false;
|
||||
float radio = getProgress() * 1.0f / getMax();
|
||||
float progressPosX = (int) (mRealWidth * radio);
|
||||
String text = getProgress() + "%";
|
||||
// mPaint.getTextBounds(text, 0, text.length(), mTextBound);
|
||||
float textWidth = mPaint.measureText(text);
|
||||
float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
|
||||
if (progressPosX + textWidth > mRealWidth) {
|
||||
progressPosX = mRealWidth - textWidth;
|
||||
noNeedBg = true;
|
||||
}
|
||||
// draw reached bar
|
||||
float endX = progressPosX - mTextOffset / 2;
|
||||
if (endX > 0) {
|
||||
mPaint.setColor(mReachedBarColor);
|
||||
mPaint.setStrokeWidth(mReachedProgressBarHeight);
|
||||
canvas.drawLine(0, 0, endX, 0, mPaint);
|
||||
}
|
||||
// draw progress bar
|
||||
// measure text bound
|
||||
if (mIfDrawText) {
|
||||
mPaint.setColor(mTextColor);
|
||||
canvas.drawText(text, progressPosX, -textHeight, mPaint);
|
||||
}
|
||||
// draw unreached bar
|
||||
if (!noNeedBg) {
|
||||
float start = progressPosX + mTextOffset / 2 + textWidth;
|
||||
mPaint.setColor(mUnReachedBarColor);
|
||||
mPaint.setStrokeWidth(mUnReachedProgressBarHeight);
|
||||
canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* dp 2 px
|
||||
*/
|
||||
protected int dp2px(int dpVal) {
|
||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
|
||||
getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
/**
|
||||
* sp 2 px
|
||||
*/
|
||||
protected int sp2px(int spVal) {
|
||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,
|
||||
getResources().getDisplayMetrics());
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2015/4/22.
|
||||
* 不带有滑动功能的ListView
|
||||
*/
|
||||
public class NoScrollListView extends ListView {
|
||||
public NoScrollListView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NoScrollListView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NoScrollListView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
|
||||
super.onMeasure(widthMeasureSpec, expandSpec);
|
||||
}
|
||||
}
|
267
app/src/main/java/com/arialyy/simple/widget/ProgressLayout.java
Normal file
267
app/src/main/java/com/arialyy/simple/widget/ProgressLayout.java
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.widget.AppCompatImageButton;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.AbsGroupEntity;
|
||||
import com.arialyy.aria.core.common.AbsNormalEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.simple.R;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 统一的进度布局
|
||||
*/
|
||||
public class ProgressLayout extends RelativeLayout implements View.OnClickListener {
|
||||
private final String TAG = "ProgressLayout";
|
||||
private TextView speedOrState, fileName, leftTime, fileSize;
|
||||
private HorizontalProgressBarWithNumber pb;
|
||||
private AppCompatImageButton delBt;
|
||||
private Button handleBt;
|
||||
private OnProgressLayoutBtListener listener;
|
||||
private AbsEntity entity;
|
||||
private int currentState;
|
||||
|
||||
public interface OnProgressLayoutBtListener {
|
||||
/**
|
||||
* 处理创建操作
|
||||
*/
|
||||
void create(View v, AbsEntity entity);
|
||||
|
||||
/**
|
||||
* 处理任务暂停的操作
|
||||
*/
|
||||
void stop(View v, AbsEntity entity);
|
||||
|
||||
/**
|
||||
* 处理恢复任务的操作
|
||||
*/
|
||||
void resume(View v, AbsEntity entity);
|
||||
|
||||
/**
|
||||
* 处理任务删除的操作
|
||||
*/
|
||||
void cancel(View v, AbsEntity entity);
|
||||
}
|
||||
|
||||
public ProgressLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ProgressLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, -1);
|
||||
}
|
||||
|
||||
public ProgressLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_progress_content, this, true);
|
||||
speedOrState = findViewById(R.id.speed_or_state);
|
||||
fileName = findViewById(R.id.file_name);
|
||||
leftTime = findViewById(R.id.left_time);
|
||||
fileSize = findViewById(R.id.file_size);
|
||||
pb = findViewById(R.id.pb);
|
||||
delBt = findViewById(R.id.del_bt);
|
||||
handleBt = findViewById(R.id.handle_bt);
|
||||
delBt.setOnClickListener(this);
|
||||
handleBt.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void setBtListener(OnProgressLayoutBtListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override public void onClick(View v) {
|
||||
if (listener == null) {
|
||||
ALog.e(TAG, "没有设置OnProgressLayoutBtListener");
|
||||
return;
|
||||
}
|
||||
if (entity == null) {
|
||||
ALog.d(TAG, "entity 为空,请设置信息");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (v.getId()) {
|
||||
case R.id.del_bt:
|
||||
listener.cancel(v, entity);
|
||||
initState();
|
||||
break;
|
||||
case R.id.handle_bt:
|
||||
handleTask(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void initState() {
|
||||
fileName.setText("-");
|
||||
leftTime.setText("");
|
||||
speedOrState.setText("");
|
||||
fileSize.setText("-/-");
|
||||
pb.setProgress(0);
|
||||
}
|
||||
|
||||
private void handleTask(View v) {
|
||||
switch (entity.getState()) {
|
||||
case IEntity.STATE_OTHER:
|
||||
case IEntity.STATE_FAIL:
|
||||
case IEntity.STATE_STOP:
|
||||
listener.resume(v, entity);
|
||||
break;
|
||||
case IEntity.STATE_COMPLETE:
|
||||
case IEntity.STATE_WAIT:
|
||||
if (entity.getId() != -1) {
|
||||
listener.resume(v, entity);
|
||||
} else {
|
||||
listener.create(v, entity);
|
||||
}
|
||||
break;
|
||||
case IEntity.STATE_PRE:
|
||||
case IEntity.STATE_POST_PRE:
|
||||
case IEntity.STATE_RUNNING:
|
||||
listener.stop(v, entity);
|
||||
break;
|
||||
default:
|
||||
listener.create(v, entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setInfo(AbsEntity entity) {
|
||||
this.entity = entity;
|
||||
this.currentState = entity.getState();
|
||||
if (entity instanceof AbsNormalEntity) {
|
||||
AbsNormalEntity normalEntity = (AbsNormalEntity) entity;
|
||||
//ALog.d(TAG, "fileName = " + ((AbsNormalEntity) entity).getFileName());
|
||||
fileName.setText(normalEntity.getFileName());
|
||||
} else if (entity instanceof AbsGroupEntity) {
|
||||
AbsGroupEntity groupEntity = (AbsGroupEntity) entity;
|
||||
fileName.setText(
|
||||
groupEntity.getAlias() == null ? groupEntity.getKey() : groupEntity.getAlias());
|
||||
}
|
||||
|
||||
String str =
|
||||
formatFileSize(entity.getCurrentProgress()) + "/" + formatFileSize(entity.getFileSize());
|
||||
fileSize.setText(str);
|
||||
leftTime.setText(CommonUtil.formatTime(entity.getTimeLeft()));
|
||||
String btStr = getResources().getString(R.string.start);
|
||||
String stateStr = "";
|
||||
switch (entity.getState()) {
|
||||
case IEntity.STATE_WAIT:
|
||||
btStr = getResources().getString(R.string.start);
|
||||
stateStr = getResources().getString(R.string.waiting);
|
||||
break;
|
||||
case IEntity.STATE_OTHER:
|
||||
case IEntity.STATE_FAIL:
|
||||
btStr = getResources().getString(R.string.start);
|
||||
stateStr = getResources().getString(R.string.state_error);
|
||||
break;
|
||||
case IEntity.STATE_STOP:
|
||||
btStr = getResources().getString(R.string.resume);
|
||||
stateStr = getResources().getString(R.string.stopped);
|
||||
break;
|
||||
case IEntity.STATE_PRE:
|
||||
case IEntity.STATE_POST_PRE:
|
||||
case IEntity.STATE_RUNNING:
|
||||
btStr = getResources().getString(R.string.stop);
|
||||
stateStr = entity.getConvertSpeed();
|
||||
leftTime.setText(CommonUtil.formatTime(entity.getTimeLeft()));
|
||||
break;
|
||||
case IEntity.STATE_COMPLETE:
|
||||
btStr = getResources().getString(R.string.re_start);
|
||||
stateStr = getResources().getString(R.string.completed);
|
||||
break;
|
||||
case IEntity.STATE_CANCEL:
|
||||
initState();
|
||||
break;
|
||||
default:
|
||||
btStr = getResources().getString(R.string.start);
|
||||
stateStr = "";
|
||||
leftTime.setText("");
|
||||
}
|
||||
this.handleBt.setText(btStr);
|
||||
this.speedOrState.setText(stateStr);
|
||||
if (entity.getState() != IEntity.STATE_CANCEL){
|
||||
this.pb.setProgress(entity.getPercent());
|
||||
}
|
||||
}
|
||||
|
||||
public void setFileName(Character fileName) {
|
||||
this.fileName.setText(fileName);
|
||||
}
|
||||
|
||||
public void setLeftTime(Character leftTime) {
|
||||
this.leftTime.setText(leftTime);
|
||||
}
|
||||
|
||||
public void setFileSize(Character fileSize) {
|
||||
this.fileSize.setText(fileSize);
|
||||
}
|
||||
|
||||
public void setProgress(int progress) {
|
||||
this.pb.setProgress(progress);
|
||||
}
|
||||
|
||||
public void setSpeed(Character speed) {
|
||||
this.speedOrState.setText(speed);
|
||||
}
|
||||
|
||||
public void setState(Character state) {
|
||||
this.speedOrState.setText(state);
|
||||
}
|
||||
|
||||
public String formatFileSize(double size) {
|
||||
if (size < 0) {
|
||||
return "0k";
|
||||
}
|
||||
double kiloByte = size / 1024;
|
||||
if (kiloByte < 1) {
|
||||
return size + "b";
|
||||
}
|
||||
|
||||
double megaByte = kiloByte / 1024;
|
||||
if (megaByte < 1) {
|
||||
BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
|
||||
return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "k";
|
||||
}
|
||||
|
||||
double gigaByte = megaByte / 1024;
|
||||
if (gigaByte < 1) {
|
||||
BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
|
||||
return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "m";
|
||||
}
|
||||
|
||||
double teraBytes = gigaByte / 1024;
|
||||
if (teraBytes < 1) {
|
||||
BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
|
||||
return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "g";
|
||||
}
|
||||
BigDecimal result4 = new BigDecimal(teraBytes);
|
||||
return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "t";
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.simple.R;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/7/17.
|
||||
*/
|
||||
public class SubStateLinearLayout extends LinearLayout implements View.OnClickListener {
|
||||
private final String TAG = "SubStateLinearLayout";
|
||||
|
||||
interface OnShowCallback {
|
||||
void onShow(boolean visibility);
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(int position, View view);
|
||||
}
|
||||
|
||||
OnShowCallback mShowCallback;
|
||||
OnItemClickListener mItemClickListener;
|
||||
|
||||
List<DownloadEntity> mSubData = new LinkedList<>();
|
||||
Map<String, Integer> mPosition = new WeakHashMap<>();
|
||||
SparseArray<View> mViews = new SparseArray<>();
|
||||
|
||||
public SubStateLinearLayout(Context context) {
|
||||
super(context);
|
||||
setOrientation(VERTICAL);
|
||||
}
|
||||
|
||||
public SubStateLinearLayout(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setOrientation(VERTICAL);
|
||||
}
|
||||
|
||||
public SubStateLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setOrientation(VERTICAL);
|
||||
}
|
||||
|
||||
public void addData(List<DownloadEntity> datas) {
|
||||
removeAllViews();
|
||||
mSubData.clear();
|
||||
mSubData.addAll(datas);
|
||||
createShowView();
|
||||
int i = 1;
|
||||
for (DownloadEntity entity : datas) {
|
||||
TextView view = createView(i - 1, entity);
|
||||
mPosition.put(entity.getFilePath(), i);
|
||||
addView(view, i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onClick(View v) {
|
||||
if (mItemClickListener != null) {
|
||||
mItemClickListener.onItemClick(mViews.indexOfValue(v), v);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnShowCallback(OnShowCallback callback) {
|
||||
this.mShowCallback = callback;
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.mItemClickListener = listener;
|
||||
}
|
||||
|
||||
public List<DownloadEntity> getSubData() {
|
||||
return mSubData;
|
||||
}
|
||||
|
||||
public void updateChildProgress(List<DownloadEntity> entities) {
|
||||
for (DownloadEntity entity : entities) {
|
||||
Integer i = mPosition.get(entity.getFilePath());
|
||||
if (i == null) return;
|
||||
int position = i;
|
||||
if (position != -1) {
|
||||
TextView child = ((TextView) getChildAt(position));
|
||||
int p = getPercent(entity);
|
||||
child.setText(entity.getFileName() + ": " + p + "%" + " | " + entity.getConvertSpeed());
|
||||
child.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateChildState(DownloadEntity entity) {
|
||||
Integer i = mPosition.get(entity.getFilePath());
|
||||
if (i == null) return;
|
||||
int position = i;
|
||||
if (position != -1) {
|
||||
TextView child = ((TextView) getChildAt(position));
|
||||
if (entity.isComplete()) {
|
||||
child.setText(entity.getFileName() + " | " + getResources().getText(R.string.complete));
|
||||
} else {
|
||||
int p = getPercent(entity);
|
||||
child.setText(entity.getFileName() + ": " + p + "%" + " | " + entity.getConvertSpeed());
|
||||
}
|
||||
child.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private TextView createView(int position, DownloadEntity entity) {
|
||||
TextView view =
|
||||
(TextView) LayoutInflater.from(getContext()).inflate(R.layout.layout_child_state, null);
|
||||
view.setText(entity.getFileName() + ": " + getPercent(entity) + "%");
|
||||
view.setOnClickListener(this);
|
||||
mViews.append(position, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void createShowView() {
|
||||
|
||||
TextView view =
|
||||
(TextView) LayoutInflater.from(getContext()).inflate(R.layout.layout_child_state, null);
|
||||
view.setText("点击显示子任务");
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
int visibility = getChildAt(1).getVisibility();
|
||||
if (visibility == GONE) {
|
||||
showChild(true);
|
||||
((TextView) v).setText("点击隐藏子任务");
|
||||
} else {
|
||||
showChild(false);
|
||||
((TextView) v).setText("点击显示子任务");
|
||||
}
|
||||
}
|
||||
});
|
||||
addView(view, 0);
|
||||
}
|
||||
|
||||
private void showChild(boolean show) {
|
||||
for (int i = 1, count = getChildCount(); i < count; i++) {
|
||||
getChildAt(i).setVisibility(show ? VISIBLE : GONE);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private int getPercent(DownloadEntity entity) {
|
||||
long size = entity.getFileSize();
|
||||
long progress = entity.getCurrentProgress();
|
||||
return size == 0 ? 0 : (int) (progress * 100 / size);
|
||||
}
|
||||
}
|
83
app/src/main/java/com/arialyy/simple/widget/SvgTextView.java
Normal file
83
app/src/main/java/com/arialyy/simple/widget/SvgTextView.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.simple.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import com.arialyy.simple.R;
|
||||
|
||||
public class SvgTextView extends RelativeLayout {
|
||||
|
||||
private TextView textView;
|
||||
private AppCompatImageView icon;
|
||||
|
||||
public SvgTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SvgTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs) {
|
||||
LayoutInflater.from(getContext()).inflate(R.layout.layout_svg_text, this, true);
|
||||
textView = findViewById(R.id.text);
|
||||
icon = findViewById(R.id.image);
|
||||
|
||||
// init values from custom attributes
|
||||
final TypedArray attributes =
|
||||
getContext().obtainStyledAttributes(attrs, R.styleable.SvgTextView);
|
||||
Drawable drawable = attributes.getDrawable(R.styleable.SvgTextView_svg_text_view_icon);
|
||||
if (drawable != null) {
|
||||
icon.setImageDrawable(drawable);
|
||||
}
|
||||
String str = attributes.getString(R.styleable.SvgTextView_text);
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
textView.setText(str);
|
||||
}
|
||||
|
||||
attributes.recycle();
|
||||
}
|
||||
|
||||
public void setIconClickListener(View.OnClickListener listener) {
|
||||
icon.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
@BindingAdapter(value = { "svg_text_view_icon" })
|
||||
public static void bindAttr(SvgTextView svgTextView, @DrawableRes int drawable) {
|
||||
svgTextView.icon.setImageResource(drawable);
|
||||
}
|
||||
|
||||
public void setIcon(@DrawableRes int drawable) {
|
||||
icon.setImageResource(drawable);
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
textView.setText(Html.fromHtml(text));
|
||||
}
|
||||
}
|
5
app/src/main/res/anim/dialog_enter.xml
Normal file
5
app/src/main/res/anim/dialog_enter.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="100%"
|
||||
android:duration="100"/>
|
||||
</set>
|
6
app/src/main/res/anim/dialog_exit.xml
Normal file
6
app/src/main/res/anim/dialog_exit.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="100"
|
||||
android:toYDelta="100%"/>
|
||||
</set>
|
5
app/src/main/res/color/bt_selector_cancel.xml
Normal file
5
app/src/main/res/color/bt_selector_cancel.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/black" android:state_pressed="true"/>
|
||||
<item android:color="@color/colorAccent" android:state_pressed="false"/>
|
||||
</selector>
|
11
app/src/main/res/drawable-v21/item_bg.xml
Normal file
11
app/src/main/res/drawable-v21/item_bg.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/ripple_material_light">
|
||||
<item android:id="@android:id/mask" android:drawable="@android:color/white" />
|
||||
<item>
|
||||
<selector>
|
||||
<!-- <item android:drawable="@color/bg_grey" android:state_pressed="true"/> -->
|
||||
<item android:drawable="@android:color/transparent"/>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
5
app/src/main/res/drawable/bg_loading.xml
Normal file
5
app/src/main/res/drawable/bg_loading.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#99000000"/>
|
||||
<corners android:radius="8dp"/>
|
||||
</shape>
|
4
app/src/main/res/drawable/ic_activity.xml
Normal file
4
app/src/main/res/drawable/ic_activity.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M160,375.01l354.02,216q4.99,3.01 11.01,3.01l10.02,-3.01 360,-220q10.02,-4.99 10.02,-16 0,-6.02 -2.5,-10.5t-7.49,-6.5L541.06,121.02q-10.02,-6.02 -20.99,0l-360,220q-8.99,6.02 -8.99,16.99 0,4.99 2.5,9.5t6.5,7.49zM531.01,162.02l316,192.99 -322.02,196L208,358.02zM875.01,476.99l-350.02,212.99 -344,-210.02q-7.01,-4 -15.01,-2.02t-12.99,8.99q-2.02,3.01 -2.5,7.01t0.51,7.49 3.49,7.01 5.5,5.5l354.02,216q3.01,2.02 5.5,2.5t5.5,0.51q4.99,0 10.02,-3.01l360,-220q7.01,-4 8.99,-12t-2.02,-15.01q-3.01,-4.99 -7.49,-7.49t-10.02,-2.02 -9.5,3.49zM875.01,615.01l-350.02,214.02 -344,-210.02q-7.01,-4 -15.01,-2.02t-12.99,8.99q-2.02,4 -2.5,9.5t2.02,10.02 7.49,7.49l354.02,216 11.01,3.01q2.02,0 4.99,-0.51t4.99,-2.5l360,-220q7.01,-4 8.99,-12t-2.02,-15.01q-3.01,-4.99 -7.49,-7.49t-10.02,-2.02 -9.5,2.5z"/>
|
||||
</vector>
|
15
app/src/main/res/drawable/ic_choose_file.xml
Normal file
15
app/src/main/res/drawable/ic_choose_file.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="1024"
|
||||
android:viewportWidth="1024"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@color/icon_black"
|
||||
android:pathData="M895.65,672.81c14.3,0 23.74,-9.54 23.74,-23.74L919.39,269.29a30.46,30.46 0,0 0,-8.66 -21.29L738.23,71.19A30.46,30.46 0,0 0,716.42 62L199.21,62c-52.29,0 -95.07,42.78 -95.07,95.07v654h-0.1v51.85h0.1c0,52.25 42.81,95.07 95.07,95.07h625.11c52.25,0 95.07,-42.81 95.07,-95.07v-71.31c0,-14.31 -9.54,-23.74 -23.74,-23.74s-23.74,9.54 -23.74,23.74v71.32a47.69,47.69 0,0 1,-47.48 47.58L199.21,910.51a47.72,47.72 0,0 1,-47.58 -47.58v-28.11h0.1L151.73,157.06a47.63,47.63 0,0 1,47.58 -47.48h482.47v123.57a71.32,71.32 0,0 0,71.32 71.32h118.8v344.6c-0.09,14.2 9.44,23.74 23.75,23.74zM847.19,256.81L753,256.81v0.1c-14.3,0 -23.74,-11.92 -23.74,-23.74v-98.75a2.4,2.4 0,0 1,4.13 -1.67l115.52,120a2.4,2.4 0,0 1,-1.73 4.04z"/>
|
||||
<path
|
||||
android:fillColor="@color/icon_black"
|
||||
android:pathData="M318.91,394.59c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h300.47c14.78,0 26.81,12.25 26.81,27.3s-12,27.3 -26.81,27.3zM318.91,569.8c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h384.85c14.78,0 26.81,12.25 26.81,27.3s-12,27.3 -26.81,27.3zM318.91,742c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h261.3c14.78,0 26.81,12.25 26.81,27.3S595,742 580.21,742z"/>
|
||||
<path
|
||||
android:fillColor="@color/icon_black"
|
||||
android:pathData="M704.01,367.3m-27.3,0a27.3,27.3 0,1 0,54.6 0,27.3 27.3,0 1,0 -54.6,0Z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_close.xml
Normal file
9
app/src/main/res/drawable/ic_close.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M521.69,449.3L111.41,39.01a51.2,51.2 0,1 0,-72.43 72.36l410.28,410.32 -410.28,410.32a51.2,51.2 0,1 0,72.4 72.4l410.32,-410.28 410.32,410.28a51.2,51.2 0,1 0,72.4 -72.36l-410.28,-410.35 410.28,-410.28a51.2,51.2 0,1 0,-72.4 -72.4l-410.28,410.28z"
|
||||
android:fillColor="#515151"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_del.xml
Normal file
10
app/src/main/res/drawable/ic_del.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M801.59,333.13c0.04,1.45 0.09,2.45 0.09,3.62l0,534.45c0,52.39 -42.47,94.87 -94.87,94.87l-389.61,0c-52.39,0 -94.87,-42.47 -94.87,-94.87l0,-534.45c0,-1.17 0.05,-2.17 0.09,-3.62L164.39,333.13l0,555.45c0,74.79 60.63,135.42 135.42,135.42l424.37,0c74.79,0 135.42,-60.63 135.42,-135.42L859.61,333.13 801.59,333.13z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M48.52,237.54l0,17.38c0,67.19 54.47,121.66 121.66,121.66l683.63,0c67.19,0 121.66,-54.47 121.66,-121.66l0,-17.38c0,-67.19 -54.47,-121.66 -121.66,-121.66l-683.63,0C102.99,115.87 48.52,170.34 48.52,237.54zM845.13,318.65l-666.25,0c-40,0 -72.42,-32.42 -72.42,-72.42l0,0c0,-40 32.42,-72.42 72.42,-72.42l666.25,0c40,0 72.42,32.42 72.42,72.42l0,0C917.54,286.22 885.12,318.65 845.13,318.65z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M367.16,119.13l0,-52.15C367.16,45.99 384.18,28.97 405.18,28.97L618.82,28.97C639.82,28.97 656.84,45.99 656.84,66.98l0,52.15c0,5.4 4.38,9.77 9.77,9.77l9.42,0c5.4,0 9.77,-4.38 9.77,-9.77L685.8,62.28c0,-34.4 -27.88,-62.28 -62.28,-62.28L400.47,0C366.08,0 338.2,27.88 338.2,62.28l0,56.85c0,5.4 4.38,9.77 9.77,9.77l9.42,0C362.79,128.91 367.16,124.53 367.16,119.13z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M345.58,876.27 L345.58,876.27c-8,0 -14.48,-6.48 -14.48,-14.48L331.09,457.81c0,-8 6.48,-14.48 14.48,-14.48l0,0c8,0 14.48,6.48 14.48,14.48L360.06,861.78C360.06,869.78 353.58,876.27 345.58,876.27z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M511.28,876.27 L511.28,876.27c-8,0 -14.48,-6.48 -14.48,-14.48L496.79,457.81c0,-8 6.48,-14.48 14.48,-14.48l0,0c8,0 14.48,6.48 14.48,14.48L525.76,861.78C525.76,869.78 519.28,876.27 511.28,876.27z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M677.11,753.91 L677.11,753.91c-8,0 -14.48,-6.48 -14.48,-14.48L662.63,457.81c0,-8 6.48,-14.48 14.48,-14.48l0,0c8,0 14.48,6.48 14.48,14.48l0,281.61C691.6,747.43 685.11,753.91 677.11,753.91z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M677.11,876.27 L677.11,876.27c-8,0 -14.48,-6.48 -14.48,-14.48l0,-46.36c0,-8 6.48,-14.48 14.48,-14.48l0,0c8,0 14.48,6.48 14.48,14.48L691.6,861.78C691.6,869.78 685.11,876.27 677.11,876.27z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_dialog.xml
Normal file
9
app/src/main/res/drawable/ic_dialog.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="1024"
|
||||
android:viewportWidth="1024"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@color/icon_color"
|
||||
android:pathData="M950.86,292.57L950.86,109.71c0,-20.2 -16.37,-36.57 -36.57,-36.57L109.71,73.14c-20.2,0 -36.57,16.37 -36.57,36.57v804.57c0,20.2 16.37,36.57 36.57,36.57h804.57c20.2,0 36.57,-16.37 36.57,-36.57L950.86,365.71L73.14,365.71v-73.14h877.71zM109.71,0h804.57C974.88,0 1024,49.12 1024,109.71v804.57C1024,974.88 974.88,1024 914.29,1024L109.71,1024C49.12,1024 0,974.88 0,914.29L0,109.71C0,49.12 49.12,0 109.71,0zM694.86,146.29L768,146.29c20.2,0 36.57,16.37 36.57,36.57 0,20.2 -16.37,36.57 -36.57,36.57h-73.14c-20.2,0 -36.57,-16.37 -36.57,-36.57 0,-20.2 16.37,-36.57 36.57,-36.57zM256,512h512c20.2,0 36.57,16.37 36.57,36.57 0,20.2 -16.37,36.57 -36.57,36.57L256,585.14c-20.2,0 -36.57,-16.37 -36.57,-36.57C219.43,528.37 235.8,512 256,512zM256,731.43h512c20.2,0 36.57,16.37 36.57,36.57 0,20.2 -16.37,36.57 -36.57,36.57L256,804.57c-20.2,0 -36.57,-16.37 -36.57,-36.57 0,-20.2 16.37,-36.57 36.57,-36.57z"/>
|
||||
</vector>
|
6
app/src/main/res/drawable/ic_dir.xml
Normal file
6
app/src/main/res/drawable/ic_dir.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#CE9F06" android:pathData="M975,774.77H49V220.37h857.09c38.11,0 69.04,30.93 69.04,69.04v485.37h-0.14zM627.71,220.37c0,-63.93 -51.78,-115.71 -115.71,-115.71H49v115.71h578.71"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M164.72,620.26V273.11h694.56v347.14h-694.56z"/>
|
||||
<path android:fillColor="#FFCD2C" android:pathData="M975,848.1V398.49c0,-31.9 -25.96,-57.86 -57.86,-57.86H106.86c-31.9,0 -57.86,25.96 -57.86,57.86v449.46c0,39.35 31.9,71.39 71.39,71.39h783.35c39.35,0.14 71.25,-31.9 71.25,-71.25z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_fragment.xml
Normal file
9
app/src/main/res/drawable/ic_fragment.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M1019.25,1024L882.39,1024l-2.9,-17.39c-11.1,-66.08 -68.78,-114.17 -135.16,-112.27 -62.88,2 -116.17,49.19 -126.76,112.27l-2.9,17.39L144.21,1024v-226.93c-78.48,-10.2 -139.96,-77.18 -140.76,-157.95 -0.4,-42.89 16.2,-83.58 46.79,-114.47 25.79,-25.99 58.58,-42.29 93.97,-46.89L144.21,148.96h283.12C439.12,65.98 510.7,2.1 595.88,2.1h2.1c83.78,1 154.55,65.18 166.35,146.86h254.93v171.15l-19.99,0.8c-64.08,2.7 -116.87,53.58 -120.16,115.77 -1.7,31.69 9.7,62.68 31.89,87.27 22.99,25.29 54.38,40.09 88.27,41.69l19.89,0.9v457.47zM916.68,982.31h60.78L977.46,605.22c-37.39,-6.1 -71.48,-24.59 -97.37,-53.28 -29.79,-32.79 -44.89,-74.48 -42.69,-117.47 4,-76.88 63.98,-140.76 140.06,-153.26v-90.67L724.74,190.54l-0.5,-20.39c-1.5,-68.88 -58.38,-125.56 -126.86,-126.46 -69.98,-0.4 -128.46,55.88 -130.06,126.46l-0.4,20.39L185.9,190.54v327.5L165.1,518.05c-32.09,0 -62.38,12.7 -85.18,35.79 -22.69,22.99 -34.99,52.98 -34.69,84.68 0.7,65.08 54.48,117.97 119.86,117.97h20.79v225.63h394.38c20.09,-73.78 85.97,-127.26 162.75,-129.66 80.08,-2.7 152.46,52.38 173.65,129.86z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M538.79,836.16L242.08,500.75l127.26,-170.05h353.3l108.47,170.95 -292.31,334.5zM295.76,498.55l242.83,274.42 240.53,-275.22 -79.48,-125.26H390.24l-94.47,126.06z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M268.97,478.86h536.14v41.69H268.97z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M396.03,507.45l38.64,-15.65 123.44,304.86 -38.64,15.65z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M524.35,784.56L643.47,489.27l38.66,15.6 -119.12,295.29zM396.22,485.29l92.07,-141.31 34.93,22.76 -92.07,141.31z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M558.2,362.12l35.97,-21.07 85.35,145.7 -35.97,21.07z"/>
|
||||
</vector>
|
6
app/src/main/res/drawable/ic_ftp.xml
Normal file
6
app/src/main/res/drawable/ic_ftp.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M643.67,570.54c-8.24,0 -13.83,0.54 -16.76,1.33v52.93c3.46,0.79 7.72,1.07 13.56,1.07 21.54,0 34.85,-10.9 34.85,-29 0,-16.48 -11.17,-26.33 -31.65,-26.33z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M553.31,329.84c-22.77,-22.76 -59.68,-22.76 -82.45,0L211.94,588.76c-22.77,22.77 -22.77,59.69 0,82.46L470.84,930.13c22.77,22.77 59.68,22.77 82.45,0l258.92,-258.92a58.29,58.29 0,0 0,0 -82.45l-258.91,-258.91zM417.98,574.26h-68.88v40.97h64.36v32.97h-64.36v72.08h-40.42L308.68,541.02h109.3v33.24zM572.78,575.07h-48.95v145.2h-40.41v-145.2h-48.4v-34.04h137.76v34.04zM699.25,638.09c-13.83,12.79 -34.58,18.89 -58.51,18.89 -5.32,0 -10.1,-0.26 -13.83,-1.07v64.36h-40.15L586.76,543.42c12.5,-2.13 30.06,-3.73 54.79,-3.73 24.99,0 43.08,4.8 55.05,14.63 11.44,8.78 18.88,23.67 18.88,41.23 -0,17.82 -5.58,32.7 -16.23,42.54z"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M816.52,233.62a19.23,19.23 0,0 1,-14.22 -7.93c-41.61,-57.71 -109.39,-93.42 -181.56,-93.42 -5.23,0 -10.46,0.19 -15.69,0.55a19.19,19.19 0,0 1,-13.05 -3.93C548.31,95.28 495.07,77.06 439.28,77.06c-99.7,0 -188.06,58.43 -228.31,146.63a19.22,19.22 0,0 1,-15.11 11.08C85.63,248.56 0.07,342.84 0.07,456.74c0,100.93 67.24,186.39 159.25,214.13a102,102 0,0 1,-8.53 -40.88c0,-18.38 4.91,-35.96 13.93,-51.42 -45.2,-22 -76.51,-68.27 -76.51,-121.84 0,-74.75 60.81,-135.55 135.56,-135.55 3.78,0 7.48,0.3 11.18,0.61 21.53,1.65 41.04,-12.31 46.28,-33.2 18.24,-72.64 83.22,-123.38 158.04,-123.38 42.75,0 83.2,16.51 113.9,46.48a44.08,44.08 0,0 0,39.77 11.59,137.33 137.33,0 0,1 27.8,-2.86c52.33,0 99.07,29.41 121.97,76.78 8.05,16.65 25.64,26.57 44.06,24.68a134.18,134.18 0,0 1,13.6 -0.69c74.75,0 135.57,60.81 135.57,135.55 0,53.57 -31.31,99.83 -76.51,121.84 9.02,15.45 13.93,33.02 13.93,51.39a102.13,102.13 0,0 1,-8.54 40.91c92.02,-27.75 159.25,-113.21 159.25,-214.14 0.02,-117.92 -91.69,-214.84 -207.54,-223.14z"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/ic_ftp_dir.xml
Normal file
5
app/src/main/res/drawable/ic_ftp_dir.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1199" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M479.38,472.06L479.38,506.15h-119.81v76.65h114.1v34.08h-114.1v118.05h-35.4L324.17,472.06h155.21zM681.84,472.06L681.84,506.15h-76.65v228.94L569.2,735.09L569.2,506.29h-75.78v-34.08L681.84,472.21zM804.72,472.06c54.86,0 82.07,26.62 82.07,80.02s-27.79,79.43 -82.65,79.43h-59.98v102.4h-34.82v-261.85L804.72,472.06zM744.74,598.6h57.2c13.17,0.88 26.33,-3.07 36.86,-11.12 8.63,-9.65 13.02,-22.38 12,-35.4 1.32,-12.73 -3.07,-25.6 -12,-34.82 -10.83,-8.19 -24.28,-12.29 -37.74,-11.12h-56.61l0.29,92.45zM744.74,598.6"/>
|
||||
<path android:fillColor="@color/icon_color" android:pathData="M776.48,241.96l-144.97,-119.81L1057.79,122.15c37.89,-0.88 71.39,24.58 80.6,61.44v58.37L776.48,241.96zM1138.4,914.87c-4.39,25.16 -25.16,44.03 -50.61,46.08h-977.19c-25.45,-2.05 -46.23,-21.07 -50.61,-46.08L59.98,108.4c4.39,-25.16 25.16,-44.03 50.61,-46.08h355.62l282.77,239.62h389.41v612.94zM1087.78,62.32L578.41,62.32l-72.85,-59.98h-394.97C81.63,1.32 53.69,12.14 32.91,32.04 12,52.08 0.15,79.58 0,108.4v806.47c0.15,28.82 12,56.47 32.91,76.36 20.77,19.89 48.86,30.72 77.68,29.7h977.33c28.82,1.02 56.76,-9.8 77.68,-29.7 20.77,-20.04 32.62,-47.54 32.91,-76.36L1198.52,183.59c0.88,-63.34 -47.54,-116.44 -110.74,-121.27zM1087.78,62.32"/>
|
||||
</vector>
|
4
app/src/main/res/drawable/ic_full_screen.xml
Normal file
4
app/src/main/res/drawable/ic_full_screen.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@color/icon_black" android:pathData="M432,636.8l-41.6,-41.6 -150.4,150.4L128,633.6L128,896h259.2l-108.8,-108.8 153.6,-150.4zM595.2,387.2l41.6,41.6 150.4,-150.4 108.8,108.8L896,128h-259.2l108.8,108.8 -150.4,150.4zM128,128v259.2l108.8,-108.8 150.4,150.4 41.6,-41.6 -147.2,-150.4L390.4,128L128,128zM595.2,636.8l150.4,150.4 -108.8,108.8L896,896v-259.2l-108.8,108.8 -150.4,-150.4 -41.6,41.6zM595.2,636.8"/>
|
||||
</vector>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user