源代码备份

This commit is contained in:
TC999
2024-08-20 16:54:35 +08:00
parent c4db18da39
commit e2a5f92e23
791 changed files with 90314 additions and 2 deletions

2
app/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/build
*.log

96
app/build.gradle Normal file
View 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
View 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

Binary file not shown.

135
app/proguard-rules.pro vendored Normal file
View 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

View File

@ -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)}")
}
}

View 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>

View 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>

View 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, "runningspeed=" + 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;
}
}
}

View 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() + ",上传完成");
}
}

View 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() + ",下载完成");
}
}

View 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()
}
}

View 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-----

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBlgTuAhvU/Z0ni2PszmIXkDvANMWNYHfiCfvOxRKoK/jCGmKw/TDF1Z49P5M5CMpKwTaQKDxfolYeCgvH9eBmY1NiE26COWexgoqxrw4pWE9/h2Thx7cVWjGWZZ4iwyYfT19/5SgPNujiW9cWGV9N8VXAKe6Sl7v+6TtjLHNCNEn7B90m6sRIYHXsAQ7W7TBlUD5S6wcAsL6v6RVMVVBoIXykNW+zQK6prAWPCtPWcEw3WwfCIUQfJLS8gMC++Ox/bT9gqR+uZTk8MGxafxa9lrvIvpcZh8uVzaP428E3mlSkJnhTAzk43VoKAKxDA1Z+Qehig7VP9GsSn2HGuYE7 AriaL@DESKTOP-BBML2VA

View 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));
}
}

View 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);
}
}
}
}

View 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) {
}
}

View File

@ -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();
}
}

View 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) {
}
}

View 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);
}
}

View File

@ -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;
}
}

View File

@ -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) {
}
}

View File

@ -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);
}
}

View File

@ -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) {
//
//}
}
}

View File

@ -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;
}
}

View 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);
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View 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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
});
}
}

View File

@ -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;
}
}
});
}
}

View File

@ -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) {
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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())
}
}
}

View File

@ -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));
}
}
}

View File

@ -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) {
// }
//}

View File

@ -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);
}
}
}

View File

@ -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) {
}
}

View File

@ -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);
}
}

View File

@ -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
}
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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);
}
}
}

View File

@ -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, "任务组下载完成");
}
}

View 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.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;
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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组合任务
* 2m3u8任务
*/
public int type = 0;
public String[] urls, names;
}

View 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.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();
}
}

View File

@ -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;
}

View 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.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);
}
}

View File

@ -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 + ""));
}
}
}

View File

@ -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());
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View 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.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 createmd5" + 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());
}
}

View File

@ -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());
}
}
}

View File

@ -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);
}
}

View 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, "runningPercent = " + 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();
}
}

View 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;
}
}

View 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];
}
};
}

View 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;
}

View 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);
}
}

View 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);
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View 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";
}
}

View File

@ -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);
}
}

View 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));
}
}

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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