id功能修改

v3.7
laoyuyu 5 years ago
parent fdb607e10f
commit 27fb964fef
  1. 9
      Aria/src/main/java/com/arialyy/aria/core/command/CancelAllCmd.java
  2. 10
      Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
  3. 16
      Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
  4. 192
      Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java
  5. 70
      Aria/src/main/java/com/arialyy/aria/core/common/AbsStartTarget.java
  6. 59
      Aria/src/main/java/com/arialyy/aria/core/common/BaseDelegate.java
  7. 12
      Aria/src/main/java/com/arialyy/aria/core/common/Suggest.java
  8. 18
      Aria/src/main/java/com/arialyy/aria/core/common/controller/ControllerType.java
  9. 145
      Aria/src/main/java/com/arialyy/aria/core/common/controller/FeatureController.java
  10. 48
      Aria/src/main/java/com/arialyy/aria/core/common/controller/INormalFeature.java
  11. 34
      Aria/src/main/java/com/arialyy/aria/core/common/controller/IStartFeature.java
  12. 122
      Aria/src/main/java/com/arialyy/aria/core/common/controller/NormalController.java
  13. 72
      Aria/src/main/java/com/arialyy/aria/core/common/controller/StartController.java
  14. 58
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSDelegate.java
  15. 45
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java
  16. 99
      Aria/src/main/java/com/arialyy/aria/core/common/http/HttpDelegate.java
  17. 21
      Aria/src/main/java/com/arialyy/aria/core/common/http/HttpTaskConfig.java
  18. 30
      Aria/src/main/java/com/arialyy/aria/core/common/http/PostDelegate.java
  19. 68
      Aria/src/main/java/com/arialyy/aria/core/download/AbsDGTarget.java
  20. 127
      Aria/src/main/java/com/arialyy/aria/core/download/AbsGroupConfigHandler.java
  21. 183
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDEntityUtil.java
  22. 254
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDGEntityUtil.java
  23. 133
      Aria/src/main/java/com/arialyy/aria/core/download/CheckFtpDirEntityUtil.java
  24. 27
      Aria/src/main/java/com/arialyy/aria/core/download/DGTaskWrapper.java
  25. 178
      Aria/src/main/java/com/arialyy/aria/core/download/DNormalConfigHandler.java
  26. 38
      Aria/src/main/java/com/arialyy/aria/core/download/DTaskWrapper.java
  27. 134
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  28. 161
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  29. 70
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirConfigHandler.java
  30. 110
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
  31. 80
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirNormalTarget.java
  32. 82
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirStartTarget.java
  33. 150
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
  34. 80
      Aria/src/main/java/com/arialyy/aria/core/download/FtpNormalTarget.java
  35. 79
      Aria/src/main/java/com/arialyy/aria/core/download/FtpStartTarget.java
  36. 113
      Aria/src/main/java/com/arialyy/aria/core/download/GroupNormalTarget.java
  37. 141
      Aria/src/main/java/com/arialyy/aria/core/download/GroupStartTarget.java
  38. 176
      Aria/src/main/java/com/arialyy/aria/core/download/HttpGroupConfigHandler.java
  39. 85
      Aria/src/main/java/com/arialyy/aria/core/download/HttpNormalTarget.java
  40. 98
      Aria/src/main/java/com/arialyy/aria/core/download/HttpStartTarget.java
  41. 23
      Aria/src/main/java/com/arialyy/aria/core/download/group/FtpDirInfoThread.java
  42. 30
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Delegate.java
  43. 18
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8LiveDelegate.java
  44. 17
      Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8VodDelegate.java
  45. 4
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java
  46. 6
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java
  47. 310
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  48. 24
      Aria/src/main/java/com/arialyy/aria/core/inf/IConfigHandler.java
  49. 57
      Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java
  50. 50
      Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderDelegate.java
  51. 71
      Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java
  52. 33
      Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
  53. 17
      Aria/src/main/java/com/arialyy/aria/core/manager/IGroupWrapperFactory.java
  54. 2
      Aria/src/main/java/com/arialyy/aria/core/manager/INormalTEFactory.java
  55. 88
      Aria/src/main/java/com/arialyy/aria/core/manager/TaskWrapperManager.java
  56. 24
      Aria/src/main/java/com/arialyy/aria/core/manager/UTaskWrapperFactory.java
  57. 8
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  58. 109
      Aria/src/main/java/com/arialyy/aria/core/upload/CheckUEntityUtil.java
  59. 57
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpNormalTarget.java
  60. 65
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpStartTarget.java
  61. 110
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  62. 63
      Aria/src/main/java/com/arialyy/aria/core/upload/HttpNormalTarget.java
  63. 58
      Aria/src/main/java/com/arialyy/aria/core/upload/HttpStartTarget.java
  64. 109
      Aria/src/main/java/com/arialyy/aria/core/upload/UNormalConfigHandler.java
  65. 13
      Aria/src/main/java/com/arialyy/aria/core/upload/UTaskWrapper.java
  66. 62
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  67. 125
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
  68. 22
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  69. 4
      Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
  70. 9
      Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java
  71. 47
      Aria/src/main/java/com/arialyy/aria/util/DbDataHelper.java
  72. 1
      app/src/main/AndroidManifest.xml
  73. 4
      app/src/main/assets/help_code/KotlinHttpDownload.kt
  74. 34
      app/src/main/java/com/arialyy/simple/core/download/DownloadDialog.java
  75. 41
      app/src/main/java/com/arialyy/simple/core/download/DownloadDialogFragment.java
  76. 57
      app/src/main/java/com/arialyy/simple/core/download/DownloadPopupWindow.java
  77. 38
      app/src/main/java/com/arialyy/simple/core/download/FtpDownloadActivity.java
  78. 2
      app/src/main/java/com/arialyy/simple/core/download/FtpDownloadModule.java
  79. 36
      app/src/main/java/com/arialyy/simple/core/download/HighestPriorityActivity.java
  80. 10
      app/src/main/java/com/arialyy/simple/core/download/HttpDownloadModule.java
  81. 22
      app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt
  82. 27
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  83. 54
      app/src/main/java/com/arialyy/simple/core/download/fragment_download/DownloadFragment.java
  84. 46
      app/src/main/java/com/arialyy/simple/core/download/group/DownloadGroupActivity.java
  85. 36
      app/src/main/java/com/arialyy/simple/core/download/group/FTPDirDownloadActivity.java
  86. 23
      app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveDLoadActivity.java
  87. 2
      app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8LiveModule.java
  88. 34
      app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodDLoadActivity.java
  89. 2
      app/src/main/java/com/arialyy/simple/core/download/m3u8/M3U8VodModule.java
  90. 27
      app/src/main/java/com/arialyy/simple/core/download/multi_download/DownloadAdapter.java
  91. 91
      app/src/main/java/com/arialyy/simple/core/test/TestFTPActivity.java
  92. 104
      app/src/main/java/com/arialyy/simple/core/test/TestFTPDirActivity.java
  93. 80
      app/src/main/java/com/arialyy/simple/core/test/TestMutilTaskSysDownload.java
  94. 33
      app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
  95. 17
      app/src/main/java/com/arialyy/simple/core/upload/HttpUploadActivity.java
  96. 2
      app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java
  97. 31
      app/src/main/java/com/arialyy/simple/modlue/AnyRunnModule.java
  98. 10
      app/src/main/java/com/arialyy/simple/util/AppUtil.java
  99. 9
      app/src/main/res/layout/dialog_download.xml
  100. 8
      app/src/main/res/layout/dialog_fragment_download.xml
  101. Some files were not shown because too many files have changed in this diff Show More

@ -65,7 +65,7 @@ final public class CancelAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T
if (entities != null && !entities.isEmpty()) {
for (DownloadEntity entity : entities) {
remove(TaskWrapperManager.getInstance()
.getHttpTaskWrapper(DTaskWrapper.class, entity.getKey()));
.getNormalTaskWrapper(DTaskWrapper.class, entity.getId()));
}
}
}
@ -78,9 +78,8 @@ final public class CancelAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T
DbEntity.findDatas(DownloadGroupEntity.class, "state!=?", "-1");
if (entities != null && !entities.isEmpty()) {
for (DownloadGroupEntity entity : entities) {
remove(
TaskWrapperManager.getInstance()
.getDGTaskWrapper(DGTaskWrapper.class, entity.getUrls()));
remove(TaskWrapperManager.getInstance()
.getGroupWrapper(DGTaskWrapper.class, entity.getId()));
}
}
}
@ -94,7 +93,7 @@ final public class CancelAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T
if (entities != null && !entities.isEmpty()) {
for (UploadEntity entity : entities) {
remove(TaskWrapperManager.getInstance()
.getHttpTaskWrapper(UTaskWrapper.class, entity.getKey()));
.getNormalTaskWrapper(UTaskWrapper.class, entity.getId()));
}
}
}

@ -62,7 +62,7 @@ final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
if (entities != null && !entities.isEmpty()) {
for (DownloadEntity entity : entities) {
addResumeEntity(TaskWrapperManager.getInstance()
.getHttpTaskWrapper(DTaskWrapper.class, entity.getKey()));
.getNormalTaskWrapper(DTaskWrapper.class, entity.getId()));
}
}
} else if (type == 2) {
@ -72,7 +72,7 @@ final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
for (DownloadGroupEntity entity : entities) {
addResumeEntity(
TaskWrapperManager.getInstance()
.getDGTaskWrapper(DGTaskWrapper.class, entity.getUrls()));
.getGroupWrapper(DGTaskWrapper.class, entity.getId()));
}
}
} else if (type == 3) {
@ -81,7 +81,7 @@ final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
if (entities != null && !entities.isEmpty()) {
for (UploadEntity entity : entities) {
addResumeEntity(TaskWrapperManager.getInstance()
.getHttpTaskWrapper(UTaskWrapper.class, entity.getKey()));
.getNormalTaskWrapper(UTaskWrapper.class, entity.getId()));
}
}
}
@ -91,7 +91,9 @@ final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
* 添加恢复实体
*/
private void addResumeEntity(AbsTaskWrapper te) {
if (te == null || te.getEntity() == null) return;
if (te == null || te.getEntity() == null) {
return;
}
if (!mQueue.taskExists(te.getKey())) {
mWaitList.add(te);
}

@ -127,11 +127,7 @@ final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
"isGroupChild=? and state=?", "false", "3");
if (dEntities != null && !dEntities.isEmpty()) {
for (DownloadEntity e : dEntities) {
if (e.getTaskType() == AbsTaskWrapper.D_FTP) {
waitList.add(tManager.getFtpTaskWrapper(DTaskWrapper.class, e.getKey()));
} else if (e.getTaskType() == AbsTaskWrapper.D_HTTP) {
waitList.add(tManager.getHttpTaskWrapper(DTaskWrapper.class, e.getKey()));
}
waitList.add(tManager.getNormalTaskWrapper(DTaskWrapper.class, e.getId()));
}
}
} else if (type == 2) { // 组合任务
@ -140,9 +136,9 @@ final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
if (dEntities != null && !dEntities.isEmpty()) {
for (DownloadGroupEntity e : dEntities) {
if (e.getTaskType() == AbsTaskWrapper.DG_HTTP) {
waitList.add(tManager.getDGTaskWrapper(DGTaskWrapper.class, e.getUrls()));
waitList.add(tManager.getGroupWrapper(DGTaskWrapper.class, e.getId()));
} else if (e.getTaskType() == AbsTaskWrapper.D_FTP_DIR) {
waitList.add(tManager.getFtpTaskWrapper(DGTaskWrapper.class, e.getKey()));
waitList.add(tManager.getGroupWrapper(DGTaskWrapper.class, e.getId()));
}
}
}
@ -151,11 +147,7 @@ final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
if (dEntities != null && !dEntities.isEmpty()) {
for (UploadEntity e : dEntities) {
if (e.getTaskType() == AbsTaskWrapper.D_FTP) {
waitList.add(tManager.getFtpTaskWrapper(UTaskWrapper.class, e.getKey()));
} else if (e.getTaskType() == AbsTaskWrapper.D_HTTP) {
waitList.add(tManager.getHttpTaskWrapper(UTaskWrapper.class, e.getKey()));
}
waitList.add(tManager.getNormalTaskWrapper(UTaskWrapper.class, e.getId()));
}
}
}

@ -0,0 +1,192 @@
/*
* 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.aria.core.common;
import com.arialyy.aria.core.common.controller.INormalFeature;
import com.arialyy.aria.core.common.controller.NormalController;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.RecordUtil;
/**
* 处理任务停止恢复删除等功能
*/
public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends AbsTarget<TARGET>
implements INormalFeature {
/**
* 任务是否在执行
*
* @return {@code true} 任务正在执行
*/
public abstract boolean isRunning();
/**
* 任务是否存在
*
* @return {@code true} 任务存在
*/
public abstract boolean taskExists();
private NormalController mNormalController;
private synchronized NormalController getController() {
if (mNormalController == null) {
mNormalController = new NormalController(getTaskWrapper());
}
return mNormalController;
}
/**
* 删除记录如果任务正在执行则会删除正在下载的任务
*/
public void removeRecord() {
if (isRunning()) {
ALog.d("AbsTarget", "任务正在下载,即将删除任务");
cancel();
} else {
if (getEntity() instanceof AbsNormalEntity) {
RecordUtil.delTaskRecord((AbsNormalEntity) getEntity(), getTaskWrapper().isRemoveFile());
} else if (getEntity() instanceof DownloadGroupEntity) {
RecordUtil.delGroupTaskRecord(((DownloadGroupEntity) getEntity()),
getTaskWrapper().isRemoveFile(),
true);
}
TaskWrapperManager.getInstance().removeTaskWrapper(getTaskWrapper());
}
}
/**
* 获取任务进度如果任务存在则返回当前进度
*
* @return 该任务进度
*/
public long getCurrentProgress() {
return getEntity() == null ? -1 : getEntity().getCurrentProgress();
}
/**
* 获取任务文件大小
*
* @return 文件大小
*/
public long getFileSize() {
return getEntity() == null ? 0 : getEntity().getFileSize();
}
/**
* 获取单位转换后的文件大小
*
* @return 文件大小{@code xxx mb}
*/
public String getConvertFileSize() {
return getEntity() == null ? "0b" : CommonUtil.formatFileSize(getEntity().getFileSize());
}
/**
* 获取存放的扩展字段
* 设置扩展字段{@link #setExtendField(String)}
*/
public String getExtendField() {
return getEntity().getStr();
}
/**
* 获取任务状态
*
* @return {@link IEntity}
*/
public int getTaskState() {
return getEntity().getState();
}
/**
* 获取任务进度百分比
*
* @return 返回任务进度
*/
public int getPercent() {
if (getEntity() == null) {
ALog.e("AbsTarget", "下载管理器中没有该任务");
return 0;
}
if (getEntity().getFileSize() != 0) {
return (int) (getEntity().getCurrentProgress() * 100 / getEntity().getFileSize());
}
return 0;
}
/**
* 停止任务
*/
@Override
public void stop() {
getController().stop();
}
/**
* 恢复任务
*/
@Override
public void resume() {
getController().resume();
}
/**
* 删除任务
*/
@Override
public void cancel() {
getController().cancel();
}
/**
* 任务重试
*/
@Override
public void reTry() {
getController().reTry();
}
/**
* 删除任务
*
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
@Override
public void cancel(boolean removeFile) {
getController().cancel(removeFile);
}
/**
* 重新下载
*/
@Override
public void reStart() {
getController().reStart();
}
@Override
public void save() {
getController().save();
}
}

@ -0,0 +1,70 @@
/*
* 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.aria.core.common;
import com.arialyy.aria.core.common.controller.IStartFeature;
import com.arialyy.aria.core.common.controller.StartController;
import com.arialyy.aria.core.inf.AbsTarget;
/**
* 处理第一次下载
*/
public abstract class AbsStartTarget<TARGET extends AbsStartTarget> extends AbsTarget<TARGET>
implements IStartFeature {
private StartController mStartController;
private synchronized StartController getController() {
if (mStartController == null) {
mStartController = new StartController(getTaskWrapper());
}
return mStartController;
}
/**
* 添加任务
*
* @return 正常添加返回任务id否则返回-1
*/
@Override
public long add() {
return getController().add();
}
/**
* 开始任务
*
* @return 正常启动返回任务id否则返回-1
*/
@Override
public long start() {
return getController().start();
}
/**
* 将任务设置为最高优先级任务最高优先级任务有以下特点
* 1在下载队列中有且只有一个最高优先级任务
* 2最高优先级任务会一直存在直到用户手动暂停或任务完成
* 3任务调度器不会暂停最高优先级任务
* 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效
* 5如果下载队列中已经满了则会停止队尾的任务当高优先级任务完成后该队尾任务将自动执行
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/
@Override
public long setHighestPriority() {
return getController().setHighestPriority();
}
}

@ -15,52 +15,37 @@
*/
package com.arialyy.aria.core.common;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.controller.ControllerType;
import com.arialyy.aria.core.common.controller.FeatureController;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.ITargetHandler;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.CommonUtil;
public abstract class BaseDelegate<TARGET extends AbsTarget> implements ITargetHandler {
protected TARGET mTarget;
public abstract class BaseDelegate<TARGET extends AbsTarget> {
protected final String TAG;
protected TARGET mTarget;
protected AbsTaskWrapper mWrapper;
public BaseDelegate(TARGET target) {
mTarget = target;
public BaseDelegate(TARGET target, AbsTaskWrapper wrapper) {
TAG = CommonUtil.getClassName(getClass());
mTarget = target;
mWrapper = wrapper;
}
@Override public void add() {
mTarget.add();
}
@Override public void start() {
mTarget.start();
}
@Override public void stop() {
mTarget.stop();
}
@Override public void resume() {
mTarget.resume();
}
@Override public void cancel() {
mTarget.cancel();
}
@Override public void save() {
mTarget.save();
}
@Override public void cancel(boolean removeFile) {
mTarget.cancel(removeFile);
}
@Override public void reTry() {
mTarget.reTry();
protected AbsTaskWrapper getTaskWrapper() {
return mWrapper;
}
@Override public void reStart() {
mTarget.reStart();
/**
* 使用对应等控制器注意
* 1对于不存在的任务第一次下载只能使用{@link ControllerType#START_CONTROLLER}
* 2对于已存在的任务只能使用{@link ControllerType#NORMAL_CONTROLLER}
*
* @param clazz {@link ControllerType#START_CONTROLLER}{@link ControllerType#NORMAL_CONTROLLER}
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public <T extends FeatureController> T controller(@ControllerType Class<T> clazz) {
return FeatureController.newInstance(clazz, getTaskWrapper());
}
}

@ -13,15 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.upload;
package com.arialyy.aria.core.common;
import com.arialyy.aria.core.inf.AbsTarget;
/**
* Created by AriaL on 2017/6/29.
* 普通上传任务接收器
*/
abstract class AbsUploadTarget<TARGET extends AbsUploadTarget> extends AbsTarget<TARGET> {
public interface Suggest {
String TASK_CONTROLLER = "after use #add()、#start()、#stop()、#cancel()、#resume()、#save()?";
String TO_CONTROLLER = "after use #controller()?";
}

@ -13,18 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.common.http;
package com.arialyy.aria.core.common.controller;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.inf.AbsTarget;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* get处理委托类
*/
public class GetDelegate<TARGET extends AbsTarget> extends HttpDelegate<TARGET> {
public GetDelegate(TARGET target) {
super(target);
mTarget.getTaskWrapper().asHttp().setRequestEnum(RequestEnum.GET);
}
@Retention(RetentionPolicy.SOURCE) public @interface ControllerType {
Class<StartController> START_CONTROLLER = StartController.class;
Class<NormalController> NORMAL_CONTROLLER = NormalController.class;
}

@ -0,0 +1,145 @@
/*
* 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.aria.core.common.controller;
import android.os.Handler;
import android.os.Looper;
import com.arialyy.aria.core.download.CheckDEntityUtil;
import com.arialyy.aria.core.download.CheckDGEntityUtil;
import com.arialyy.aria.core.download.CheckFtpDirEntityUtil;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.core.upload.CheckUEntityUtil;
import com.arialyy.aria.core.upload.UTaskWrapper;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 功能控制器
*/
public abstract class FeatureController {
private AbsTaskWrapper mTaskWrapper;
FeatureController(AbsTaskWrapper wrapper) {
mTaskWrapper = wrapper;
}
/**
* 使用对应等控制器注意
* 1对于不存在的任务第一次下载只能使用{@link ControllerType#START_CONTROLLER}
* 2对于已存在的任务只能使用{@link ControllerType#NORMAL_CONTROLLER}
*
* @param clazz {@link ControllerType#START_CONTROLLER}{@link ControllerType#NORMAL_CONTROLLER}
*/
public static <T extends FeatureController> T newInstance(@ControllerType Class<T> clazz,
AbsTaskWrapper wrapper) {
if (wrapper.getEntity().getId() == -1 && clazz != ControllerType.START_CONTROLLER) {
throw new IllegalArgumentException("对于不存在的任务(第一次下载),只能使用\"ControllerType.START_CONTROLLER\"");
}
if (wrapper.getEntity().getId() != -1 && clazz != ControllerType.NORMAL_CONTROLLER) {
throw new IllegalArgumentException("对于已存在的任务,只能使用\" ControllerType.NORMAL_CONTROLLER\"");
}
Class[] paramTypes = { AbsTaskWrapper.class };
Object[] params = { wrapper };
try {
Constructor<T> con = clazz.getConstructor(paramTypes);
return con.newInstance(params);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
protected AbsTaskWrapper getTaskWrapper() {
return mTaskWrapper;
}
protected AbsEntity getEntity() {
return mTaskWrapper.getEntity();
}
int checkTaskType() {
int taskType = 0;
if (mTaskWrapper instanceof DTaskWrapper) {
taskType = ITask.DOWNLOAD;
} else if (mTaskWrapper instanceof DGTaskWrapper) {
taskType = ITask.DOWNLOAD_GROUP;
} else if (mTaskWrapper instanceof UTaskWrapper) {
taskType = ITask.UPLOAD;
}
return taskType;
}
/**
* 如果检查实体失败将错误回调
*/
boolean checkConfig() {
boolean b = checkEntity();
ISchedulers schedulers = getScheduler();
if (!b && schedulers != null) {
new Handler(Looper.getMainLooper(), schedulers).obtainMessage(ISchedulers.CHECK_FAIL,
checkTaskType(), -1, null).sendToTarget();
}
return b;
}
private ISchedulers getScheduler() {
if (mTaskWrapper instanceof DTaskWrapper) {
return DownloadSchedulers.getInstance();
}
if (mTaskWrapper instanceof UTaskWrapper) {
return UploadSchedulers.getInstance();
}
if (mTaskWrapper instanceof DGTaskWrapper) {
return DownloadSchedulers.getInstance();
}
return null;
}
private boolean checkEntity() {
if (mTaskWrapper instanceof DTaskWrapper) {
return CheckDEntityUtil.newInstance((DTaskWrapper) mTaskWrapper).checkEntity();
}
if (mTaskWrapper instanceof DGTaskWrapper) {
if (mTaskWrapper.getRequestType() == AbsTaskWrapper.D_FTP_DIR) {
return CheckFtpDirEntityUtil.newInstance((DGTaskWrapper) mTaskWrapper).checkEntity();
}
if (mTaskWrapper.getRequestType() == AbsTaskWrapper.DG_HTTP) {
return CheckDGEntityUtil.newInstance((DGTaskWrapper) mTaskWrapper).checkEntity();
}
}
if (mTaskWrapper instanceof UTaskWrapper) {
return CheckUEntityUtil.newInstance((UTaskWrapper) mTaskWrapper).checkEntity();
}
return false;
}
}

@ -13,46 +13,48 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.inf;
package com.arialyy.aria.core.common.controller;
/**
* Created by lyy on 2019/4/5.
* 组合任务配置处理
* 恢复停止删除等功能控制器
*/
public interface IGroupConfigHandler {
public interface INormalFeature {
/**
* 获取实体
* 停止任务
*/
AbsEntity getEntity();
void stop();
/**
* 任务是否存在
*
* @return {@code true}任务存在{@code false} 任务不存在
* 恢复任务
*/
boolean taskExists();
void resume();
/**
* 任务是否在执行
*
* @return {@code true} 任务正在执行{@code false} 任务没有执行
* 删除任务
*/
boolean isRunning();
void cancel();
/**
* 检查实体是否合法
*
* @return {@code true}合法
* 任务重试
*/
boolean checkEntity();
void reTry();
/**
* 检查文件夹路径
* 1文件夹路径不能为空
* 2文件夹路径不能是文件
* 删除任务
*
* @return {@code true} 合法
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
void cancel(boolean removeFile);
/**
* 重新下载
*/
void reStart();
/**
* 保存数据
*/
boolean checkDirPath();
void save();
}

@ -13,24 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.download;
package com.arialyy.aria.core.common.controller;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.util.CommonUtil;
/**
* 第一次启动任务的功能接口
*/
public interface IStartFeature {
/**
* Created by lyy on 2017/2/28.
* 添加任务
*
* @return 正常添加返回任务id否则返回-1
*/
abstract class AbsDTarget<TARGET extends AbsDTarget> extends AbsTarget<TARGET> {
long add();
/**
* 更新下载url
* 开始任务
*
* @param newUrl 新的下载url
* @return 正常启动返回任务id否则返回-1
*/
public abstract TARGET updateUrl(String newUrl);
long start();
/**
* 将任务设置为最高优先级任务最高优先级任务有以下特点
@ -41,15 +43,5 @@ abstract class AbsDTarget<TARGET extends AbsDTarget> extends AbsTarget<TARGET> {
* 5如果下载队列中已经满了则会停止队尾的任务当高优先级任务完成后该队尾任务将自动执行
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/
public void setHighestPriority() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_HIGHEST_PRIORITY,
checkTaskType()));
}
}
@Override public DownloadEntity getEntity() {
return (DownloadEntity) super.getEntity();
}
long setHighestPriority();
}

@ -0,0 +1,122 @@
/*
* 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.aria.core.common.controller;
import com.arialyy.aria.core.command.CancelCmd;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
/**
* 启动控制器
*/
public final class NormalController extends FeatureController implements INormalFeature {
private String TAG = "NormalController";
public NormalController(AbsTaskWrapper wrapper) {
super(wrapper);
}
/**
* 停止任务
*/
@Override
public void stop() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_STOP,
checkTaskType()));
}
}
/**
* 恢复任务
*/
@Override
public void resume() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
checkTaskType()));
}
}
/**
* 删除任务
*/
@Override
public void cancel() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CANCEL,
checkTaskType()));
}
}
/**
* 任务重试
*/
@Override
public void reTry() {
if (checkConfig()) {
int taskType = checkTaskType();
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_STOP, taskType));
EventMsgUtil.getDefault()
.post(
CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START, taskType));
}
}
/**
* 删除任务
*
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
@Override
public void cancel(boolean removeFile) {
if (checkConfig()) {
CancelCmd cancelCmd =
(CancelCmd) CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CANCEL,
checkTaskType());
cancelCmd.removeFile = removeFile;
EventMsgUtil.getDefault().post(cancelCmd);
}
}
/**
* 重新下载
*/
@Override
public void reStart() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_RESTART,
checkTaskType()));
}
}
@Override public void save() {
if (!checkConfig()) {
ALog.e(TAG, "保存修改失败");
} else {
ALog.i(TAG, "保存成功");
}
}
}

@ -0,0 +1,72 @@
/*
* 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.aria.core.common.controller;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.CommonUtil;
/**
* 启动控制器
*/
public final class StartController extends FeatureController implements IStartFeature {
public StartController(AbsTaskWrapper wrapper) {
super(wrapper);
}
/**
* 添加任务
*
* @return 正常添加返回任务id否则返回-1
*/
public long add() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CREATE,
checkTaskType()));
return getEntity().getId();
}
return -1;
}
/**
* 开始任务
*
* @return 正常启动返回任务id否则返回-1
*/
public long start() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
checkTaskType()));
return getEntity().getId();
}
return -1;
}
@Override public long setHighestPriority() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_HIGHEST_PRIORITY,
checkTaskType()));
return getEntity().getId();
}
return -1;
}
}

@ -15,12 +15,14 @@
*/
package com.arialyy.aria.core.common.ftp;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.common.ProtocolType;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.ITargetHandler;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
/**
* D_FTP SSL/TSL 参数委托
@ -29,9 +31,9 @@ public class FTPSDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
private FtpUrlEntity mUrlEntity;
public FTPSDelegate(TARGET target) {
super(target);
mUrlEntity = mTarget.getTaskWrapper().asFtp().getUrlEntity();
public FTPSDelegate(TARGET target, AbsTaskWrapper wrapper) {
super(target, wrapper);
mUrlEntity = getTaskWrapper().asFtp().getUrlEntity();
}
/**
@ -39,7 +41,8 @@ public class FTPSDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param protocol {@link ProtocolType}
*/
public FTPSDelegate setProtocol(@ProtocolType String protocol) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FTPSDelegate<TARGET> setProtocol(@ProtocolType String protocol) {
if (TextUtils.isEmpty(protocol)) {
throw new NullPointerException("协议为空");
}
@ -52,7 +55,8 @@ public class FTPSDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param keyAlias 别名
*/
public FTPSDelegate setAlias(String keyAlias) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FTPSDelegate<TARGET> setAlias(String keyAlias) {
if (TextUtils.isEmpty(keyAlias)) {
throw new NullPointerException("别名为空");
}
@ -65,7 +69,8 @@ public class FTPSDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param storePass 私钥密码
*/
public FTPSDelegate setStorePass(String storePass) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FTPSDelegate<TARGET> setStorePass(String storePass) {
if (TextUtils.isEmpty(storePass)) {
throw new NullPointerException("证书密码为空");
}
@ -78,47 +83,12 @@ public class FTPSDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param storePath 证书路径
*/
public FTPSDelegate setStorePath(String storePath) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FTPSDelegate<TARGET> setStorePath(String storePath) {
if (TextUtils.isEmpty(storePath)) {
throw new NullPointerException("证书路径为空");
}
mUrlEntity.storePath = storePath;
return this;
}
@Override public void add() {
mTarget.add();
}
@Override public void start() {
mTarget.start();
}
@Override public void stop() {
mTarget.stop();
}
@Override public void resume() {
mTarget.resume();
}
@Override public void cancel() {
mTarget.cancel();
}
@Override public void save() {
mTarget.save();
}
@Override public void cancel(boolean removeFile) {
mTarget.cancel(removeFile);
}
@Override public void reTry() {
mTarget.reTry();
}
@Override public void reStart() {
mTarget.reStart();
}
}

@ -15,52 +15,65 @@
*/
package com.arialyy.aria.core.common.ftp;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/3/9.
* ftp 委托
*/
public class FtpDelegate<TARGET extends AbsTarget> implements IFtpTarget<TARGET> {
public class FtpDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET> {
private static final String TAG = "FtpDelegate";
private TARGET mTarget;
public FtpDelegate(TARGET target) {
mTarget = target;
public FtpDelegate(TARGET target, AbsTaskWrapper wrapper) {
super(target, wrapper);
}
@Override public TARGET charSet(String charSet) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FtpDelegate<TARGET> charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) {
throw new NullPointerException("字符编码为空");
}
mTarget.getTaskWrapper().asFtp().setCharSet(charSet);
return mTarget;
getTaskWrapper().asFtp().setCharSet(charSet);
return this;
}
@Override public TARGET login(String userName, String password) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FtpDelegate<TARGET> login(String userName, String password) {
return login(userName, password, null);
}
@Override public TARGET login(String userName, String password, String account) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FtpDelegate<TARGET> login(String userName, String password, String account) {
if (TextUtils.isEmpty(userName)) {
ALog.e(TAG, "用户名不能为null");
return mTarget;
return this;
} else if (TextUtils.isEmpty(password)) {
ALog.e(TAG, "密码不能为null");
return mTarget;
return this;
}
// urlEntity 不能在构造函数中获取,因为ftp上传时url是后于构造函数的
FtpUrlEntity urlEntity = mTarget.getTaskWrapper().asFtp().getUrlEntity();
FtpUrlEntity urlEntity = getTaskWrapper().asFtp().getUrlEntity();
urlEntity.needLogin = true;
urlEntity.user = userName;
urlEntity.password = password;
urlEntity.account = account;
return mTarget;
return this;
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public FTPSDelegate<TARGET> asFtps() {
return new FTPSDelegate<>(mTarget, mWrapper);
}
//@Override public TARGET setProxy(Proxy proxy) {

@ -15,16 +15,14 @@
*/
package com.arialyy.aria.core.common.http;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadGroupTarget;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import com.arialyy.aria.core.inf.IHttpHeaderDelegate;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
import java.util.Collection;
@ -35,39 +33,48 @@ import java.util.Set;
/**
* HTTP协议处理
*/
public class HttpDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
implements IHttpHeaderDelegate<TARGET> {
public HttpDelegate(TARGET target) {
super(target);
}
public class HttpDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET> {
public TARGET setParams(Map<String, String> params) {
mTarget.getTaskWrapper().asHttp().setParams(params);
if (mTarget instanceof DownloadGroupTarget) {
for (DTaskWrapper subTask : ((DGTaskWrapper) mTarget.getTaskWrapper()).getSubTaskWrapper()) {
subTask.asHttp().setParams(params);
public HttpDelegate(TARGET target, AbsTaskWrapper wrapper) {
super(target, wrapper);
}
/**
* 设置请求类型
*
* @param requestEnum {@link RequestEnum}
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public HttpDelegate<TARGET> setRequestType(RequestEnum requestEnum) {
getTaskWrapper().asHttp().setRequestEnum(requestEnum);
return this;
}
return mTarget;
/**
* 设置http请求参数
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public HttpDelegate<TARGET> setParams(Map<String, String> params) {
getTaskWrapper().asHttp().setParams(params);
return this;
}
public TARGET setParam(String key, String value) {
/**
* 设置http请求参数
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public HttpDelegate<TARGET> setParam(String key, String value) {
if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) {
ALog.d(TAG, "key 或value 为空");
return mTarget;
return this;
}
Map<String, String> params = mTarget.getTaskWrapper().asHttp().getParams();
Map<String, String> params = getTaskWrapper().asHttp().getParams();
if (params == null) {
params = new HashMap<>();
mTarget.getTaskWrapper().asHttp().setParams(params);
getTaskWrapper().asHttp().setParams(params);
}
params.put(key, value);
if (mTarget instanceof DownloadGroupTarget) {
for (DTaskWrapper subTask : ((DGTaskWrapper) mTarget.getTaskWrapper()).getSubTaskWrapper()) {
subTask.asHttp().setParams(params);
}
}
return mTarget;
return this;
}
/**
@ -77,17 +84,17 @@ public class HttpDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
* @param key header对应的key
* @param value header对应的value
*/
@Override
public TARGET addHeader(@NonNull String key, @NonNull String value) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public HttpDelegate<TARGET> addHeader(@NonNull String key, @NonNull String value) {
if (TextUtils.isEmpty(key)) {
ALog.w(TAG, "设置header失败,header对应的key不能为null");
return mTarget;
return this;
} else if (TextUtils.isEmpty(value)) {
ALog.w(TAG, "设置header失败,header对应的value不能为null");
return mTarget;
return this;
}
addHeader(mTarget.getTaskWrapper(), key, value);
return mTarget;
addHeader(getTaskWrapper(), key, value);
return this;
}
/**
@ -96,27 +103,23 @@ public class HttpDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param headers 一组http header数据
*/
@Override
public TARGET addHeaders(@NonNull Map<String, String> headers) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public HttpDelegate<TARGET> addHeaders(@NonNull Map<String, String> headers) {
if (headers.size() == 0) {
ALog.w(TAG, "设置header失败,map没有header数据");
return mTarget;
}
addHeaders(mTarget.getTaskWrapper(), headers);
return mTarget;
return this;
}
@Override public TARGET setUrlProxy(Proxy proxy) {
mTarget.getTaskWrapper().asHttp().setProxy(proxy);
return mTarget;
addHeaders(getTaskWrapper(), headers);
return this;
}
public TARGET setFileLenAdapter(IHttpFileLenAdapter adapter) {
if (adapter == null) {
throw new IllegalArgumentException("adapter为空");
}
mTarget.getTaskWrapper().asHttp().setFileLenAdapter(adapter);
return mTarget;
/**
* 设置代理
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public HttpDelegate<TARGET> setUrlProxy(Proxy proxy) {
getTaskWrapper().asHttp().setProxy(proxy);
return this;
}
private void addHeader(AbsTaskWrapper taskWrapper, String key, String value) {

@ -71,11 +71,6 @@ public class HttpTaskConfig implements ITaskConfig {
* 文件上传需要的key
*/
private String attachment;
/**
* 上传的文件类型
*/
private String contentType = "multipart/form-data";
private String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)";
private Proxy proxy;
/**
@ -112,22 +107,6 @@ public class HttpTaskConfig implements ITaskConfig {
this.attachment = attachment;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public boolean isChunked() {
return isChunked;
}

@ -1,30 +0,0 @@
/*
* 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.aria.core.common.http;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.inf.AbsTarget;
/**
* post处理委托类
*/
public class PostDelegate<TARGET extends AbsTarget> extends HttpDelegate<TARGET> {
public PostDelegate(TARGET target) {
super(target);
mTarget.getTaskWrapper().asHttp().setRequestEnum(RequestEnum.POST);
}
}

@ -1,68 +0,0 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.manager.SubTaskManager;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lyy on 2017/7/26.
*/
abstract class AbsDGTarget<TARGET extends AbsDGTarget> extends AbsTarget<TARGET> {
private SubTaskManager mSubTaskManager;
/**
* 获取子任务管理器
*
* @return 子任务管理器
*/
@CheckResult
public SubTaskManager getSubTaskManager() {
if (mSubTaskManager == null) {
mSubTaskManager = new SubTaskManager(getTargetName(), getTaskWrapper());
}
return mSubTaskManager;
}
@Override public DownloadGroupEntity getEntity() {
return (DownloadGroupEntity) super.getEntity();
}
@Override public DGTaskWrapper getTaskWrapper() {
return (DGTaskWrapper) super.getTaskWrapper();
}
/**
* 设置任务组别名
*/
@CheckResult
public TARGET setGroupAlias(String alias) {
if (TextUtils.isEmpty(alias)) return (TARGET) this;
getEntity().setAlias(alias);
return (TARGET) this;
}
}

@ -17,115 +17,67 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.IGroupConfigHandler;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IConfigHandler;
import com.arialyy.aria.core.manager.SubTaskManager;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lyy on 2019/4/9.
* 下载组合任务功能
*/
abstract class AbsGroupConfigHandler<TARGET extends AbsDGTarget> implements IGroupConfigHandler {
abstract class AbsGroupConfigHandler<TARGET extends AbsTarget> implements IConfigHandler {
protected String TAG;
private TARGET mTarget;
private DGTaskWrapper mWrapper;
/**
* 组任务名
*/
private String mGroupHash;
/**
* 文件夹临时路径
*/
private String mDirPathTemp;
/**
* 是否需要修改路径
*/
private boolean needModifyPath = false;
AbsGroupConfigHandler(TARGET target, DGTaskWrapper wrapper) {
private SubTaskManager mSubTaskManager;
AbsGroupConfigHandler(TARGET target, long taskId) {
TAG = CommonUtil.getClassName(getClass());
mTarget = target;
mWrapper = wrapper;
setGroupHash(wrapper.getKey());
mTarget.setTaskWrapper(wrapper);
mWrapper = TaskWrapperManager.getInstance().getGroupWrapper(DGTaskWrapper.class, taskId);
mTarget.setTaskWrapper(mWrapper);
if (getEntity() != null) {
mDirPathTemp = getEntity().getDirPath();
getTaskWrapper().setDirPathTemp(getEntity().getDirPath());
}
}
@Override public boolean isRunning() {
DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(getEntity().getKey());
return task != null && task.isRunning();
}
@CheckResult
TARGET setDirPath(String dirPath) {
mDirPathTemp = dirPath;
return mTarget;
}
/**
* 改变任务组文件夹路径修改文件夹路径会将子任务所有路径更换
* 获取子任务管理器
*
* @param newDirPath 新的文件夹路径
* @return 子任务管理器
*/
void reChangeDirPath(String newDirPath) {
ALog.d(TAG, String.format("修改新路径为:%s", newDirPath));
List<DTaskWrapper> subTasks = mWrapper.getSubTaskWrapper();
if (subTasks != null && !subTasks.isEmpty()) {
for (DTaskWrapper dte : subTasks) {
DownloadEntity de = dte.getEntity();
String oldPath = de.getFilePath();
String newPath = newDirPath + "/" + de.getFileName();
File file = new File(oldPath);
if (file.exists()) {
file.renameTo(new File(newPath));
}
de.setFilePath(newPath);
}
@CheckResult
SubTaskManager getSubTaskManager() {
if (mSubTaskManager == null) {
mSubTaskManager = new SubTaskManager(mTarget.getTargetName(), getTaskWrapper());
}
return mSubTaskManager;
}
/**
* 检查并设置文件夹路径
*
* @return {@code true} 合法
* 设置任务组别名
*/
@Override public boolean checkDirPath() {
if (TextUtils.isEmpty(mDirPathTemp)) {
ALog.e(TAG, "文件夹路径不能为null");
return false;
} else if (!mDirPathTemp.startsWith("/")) {
ALog.e(TAG, String.format("文件夹路径【%s】错误", mDirPathTemp));
return false;
void setGroupAlias(String alias) {
if (TextUtils.isEmpty(alias)) {
return;
}
File file = new File(mDirPathTemp);
if (file.isFile()) {
ALog.e(TAG, String.format("路径【%s】是文件,请设置文件夹路径", mDirPathTemp));
return false;
getEntity().setAlias(alias);
}
if ((getEntity().getDirPath() == null || !getEntity().getDirPath().equals(mDirPathTemp))
&& DbEntity.checkDataExist(DownloadGroupEntity.class, "dirPath=?", mDirPathTemp)) {
ALog.e(TAG, String.format("文件夹路径【%s】已被其它任务占用,请重新设置文件夹路径", mDirPathTemp));
return false;
@Override public boolean isRunning() {
DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(getEntity().getKey());
return task != null && task.isRunning();
}
if (TextUtils.isEmpty(getEntity().getDirPath()) || !getEntity().getDirPath()
.equals(mDirPathTemp)) {
if (!file.exists()) {
file.mkdirs();
}
needModifyPath = true;
getEntity().setDirPath(mDirPathTemp);
ALog.i(TAG, String.format("文件夹路径改变,将更新文件夹路径为:%s", mDirPathTemp));
}
return true;
@CheckResult
TARGET setDirPath(String dirPath) {
mWrapper.setDirPathTemp(dirPath);
return mTarget;
}
@Override public DownloadGroupEntity getEntity() {
@ -133,30 +85,15 @@ abstract class AbsGroupConfigHandler<TARGET extends AbsDGTarget> implements IGro
}
@Override public boolean taskExists() {
return DbEntity.checkDataExist(DownloadGroupEntity.class, "groupHash=?", mWrapper.getKey());
return getEntity().getId() != -1 && DbEntity.checkDataExist(DownloadGroupEntity.class,
"rowid=?", String.valueOf(getEntity().getId()));
}
DGTaskWrapper getTaskWrapper() {
return mWrapper;
}
boolean isNeedModifyPath() {
return needModifyPath;
}
String getDirPathTemp() {
return mDirPathTemp;
}
TARGET getTarget() {
return mTarget;
}
public String getGroupHash() {
return mGroupHash;
}
public void setGroupHash(String groupHash) {
this.mGroupHash = groupHash;
}
}

@ -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.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.inf.ITargetHandler;
import com.arialyy.aria.core.inf.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.RecordUtil;
import java.io.File;
/**
* 检查下载任务实体
*/
public class CheckDEntityUtil {
private final String TAG = "CheckDLoadEntity";
private DTaskWrapper mWrapper;
private DownloadEntity mEntity;
public static CheckDEntityUtil newInstance(DTaskWrapper wrapper) {
return new CheckDEntityUtil(wrapper);
}
private CheckDEntityUtil(DTaskWrapper wrapper) {
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}
public boolean checkEntity() {
boolean b = checkFtps() && checkUrl() && checkFilePath();
if (b) {
mEntity.save();
}
if (mWrapper.getRequestType() == ITaskWrapper.M3U8_VOD
|| mWrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) {
handleM3U8();
}
return b;
}
private void handleM3U8() {
File file = new File(mWrapper.getmTempFilePath());
// 缓存文件夹格式:问文件夹/.文件名_码率
String cacheDir = String.format("%s/.%s_%s", file.getParent(), file.getName(),
mWrapper.asM3U8().getBandWidth());
mWrapper.asM3U8().setCacheDir(cacheDir);
mEntity.getM3U8Entity().setCacheDir(cacheDir);
if (mWrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
if (mEntity.getFileSize() == 0) {
ALog.w(TAG,
"由于m3u8协议的特殊性质,无法有效快速获取到正确到文件长度,如果你需要显示文件中长度,你需要自行设置文件长度:.asM3U8().asVod().setFileSize(xxx)");
}
} else if (mWrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) {
if (file.exists()) {
ALog.w(TAG, "对于直播来说,每次下载都是一个新文件,所以你需要设置新都文件路径,否则Aria框架将会覆盖已下载的文件");
file.delete();
}
}
if (mWrapper.asM3U8().getBandWidthUrlConverter() != null
&& mWrapper.asM3U8().getBandWidth() == 0) {
ALog.w(TAG, "你已经设置了码率url转换器,但是没有设置码率,Aria框架将采用第一个获取到的码率");
}
}
private boolean checkFilePath() {
String filePath = mWrapper.getmTempFilePath();
if (TextUtils.isEmpty(filePath)) {
ALog.e(TAG, "下载失败,文件保存路径为null");
return false;
} else if (!filePath.startsWith("/")) {
ALog.e(TAG, String.format("下载失败,文件保存路径【%s】错误", filePath));
return false;
}
File file = new File(filePath);
if (file.isDirectory()) {
if (mWrapper.getRequestType() == ITargetHandler.D_HTTP
|| mWrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
ALog.e(TAG,
String.format("下载失败,保存路径【%s】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip", filePath));
return false;
} else if (mWrapper.getRequestType() == ITargetHandler.D_FTP) {
filePath += mEntity.getFileName();
}
} else {
// http文件名设置
if (TextUtils.isEmpty(mEntity.getFileName())) {
mEntity.setFileName(file.getName());
}
}
return checkPathConflicts(filePath);
}
/**
* 检查路径冲突
*/
private boolean checkPathConflicts(String filePath) {
//设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
if (!filePath.equals(mEntity.getFilePath())) {
// 检查路径冲突
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
if (!mWrapper.isForceDownload()) {
ALog.e(TAG, String.format("下载失败,保存路径【%s】已经被其它任务占用,请设置其它保存路径", filePath));
return false;
} else {
ALog.w(TAG, String.format("保存路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));
RecordUtil.delTaskRecord(filePath, RecordHandler.TYPE_DOWNLOAD);
}
}
File oldFile = new File(mEntity.getFilePath());
File newFile = new File(filePath);
mEntity.setFilePath(filePath);
mEntity.setFileName(newFile.getName());
// 如过使用Content-Disposition中的文件名,将不会执行重命名工作
if (mWrapper.asHttp().isUseServerFileName()
|| mWrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) {
return true;
}
if (oldFile.exists()) {
// 处理普通任务的重命名
RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
ALog.i(TAG, String.format("将任务重命名为:%s", newFile.getName()));
} else if (RecordUtil.blockTaskExists(oldFile.getPath())) {
// 处理分块任务的重命名
RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
ALog.i(TAG, String.format("将分块任务重命名为:%s", newFile.getName()));
}
}
return true;
}
private boolean checkUrl() {
final String url = mEntity.getUrl();
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "下载失败,url为null");
return false;
} else if (!CheckUtil.checkUrlNotThrow(url)) {
ALog.e(TAG, "下载失败,url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "下载失败,url【" + url + "】不合法");
return false;
}
if (!TextUtils.isEmpty(mWrapper.getmTempUrl())) {
mEntity.setUrl(mWrapper.getmTempUrl());
}
return true;
}
private boolean checkFtps() {
if (mWrapper.asFtp().getUrlEntity().isFtps) {
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return true;
}
}

@ -0,0 +1,254 @@
/*
* 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.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.RecordUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CheckDGEntityUtil {
private final String TAG = "CheckDGEntityUtil";
private DGTaskWrapper mWrapper;
private DownloadGroupEntity mEntity;
/**
* 是否需要修改路径
*/
private boolean needModifyPath = false;
public static CheckDGEntityUtil newInstance(DGTaskWrapper wrapper) {
return new CheckDGEntityUtil(wrapper);
}
private CheckDGEntityUtil(DGTaskWrapper wrapper) {
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}
/**
* 检查并设置文件夹路径
*
* @return {@code true} 合法
*/
private boolean checkDirPath() {
if (TextUtils.isEmpty(mWrapper.getDirPathTemp())) {
ALog.e(TAG, "文件夹路径不能为null");
return false;
} else if (!mWrapper.getDirPathTemp().startsWith("/")) {
ALog.e(TAG, String.format("文件夹路径【%s】错误", mWrapper.getDirPathTemp()));
return false;
}
File file = new File(mWrapper.getDirPathTemp());
if (file.isFile()) {
ALog.e(TAG, String.format("路径【%s】是文件,请设置文件夹路径", mWrapper.getDirPathTemp()));
return false;
}
if ((mEntity.getDirPath() == null || !mEntity.getDirPath().equals(mWrapper.getDirPathTemp()))
&& DbEntity.checkDataExist(DownloadGroupEntity.class, "dirPath=?",
mWrapper.getDirPathTemp())) {
ALog.e(TAG, String.format("文件夹路径【%s】已被其它任务占用,请重新设置文件夹路径", mWrapper.getDirPathTemp()));
return false;
}
if (TextUtils.isEmpty(mEntity.getDirPath()) || !mEntity.getDirPath()
.equals(mWrapper.getDirPathTemp())) {
if (!file.exists()) {
file.mkdirs();
}
needModifyPath = true;
mEntity.setDirPath(mWrapper.getDirPathTemp());
ALog.i(TAG, String.format("文件夹路径改变,将更新文件夹路径为:%s", mWrapper.getDirPathTemp()));
}
return true;
}
/**
* 改变任务组文件夹路径修改文件夹路径会将子任务所有路径更换
*
* @param newDirPath 新的文件夹路径
*/
private void reChangeDirPath(String newDirPath) {
ALog.d(TAG, String.format("修改新路径为:%s", newDirPath));
List<DTaskWrapper> subTasks = mWrapper.getSubTaskWrapper();
if (subTasks != null && !subTasks.isEmpty()) {
for (DTaskWrapper dte : subTasks) {
DownloadEntity de = dte.getEntity();
String oldPath = de.getFilePath();
String newPath = newDirPath + "/" + de.getFileName();
File file = new File(oldPath);
if (file.exists()) {
file.renameTo(new File(newPath));
}
de.setFilePath(newPath);
}
}
}
public boolean checkEntity() {
if (!checkDirPath()) {
return false;
}
if (!checkSubName()) {
return false;
}
if (!checkUrls()) {
return false;
}
if (!mWrapper.isUnknownSize() && mEntity.getFileSize() == 0) {
ALog.e(TAG, "组合任务必须设置文件文件大小,默认需要强制设置文件大小。如果无法获取到总长度,请调用#unknownSize()来标志该组合任务");
return false;
}
if (mWrapper.asHttp().getRequestEnum() == RequestEnum.POST) {
for (DTaskWrapper subTask : mWrapper.getSubTaskWrapper()) {
subTask.asHttp().setRequestEnum(RequestEnum.POST);
}
}
if (needModifyPath) {
reChangeDirPath(mWrapper.getDirPathTemp());
}
if (!mWrapper.getSubNameTemp().isEmpty()) {
updateSingleSubFileName();
}
saveEntity();
return true;
}
private void saveEntity() {
mEntity.save();
DbEntity.saveAll(mEntity.getSubEntities());
}
/**
* 更新所有改动的子任务文件名
*/
private void updateSingleSubFileName() {
List<DTaskWrapper> entities = mWrapper.getSubTaskWrapper();
int i = 0;
for (DTaskWrapper taskWrapper : entities) {
if (i < mWrapper.getSubNameTemp().size()) {
String newName = mWrapper.getSubNameTemp().get(i);
DownloadEntity entity = taskWrapper.getEntity();
if (!newName.equals(entity.getFileName())) {
String oldPath = mEntity.getDirPath() + "/" + entity.getFileName();
String newPath = mEntity.getDirPath() + "/" + newName;
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=? or isComplete='true'",
newPath)) {
ALog.w(TAG, String.format("更新文件名失败,路径【%s】已存在或文件已下载", newPath));
return;
}
RecordUtil.modifyTaskRecord(oldPath, newPath);
entity.setFilePath(newPath);
entity.setFileName(newName);
}
}
i++;
}
}
/**
* 检查urls是否合法并删除不合法的子任务
*
* @return {@code true} 合法
*/
private boolean checkUrls() {
if (mEntity.getUrls().isEmpty()) {
ALog.e(TAG, "下载失败,子任务下载列表为null");
return false;
}
Set<String> repeated = new HashSet<>();
List<String> results = new ArrayList<>();
for (String url : mEntity.getUrls()) {
if (!repeated.add(url)) {
results.add(url);
}
}
if (!results.isEmpty()) {
ALog.e(TAG, String.format("组合任务中有url重复,重复的url:%s", Arrays.toString(results.toArray())));
return false;
}
Set<Integer> delItem = new HashSet<>();
int i = 0;
for (String url : mEntity.getUrls()) {
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "子任务url为null,即将删除该子任务。");
delItem.add(i);
continue;
} else if (!url.startsWith("http")) {
ALog.e(TAG, "子任务url【" + url + "】错误,即将删除该子任务。");
delItem.add(i);
continue;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "子任务url【" + url + "】不合法,即将删除该子任务。");
delItem.add(i);
continue;
}
i++;
}
for (int index : delItem) {
mEntity.getUrls().remove(index);
if (mWrapper.getSubNameTemp() != null && !mWrapper.getSubNameTemp().isEmpty()) {
mWrapper.getSubNameTemp().remove(index);
}
}
mEntity.setGroupHash(CommonUtil.getMd5Code(mEntity.getUrls()));
return true;
}
/**
* 如果用户设置了子任务文件名检查子任务文件名
*
* @return {@code true} 合法
*/
private boolean checkSubName() {
if (mWrapper.getSubNameTemp() == null || mWrapper.getSubNameTemp().isEmpty()) {
return true;
}
if (mEntity.getUrls().size() != mWrapper.getSubNameTemp().size()) {
ALog.e(TAG, "子任务文件名必须和子任务数量一致");
return false;
}
return true;
}
}

@ -0,0 +1,133 @@
/*
* 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.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import java.io.File;
public class CheckFtpDirEntityUtil {
private final String TAG = "CheckFtpDirEntityUtil";
private DGTaskWrapper mWrapper;
private DownloadGroupEntity mEntity;
public static CheckFtpDirEntityUtil newInstance(DGTaskWrapper wrapper) {
return new CheckFtpDirEntityUtil(wrapper);
}
private CheckFtpDirEntityUtil(DGTaskWrapper wrapper) {
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}
/**
* 检查并设置文件夹路径
*
* @return {@code true} 合法
*/
private boolean checkDirPath() {
if (TextUtils.isEmpty(mWrapper.getDirPathTemp())) {
ALog.e(TAG, "文件夹路径不能为null");
return false;
} else if (!mWrapper.getDirPathTemp().startsWith("/")) {
ALog.e(TAG, String.format("文件夹路径【%s】错误", mWrapper.getDirPathTemp()));
return false;
}
File file = new File(mWrapper.getDirPathTemp());
if (file.isFile()) {
ALog.e(TAG, String.format("路径【%s】是文件,请设置文件夹路径", mWrapper.getDirPathTemp()));
return false;
}
if ((mEntity.getDirPath() == null || !mEntity.getDirPath().equals(mWrapper.getDirPathTemp()))
&& DbEntity.checkDataExist(DownloadGroupEntity.class, "dirPath=?",
mWrapper.getDirPathTemp())) {
ALog.e(TAG, String.format("文件夹路径【%s】已被其它任务占用,请重新设置文件夹路径", mWrapper.getDirPathTemp()));
return false;
}
if (TextUtils.isEmpty(mEntity.getDirPath()) || !mEntity.getDirPath()
.equals(mWrapper.getDirPathTemp())) {
if (!file.exists()) {
file.mkdirs();
}
mEntity.setDirPath(mWrapper.getDirPathTemp());
ALog.i(TAG, String.format("文件夹路径改变,将更新文件夹路径为:%s", mWrapper.getDirPathTemp()));
}
return true;
}
public boolean checkEntity() {
boolean b = checkDirPath() && checkUrl();
if (b) {
mEntity.save();
if (mWrapper.getSubTaskWrapper() != null) {
//初始化子项的登录信息
FtpUrlEntity tUrlEntity = mWrapper.asFtp().getUrlEntity();
for (DTaskWrapper wrapper : mWrapper.getSubTaskWrapper()) {
FtpUrlEntity urlEntity = wrapper.asFtp().getUrlEntity();
urlEntity.needLogin = tUrlEntity.needLogin;
urlEntity.account = tUrlEntity.account;
urlEntity.user = tUrlEntity.user;
urlEntity.password = tUrlEntity.password;
// 处理ftps详细
if (tUrlEntity.isFtps) {
urlEntity.isFtps = true;
urlEntity.protocol = tUrlEntity.protocol;
urlEntity.storePath = tUrlEntity.storePath;
urlEntity.storePass = tUrlEntity.storePass;
urlEntity.keyAlias = tUrlEntity.keyAlias;
}
}
}
}
if (mWrapper.asFtp().getUrlEntity().isFtps) {
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return b;
}
/**
* 检查普通任务的下载地址
*
* @return {@code true}地址合法
*/
private boolean checkUrl() {
final String url = mEntity.getKey();
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "下载失败,url为null");
return false;
} else if (!url.startsWith("ftp")) {
ALog.e(TAG, "下载失败,url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "下载失败,url【" + url + "】不合法");
return false;
}
return true;
}
}

@ -18,6 +18,7 @@ package com.arialyy.aria.core.download;
import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.config.DGroupConfig;
import com.arialyy.aria.core.inf.AbsGroupTaskWrapper;
import java.util.ArrayList;
import java.util.List;
/**
@ -29,10 +30,36 @@ public class DGTaskWrapper extends AbsGroupTaskWrapper<DownloadGroupEntity, DTas
private boolean unknownSize = false;
/**
* 保存临时设置的文件夹路径
*/
private String dirPathTemp;
/**
* 子任务文件名
*/
private List<String> subNameTemp = new ArrayList<>();
public DGTaskWrapper(DownloadGroupEntity entity) {
super(entity);
}
public List<String> getSubNameTemp() {
return subNameTemp;
}
public void setSubNameTemp(List<String> subNameTemp) {
this.subNameTemp = subNameTemp;
}
public String getDirPathTemp() {
return dirPathTemp;
}
public void setDirPathTemp(String mDirPathTemp) {
this.dirPathTemp = mDirPathTemp;
}
@Override
public void setSubTaskWrapper(List<DTaskWrapper> subTaskEntities) {
this.subTaskEntities = subTaskEntities;

@ -16,57 +16,45 @@
package com.arialyy.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IConfigHandler;
import com.arialyy.aria.core.inf.ITargetHandler;
import com.arialyy.aria.core.inf.ITaskWrapper;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.RecordUtil;
import java.io.File;
/**
* Created by AriaL on 2019/4/5.
* 普通下载任务通用功能处理
*/
class DNormalConfigHandler<TARGET extends AbsDTarget> implements IConfigHandler {
class DNormalConfigHandler<TARGET extends AbsTarget> implements IConfigHandler {
private final String TAG = "DNormalDelegate";
private DownloadEntity mEntity;
private TARGET mTarget;
private String mNewUrl;
/**
* 设置的文件保存路径的临时变量
*/
private String mTempFilePath;
private DTaskWrapper mWrapper;
/**
* {@code true}强制下载不考虑文件路径是否被占用
*/
private boolean forceDownload = false;
/**
* 资源地址
*/
private String mUrl;
DNormalConfigHandler(TARGET target, String url, String targetName) {
/**
* @param taskId 第一次下载taskId为-1
*/
DNormalConfigHandler(TARGET target, long taskId, String targetName) {
this.mTarget = target;
initTarget(url, targetName);
initTarget(taskId, targetName);
}
private void initTarget(String url, String targetName) {
DTaskWrapper taskWrapper =
TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, url);
mEntity = taskWrapper.getEntity();
private void initTarget(long taskId, String targetName) {
mWrapper = TaskWrapperManager.getInstance().getNormalTaskWrapper(DTaskWrapper.class, taskId);
mEntity = mWrapper.getEntity();
mUrl = url;
mTarget.setTargetName(targetName);
mTarget.setTaskWrapper(taskWrapper);
mTarget.setTaskWrapper(mWrapper);
if (mEntity != null) {
mTempFilePath = mEntity.getDownloadPath();
getWrapper().setmTempFilePath(mEntity.getFilePath());
}
}
@ -79,13 +67,13 @@ class DNormalConfigHandler<TARGET extends AbsDTarget> implements IConfigHandler
ALog.e(TAG, "url更新失败,新的下载url和旧的url一致");
return mTarget;
}
mNewUrl = newUrl;
mTarget.getTaskWrapper().setRefreshInfo(true);
getWrapper().setRefreshInfo(true);
getWrapper().setmTempUrl(newUrl);
return mTarget;
}
@Override public DownloadEntity getEntity() {
return mTarget.getEntity();
return (DownloadEntity) mTarget.getEntity();
}
@Override public boolean taskExists() {
@ -96,140 +84,24 @@ class DNormalConfigHandler<TARGET extends AbsDTarget> implements IConfigHandler
return DownloadTaskQueue.getInstance().taskIsRunning(mEntity.getKey());
}
@Override public boolean checkEntity() {
boolean b = checkUrl() && checkFilePath();
if (b) {
mEntity.save();
}
if (mTarget.getTaskWrapper().getRequestType() == ITaskWrapper.M3U8_VOD
|| mTarget.getTaskWrapper().getRequestType() == ITaskWrapper.M3U8_LIVE) {
checkM3U8();
}
return b;
}
private void checkM3U8() {
File file = new File(mTempFilePath);
DTaskWrapper wrapper = (DTaskWrapper) mTarget.getTaskWrapper();
// 缓存文件夹格式:问文件夹/.文件名_码率
String cacheDir = String.format("%s/.%s_%s", file.getParent(), file.getName(),
wrapper.asM3U8().getBandWidth());
wrapper.asM3U8().setCacheDir(cacheDir);
mEntity.getM3U8Entity().setCacheDir(cacheDir);
if (wrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
if (mEntity.getFileSize() == 0) {
ALog.w(TAG,
"由于m3u8协议的特殊性质,无法有效快速获取到正确到文件长度,如果你需要显示文件中长度,你需要自行设置文件长度:.asM3U8().asVod().setFileSize(xxx)");
}
} else if (wrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) {
if (file.exists()) {
ALog.w(TAG, "对于直播来说,每次下载都是一个新文件,所以你需要设置新都文件路径,否则Aria框架将会覆盖已下载的文件");
file.delete();
}
}
if (wrapper.asM3U8().getBandWidthUrlConverter() != null
&& wrapper.asM3U8().getBandWidth() == 0) {
ALog.w(TAG, "你已经设置了码率url转换器,但是没有设置码率,Aria框架将采用第一个获取到的码率");
}
}
@Override public boolean checkFilePath() {
String filePath = mTempFilePath;
if (TextUtils.isEmpty(filePath)) {
ALog.e(TAG, "下载失败,文件保存路径为null");
return false;
} else if (!filePath.startsWith("/")) {
ALog.e(TAG, String.format("下载失败,文件保存路径【%s】错误", filePath));
return false;
}
File file = new File(filePath);
if (file.isDirectory()) {
if (mTarget.getTargetType() == ITargetHandler.D_HTTP
|| mTarget.getTaskWrapper().getRequestType() == ITaskWrapper.M3U8_VOD) {
ALog.e(TAG,
String.format("下载失败,保存路径【%s】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip", filePath));
return false;
} else if (mTarget.getTargetType() == ITargetHandler.D_FTP) {
filePath += mEntity.getFileName();
}
} else {
// http文件名设置
if (TextUtils.isEmpty(mEntity.getFileName())) {
mEntity.setFileName(file.getName());
}
}
//设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
if (!filePath.equals(mEntity.getFilePath())) {
// 检查路径冲突
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
if (!forceDownload) {
ALog.e(TAG, String.format("下载失败,保存路径【%s】已经被其它任务占用,请设置其它保存路径", filePath));
return false;
} else {
ALog.w(TAG, String.format("保存路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));
RecordUtil.delTaskRecord(filePath, RecordHandler.TYPE_DOWNLOAD);
mTarget.setTaskWrapper(
TaskWrapperManager.getInstance().getHttpTaskWrapper(DTaskWrapper.class, mUrl));
}
}
File oldFile = new File(mEntity.getFilePath());
File newFile = new File(filePath);
mEntity.setFilePath(filePath);
mEntity.setFileName(newFile.getName());
// 如过使用Content-Disposition中的文件名,将不会执行重命名工作
if (mTarget.getTaskWrapper().asHttp().isUseServerFileName()
|| mTarget.getTaskWrapper().getRequestType() == ITaskWrapper.M3U8_LIVE) {
return true;
}
if (oldFile.exists()) {
// 处理普通任务的重命名
RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
ALog.i(TAG, String.format("将任务重命名为:%s", newFile.getName()));
} else if (RecordUtil.blockTaskExists(oldFile.getPath())) {
// 处理分块任务的重命名
RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath());
ALog.i(TAG, String.format("将分块任务重命名为:%s", newFile.getName()));
}
}
return true;
}
@Override public boolean checkUrl() {
final String url = mEntity.getUrl();
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "下载失败,url为null");
return false;
} else if (!CheckUtil.checkUrlNotThrow(url)) {
ALog.e(TAG, "下载失败,url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "下载失败,url【" + url + "】不合法");
return false;
}
if (!TextUtils.isEmpty(mNewUrl)) {
mEntity.setUrl(mNewUrl);
}
return true;
}
void setForceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
getWrapper().setForceDownload(forceDownload);
}
void setUrl(String url) {
this.mUrl = url;
mEntity.setUrl(url);
}
String getUrl() {
return mUrl;
return mEntity.getUrl();
}
void setTempFilePath(String tempFilePath) {
getWrapper().setmTempFilePath(tempFilePath);
}
void setTempFilePath(String mTempFilePath) {
this.mTempFilePath = mTempFilePath;
private DTaskWrapper getWrapper() {
return mWrapper;
}
}

@ -37,6 +37,20 @@ public class DTaskWrapper extends AbsTaskWrapper<DownloadEntity> {
private M3U8TaskConfig m3u8TaskConfig;
/**
* 文件下载url的临时保存变量
*/
private String mTempUrl;
/**
* 文件保存路径的临时变量
*/
private String mTempFilePath;
/**
* {@code true}强制下载不考虑文件路径是否被占用
*/
private boolean forceDownload = false;
public DTaskWrapper(DownloadEntity entity) {
super(entity);
}
@ -78,4 +92,28 @@ public class DTaskWrapper extends AbsTaskWrapper<DownloadEntity> {
public void setGroupTask(boolean groupTask) {
isGroupTask = groupTask;
}
public String getmTempUrl() {
return mTempUrl;
}
public void setmTempUrl(String mTempUrl) {
this.mTempUrl = mTempUrl;
}
public String getmTempFilePath() {
return mTempFilePath;
}
public void setmTempFilePath(String mTempFilePath) {
this.mTempFilePath = mTempFilePath;
}
public boolean isForceDownload() {
return forceDownload;
}
public void setForceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
}
}

@ -22,6 +22,7 @@ import com.arialyy.annotations.TaskEnum;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.CancelAllCmd;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.ProxyHelper;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.AbsEntity;
@ -59,101 +60,91 @@ public class DownloadReceiver extends AbsReceiver {
}
/**
* 使用下载实体执行下载操作
*
* @param entity 下载实体
*/
@CheckResult
public DownloadTarget load(DownloadEntity entity) {
CheckUtil.checkUrlInvalidThrow(entity.getUrl());
return new DownloadTarget(entity, targetName);
}
/**
* 加载Httphttps单任务下载地址
* 加载Httphttps单任务下载地址用于任务第一次下载如果需要控制任务停止或删除等操作请使用{@link #load(long)}
*
* @param url 下载地址
*/
@CheckResult
public DownloadTarget load(@NonNull String url) {
public HttpStartTarget load(@NonNull String url) {
CheckUtil.checkUrlInvalidThrow(url);
return new DownloadTarget(url, targetName);
return new HttpStartTarget(url, targetName);
}
/**
* 加载下载地址如果任务组的中的下载地址改变了则任务从新的一个任务组
* 用于任务停止删除等操作
*
* @param urls 任务组子任务下载地址列表
* @deprecated {@link #loadGroup(DownloadGroupEntity)}
* @param taskId 任务id可从{@link AbsStartTarget#start()}{@link AbsStartTarget#add()}{@link
* AbsEntity#getId()}读取任务id
*/
@Deprecated
@CheckResult
public DownloadGroupTarget load(List<String> urls) {
return loadGroup(urls);
public HttpNormalTarget load(long taskId) {
CheckUtil.checkTaskId(taskId);
return new HttpNormalTarget(taskId, targetName);
}
/**
* 加载下载地址如果任务组的中的下载地址改变了则任务从新的一个任务组
* 加载组合任务用于任务第一次下载如果需要控制任务停止或删除等操作请使用{@link #loadGroup(long)}
*
* @param urls 组合任务只任务列被如果任务组的中的下载地址改变了则任务从新的一个任务组
*/
@CheckResult
public DownloadGroupTarget loadGroup(List<String> urls) {
public GroupStartTarget loadGroup(List<String> urls) {
CheckUtil.checkDownloadUrls(urls);
return new DownloadGroupTarget(urls, targetName);
return new GroupStartTarget(urls, targetName);
}
/**
* 使用下载实体执行FTP下载操作
* 加载组合任务用于任务停止删除等操作
*
* @param entity 下载实体
* @param taskId 任务id可从{@link AbsStartTarget#start()}{@link AbsStartTarget#add()}{@link
* * AbsEntity#getId()}读取任务id
*/
@CheckResult
public FtpDownloadTarget loadFtp(DownloadEntity entity) {
CheckUtil.checkUrlInvalidThrow(entity.getUrl());
return new FtpDownloadTarget(entity, targetName);
public GroupNormalTarget loadGroup(long taskId) {
CheckUtil.checkTaskId(taskId);
return new GroupNormalTarget(taskId, targetName);
}
/**
* 加载ftp单任务下载地址
* 加载ftp单任务下载地址用于任务第一次下载如果需要控制任务停止或删除等操作请使用{@link #loadFtp(long)}
*/
@CheckResult
public FtpDownloadTarget loadFtp(@NonNull String url) {
public FtpStartTarget loadFtp(@NonNull String url) {
CheckUtil.checkUrlInvalidThrow(url);
return new FtpDownloadTarget(url, targetName);
return new FtpStartTarget(url, targetName);
}
/**
* 使用任务组实体执行任务组的实体执行任务组的下载操作后续版本会删除该api
* 用于任务停止删除等操作
*
* @param groupEntity 如果加载的任务实体没有子项的下载地址
* 那么你需要使用{@link DownloadGroupTarget#setGroupUrl(List)}设置子项的下载地址
* @deprecated 请使用 {@link #loadGroup(DownloadGroupEntity)}
* @param taskId 任务id可从{@link AbsStartTarget#start()}{@link AbsStartTarget#add()}{@link
* AbsEntity#getId()}读取任务id
*/
@Deprecated
@CheckResult
public DownloadGroupTarget load(DownloadGroupEntity groupEntity) {
CheckUtil.checkDownloadUrls(groupEntity.getUrls());
return loadGroup(groupEntity);
public FtpNormalTarget loadFtp(long taskId) {
CheckUtil.checkTaskId(taskId);
return new FtpNormalTarget(taskId, targetName);
}
/**
* 使用任务组实体执行任务组的实体执行任务组的下载操作
*
* @param groupEntity 如果加载的任务实体没有子项的下载地址
* 那么你需要使用{@link DownloadGroupTarget#setGroupUrl(List)}设置子项的下载地址
* 加载ftp文件夹下载地址用于任务第一次下载如果需要控制任务停止或删除等操作请使用{@link #loadFtpDir(long)}
*/
@CheckResult
public DownloadGroupTarget loadGroup(DownloadGroupEntity groupEntity) {
CheckUtil.checkDownloadUrls(groupEntity.getUrls());
return new DownloadGroupTarget(groupEntity, targetName);
public FtpDirStartTarget loadFtpDir(@NonNull String dirUrl) {
CheckUtil.checkUrlInvalidThrow(dirUrl);
return new FtpDirStartTarget(dirUrl, targetName);
}
/**
* 加载ftp文件夹下载地址
* 加载ftp文件夹下载地址用于任务停止删除等操作
*
* @param taskId 任务id可从{@link AbsStartTarget#start()}{@link AbsStartTarget#add()}{@link
* AbsEntity#getId()}读取任务id
*/
@CheckResult
public FtpDirDownloadTarget loadFtpDir(@NonNull String dirUrl) {
CheckUtil.checkUrlInvalidThrow(dirUrl);
return new FtpDirDownloadTarget(dirUrl, targetName);
public FtpDirNormalTarget loadFtpDir(long taskId) {
CheckUtil.checkTaskId(taskId);
return new FtpDirNormalTarget(taskId, targetName);
}
/**
@ -232,37 +223,56 @@ public class DownloadReceiver extends AbsReceiver {
}
/**
* 通过下载链接获取下载实体
* 获取任务实体
*
* @param taskId 任务实体唯一id
*/
public DownloadEntity getDownloadEntity(long taskId) {
CheckUtil.checkTaskId(taskId);
return DbEntity.findFirst(DownloadEntity.class, "rowid=?", String.valueOf(taskId));
}
/**
* 获取第一个匹配url的下载实体如果你有多个任务的下载地址都相同请使用{@link #getDownloadEntity(long)}
* {@link #getDownloadEntity(String)}
*
* @return 如果url错误或查找不到数据则返回null
*/
public DownloadEntity getDownloadEntity(String downloadUrl) {
public DownloadEntity getFirstDownloadEntity(String downloadUrl) {
CheckUtil.checkUrl(downloadUrl);
return DbEntity.findFirst(DownloadEntity.class, "url=? and isGroupChild='false'", downloadUrl);
}
/**
* 通过下载链接获取下载实体
*
* @return 如果url错误或查找不到数据则返回null
*/
public List<DownloadEntity> getDownloadEntity(String downloadUrl) {
CheckUtil.checkUrl(downloadUrl);
return DbEntity.findDatas(DownloadEntity.class, "url=? and isGroupChild='false'", downloadUrl);
}
/**
* 获取组合任务实在实体
*
* @param urls 组合任务的url
* @param taskId 组合任务实体id
* @return 如果实体不存在返回null
*/
public DownloadGroupEntity getDownloadGroupEntity(List<String> urls) {
CheckUtil.checkDownloadUrls(urls);
return DbDataHelper.getDGEntity(CommonUtil.getMd5Code(urls));
public DownloadGroupEntity getGroupEntity(long taskId) {
CheckUtil.checkTaskId(taskId);
return DbDataHelper.getDGEntity(taskId);
}
/**
* 获取组合任务实在实体
*
* @param key 组合任务的key{@link DownloadGroupEntity#getKey()}
* @param urls 组合任务的url
* @return 如果实体不存在返回null
*/
public DownloadGroupEntity getDownloadGroupEntity(String key) {
if (TextUtils.isEmpty(key)) {
throw new IllegalArgumentException("key为空");
}
return DbDataHelper.getDGEntity(key);
public DownloadGroupEntity getGroupEntity(List<String> urls) {
CheckUtil.checkDownloadUrls(urls);
return DbDataHelper.getDGEntity(CommonUtil.getMd5Code(urls));
}
/**

@ -1,161 +0,0 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.http.GetDelegate;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.common.http.PostDelegate;
import com.arialyy.aria.core.download.m3u8.M3U8Delegate;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import java.net.Proxy;
import java.util.Map;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
public class DownloadTarget extends AbsDTarget<DownloadTarget> {
private HttpDelegate<DownloadTarget> mHttpDelegate;
private DNormalConfigHandler<DownloadTarget> mConfigHandler;
DownloadTarget(DownloadEntity entity, String targetName) {
this(entity.getUrl(), targetName);
}
DownloadTarget(String url, String targetName) {
mConfigHandler = new DNormalConfigHandler<>(this, url, targetName);
mHttpDelegate = new HttpDelegate<>(this);
}
/**
* Post处理
*/
@CheckResult
public PostDelegate asPost() {
mHttpDelegate = new PostDelegate<>(this);
return (PostDelegate) mHttpDelegate;
}
/**
* get处理
*/
@CheckResult
public GetDelegate asGet() {
mHttpDelegate = new GetDelegate<>(this);
return (GetDelegate) mHttpDelegate;
}
@CheckResult
public M3U8Delegate<DownloadTarget> asM3U8() {
return new M3U8Delegate<>(this);
}
/**
* 是否使用服务器通过content-disposition传递的文件名内容格式{@code attachment;filename=***}
* 如果获取不到服务器文件名则使用用户设置的文件名
*
* @param use {@code true} 使用
*/
@CheckResult
public DownloadTarget useServerFileName(boolean use) {
getTaskWrapper().asHttp().setUseServerFileName(use);
return this;
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*
* @param filePath 路径必须为文件路径不能为文件夹路径
*/
@CheckResult
public DownloadTarget setFilePath(@NonNull String filePath) {
mConfigHandler.setTempFilePath(filePath);
return this;
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*
* @param filePath 路径必须为文件路径不能为文件夹路径
* @param forceDownload {@code true}强制下载不考虑文件路径是否被占用
*/
@CheckResult
public DownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
mConfigHandler.setTempFilePath(filePath);
mConfigHandler.setForceDownload(forceDownload);
return this;
}
/**
* 如果你需要使用header中特定的key来设置文件长度或有定制文件长度的需要那么你可以通过该方法自行处理文件长度
*/
public DownloadTarget setFileLenAdapter(IHttpFileLenAdapter adapter) {
return mHttpDelegate.setFileLenAdapter(adapter);
}
/**
* 从header中获取文件描述信息
*/
public String getContentDisposition() {
return getEntity().getDisposition();
}
@Override public DownloadTarget updateUrl(String newUrl) {
return mConfigHandler.updateUrl(newUrl);
}
@Override public int getTargetType() {
return D_HTTP;
}
/**
* 设置URL的代理
*
* @param proxy {@link Proxy}
*/
@CheckResult
public DownloadTarget setUrlProxy(Proxy proxy) {
return mHttpDelegate.setUrlProxy(proxy);
}
@CheckResult
public DownloadTarget addHeader(@NonNull String key, @NonNull String value) {
return mHttpDelegate.addHeader(key, value);
}
@CheckResult
public DownloadTarget addHeaders(Map<String, String> headers) {
return mHttpDelegate.addHeaders(headers);
}
@Override protected boolean checkEntity() {
return mConfigHandler.checkEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
}

@ -15,77 +15,17 @@
*/
package com.arialyy.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
/**
* Created by lyy on 2017/4/9.
* ftp文件夹下载功能代理
*/
class FtpDirConfigHandler extends AbsGroupConfigHandler<FtpDirDownloadTarget> {
FtpDirConfigHandler(FtpDirDownloadTarget target, DGTaskWrapper wrapper) {
super(target, wrapper);
wrapper.setRequestType(AbsTaskWrapper.D_FTP_DIR);
}
class FtpDirConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHandler<TARGET> {
@Override public boolean checkEntity() {
boolean b = checkDirPath() && checkUrl();
if (b) {
getEntity().save();
if (getTaskWrapper().getSubTaskWrapper() != null) {
//初始化子项的登录信息
FtpUrlEntity tUrlEntity = getTaskWrapper().asFtp().getUrlEntity();
for (DTaskWrapper wrapper : getTaskWrapper().getSubTaskWrapper()) {
FtpUrlEntity urlEntity = wrapper.asFtp().getUrlEntity();
urlEntity.needLogin = tUrlEntity.needLogin;
urlEntity.account = tUrlEntity.account;
urlEntity.user = tUrlEntity.user;
urlEntity.password = tUrlEntity.password;
// 处理ftps详细
if (tUrlEntity.isFtps) {
urlEntity.isFtps = true;
urlEntity.protocol = tUrlEntity.protocol;
urlEntity.storePath = tUrlEntity.storePath;
urlEntity.storePass = tUrlEntity.storePass;
urlEntity.keyAlias = tUrlEntity.keyAlias;
}
}
}
}
if (getTaskWrapper().asFtp().getUrlEntity().isFtps) {
if (TextUtils.isEmpty(getTaskWrapper().asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(getTaskWrapper().asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return b;
}
/**
* 检查普通任务的下载地址
*
* @return {@code true}地址合法
*/
private boolean checkUrl() {
final String url = getGroupHash();
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "下载失败,url为null");
return false;
} else if (!url.startsWith("ftp")) {
ALog.e(TAG, "下载失败,url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "下载失败,url【" + url + "】不合法");
return false;
}
return true;
FtpDirConfigHandler(TARGET target, long taskId) {
super(target, taskId);
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP_DIR);
}
}

@ -1,110 +0,0 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.ftp.FTPSDelegate;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import java.net.Proxy;
/**
* Created by Aria.Lao on 2017/7/26.
* ftp文件夹下载
*/
public class FtpDirDownloadTarget extends AbsDGTarget<FtpDirDownloadTarget>
implements IFtpTarget<FtpDirDownloadTarget> {
private FtpDelegate<FtpDirDownloadTarget> mFtpDelegate;
private FtpDirConfigHandler mConfigHandler;
FtpDirDownloadTarget(String url, String targetName) {
setTargetName(targetName);
init(url);
}
private void init(String key) {
mConfigHandler = new FtpDirConfigHandler(this,
TaskWrapperManager.getInstance().getFtpTaskWrapper(DGTaskWrapper.class, key));
mFtpDelegate = new FtpDelegate<>(this);
}
@Override public int getTargetType() {
return GROUP_FTP_DIR;
}
@Override protected boolean checkEntity() {
return mConfigHandler.checkEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
/**
* 设置任务组的文件夹路径在Aria中任务组的所有子任务都会下载到以任务组组名的文件夹中
* groupDirPath = "/mnt/sdcard/download/group_test"
* <pre>
* {@code
* + mnt
* + sdcard
* + download
* + group_test
* - task1.apk
* - task2.apk
* - task3.apk
* ....
*
* }
* </pre>
*
* @param dirPath 任务组保存文件夹路径
*/
@CheckResult
public FtpDirDownloadTarget setDirPath(String dirPath) {
return mConfigHandler.setDirPath(dirPath);
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSDelegate<FtpDirDownloadTarget> asFtps() {
getTaskWrapper().asFtp().getUrlEntity().isFtps = true;
return new FTPSDelegate<>(this);
}
@CheckResult
@Override public FtpDirDownloadTarget charSet(String charSet) {
return mFtpDelegate.charSet(charSet);
}
@CheckResult
@Override public FtpDirDownloadTarget login(String userName, String password) {
return mFtpDelegate.login(userName, password);
}
@CheckResult
@Override public FtpDirDownloadTarget login(String userName, String password, String account) {
return mFtpDelegate.login(userName, password, account);
}
}

@ -0,0 +1,80 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.util.CommonUtil;
/**
* Created by Aria.Lao on 2017/7/26.
* ftp文件夹下载
*/
public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
private FtpDirConfigHandler<FtpDirNormalTarget> mConfigHandler;
FtpDirNormalTarget(long taskId, String targetName) {
setTargetName(targetName);
mConfigHandler = new FtpDirConfigHandler<>(this, taskId);
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(getEntity().getKey()));
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
/**
* 设置任务组的文件夹路径在Aria中任务组的所有子任务都会下载到以任务组组名的文件夹中
* groupDirPath = "/mnt/sdcard/download/group_test"
* <pre>
* {@code
* + mnt
* + sdcard
* + download
* + group_test
* - task1.apk
* - task2.apk
* - task3.apk
* ....
*
* }
* </pre>
*
* @param dirPath 任务组保存文件夹路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDirNormalTarget modifyDirPath(String dirPath) {
return mConfigHandler.setDirPath(dirPath);
}
/**
* 设置登陆字符串编码ftps等参数
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDelegate<FtpDirNormalTarget> option() {
return new FtpDelegate<>(this, getTaskWrapper());
}
@Override public DownloadGroupEntity getEntity() {
return (DownloadGroupEntity) super.getEntity();
}
}

@ -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.aria.core.download;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.util.CommonUtil;
/**
* Created by Aria.Lao on 2017/7/26.
* ftp文件夹下载
*/
public class FtpDirStartTarget extends AbsStartTarget<FtpDirStartTarget> {
private FtpDirConfigHandler<FtpDirStartTarget> mConfigHandler;
FtpDirStartTarget(String url, String targetName) {
setTargetName(targetName);
mConfigHandler = new FtpDirConfigHandler<>(this, -1);
getEntity().setGroupHash(url);
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(url));
}
/**
* 设置任务组的文件夹路径在Aria中任务组的所有子任务都会下载到以任务组组名的文件夹中
* groupDirPath = "/mnt/sdcard/download/group_test"
* <pre>
* {@code
* + mnt
* + sdcard
* + download
* + group_test
* - task1.apk
* - task2.apk
* - task3.apk
* ....
*
* }
* </pre>
*
* @param dirPath 任务组保存文件夹路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDirStartTarget setDirPath(String dirPath) {
return mConfigHandler.setDirPath(dirPath);
}
/**
* 设置任务组别名
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDirStartTarget setGroupAlias(String alias) {
mConfigHandler.setGroupAlias(alias);
return this;
}
/**
* 设置登陆字符串编码ftps等参数
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDelegate<FtpDirStartTarget> option() {
return new FtpDelegate<>(this, getTaskWrapper());
}
@Override public DownloadGroupEntity getEntity() {
return (DownloadGroupEntity) super.getEntity();
}
}

@ -1,150 +0,0 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.arialyy.aria.core.common.ftp.FTPSDelegate;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.net.Proxy;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
public class FtpDownloadTarget extends AbsDTarget<FtpDownloadTarget>
implements IFtpTarget<FtpDownloadTarget> {
private FtpDelegate<FtpDownloadTarget> mFtpDelegate;
private DNormalConfigHandler<FtpDownloadTarget> mConfigHandler;
FtpDownloadTarget(DownloadEntity entity, String targetName) {
this(entity.getUrl(), targetName);
}
FtpDownloadTarget(String url, String targetName) {
mConfigHandler = new DNormalConfigHandler<>(this, url, targetName);
init();
}
private void init() {
int lastIndex = mConfigHandler.getUrl().lastIndexOf("/");
getEntity().setFileName(mConfigHandler.getUrl().substring(lastIndex + 1));
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(mConfigHandler.getUrl()));
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP);
mFtpDelegate = new FtpDelegate<>(this);
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSDelegate<FtpDownloadTarget> asFtps() {
getTaskWrapper().asFtp().getUrlEntity().isFtps = true;
return new FTPSDelegate<>(this);
}
@Override protected boolean checkEntity() {
if (getTaskWrapper().asFtp().getUrlEntity().isFtps) {
if (TextUtils.isEmpty(getTaskWrapper().asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(getTaskWrapper().asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return mConfigHandler.checkEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
/**
* 设置文件保存文件夹路径
*
* @param filePath 文件保存路径
* @deprecated {@link #setFilePath(String)} 请使用这个api
*/
@Deprecated
@CheckResult
public FtpDownloadTarget setDownloadPath(@NonNull String filePath) {
return setFilePath(filePath);
}
/**
* 设置文件保存文件夹路径
* 关于文件名
* 1如果保存路径是该文件的保存路径/mnt/sdcard/file.zip则使用路径中的文件名file.zip
* 2如果保存路径是文件夹路径/mnt/sdcard/则使用FTP服务器该文件的文件名
*/
@CheckResult
public FtpDownloadTarget setFilePath(@NonNull String filePath) {
mConfigHandler.setTempFilePath(filePath);
return this;
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*
* @param filePath 路径必须为文件路径不能为文件夹路径
* @param forceDownload {@code true}强制下载不考虑文件路径是否被占用
*/
@CheckResult
public FtpDownloadTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
mConfigHandler.setTempFilePath(filePath);
mConfigHandler.setForceDownload(forceDownload);
return this;
}
@Override public int getTargetType() {
return D_FTP;
}
@CheckResult
@Override public FtpDownloadTarget charSet(String charSet) {
return mFtpDelegate.charSet(charSet);
}
@CheckResult
@Override public FtpDownloadTarget login(String userName, String password) {
return mFtpDelegate.login(userName, password);
}
@CheckResult
@Override public FtpDownloadTarget login(String userName, String password, String account) {
return mFtpDelegate.login(userName, password, account);
}
@Override public FtpDownloadTarget updateUrl(String newUrl) {
return mConfigHandler.updateUrl(newUrl);
}
}

@ -0,0 +1,80 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.CommonUtil;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
private DNormalConfigHandler<FtpNormalTarget> mConfigHandler;
FtpNormalTarget(long taskId, String targetName) {
mConfigHandler = new DNormalConfigHandler<>(this, taskId, targetName);
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(mConfigHandler.getUrl()));
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP);
}
/**
* 设置登陆字符串编码ftps等参数
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDelegate<FtpNormalTarget> option() {
return new FtpDelegate<>(this, getTaskWrapper());
}
/**
* 设置文件保存文件夹路径
* 关于文件名
* 1如果保存路径是该文件的保存路径/mnt/sdcard/file.zip则使用路径中的文件名file.zip
* 2如果保存路径是文件夹路径/mnt/sdcard/则使用FTP服务器该文件的文件名
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpNormalTarget modifyFilePath(@NonNull String filePath) {
int lastIndex = mConfigHandler.getUrl().lastIndexOf("/");
getEntity().setFileName(mConfigHandler.getUrl().substring(lastIndex + 1));
mConfigHandler.setTempFilePath(filePath);
return this;
}
/**
* 更新下载地址
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpNormalTarget updateUrl(String newUrl) {
return mConfigHandler.updateUrl(newUrl);
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
@Override public DownloadEntity getEntity() {
return (DownloadEntity) super.getEntity();
}
}

@ -0,0 +1,79 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.CommonUtil;
/**
* 处理ftp第一次下载等逻辑
*/
public class FtpStartTarget extends AbsStartTarget<FtpStartTarget> {
private DNormalConfigHandler<FtpStartTarget> mConfigHandler;
FtpStartTarget(String url, String targetName) {
mConfigHandler = new DNormalConfigHandler<>(this, -1, targetName);
mConfigHandler.setUrl(url);
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(url));
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP);
}
/**
* 设置登陆字符串编码ftps等参数
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDelegate<FtpStartTarget> option() {
return new FtpDelegate<>(this, getTaskWrapper());
}
/**
* 设置文件保存文件夹路径
* 关于文件名
* 1如果保存路径是该文件的保存路径/mnt/sdcard/file.zip则使用路径中的文件名file.zip
* 2如果保存路径是文件夹路径/mnt/sdcard/则使用FTP服务器该文件的文件名
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpStartTarget setFilePath(@NonNull String filePath) {
int lastIndex = mConfigHandler.getUrl().lastIndexOf("/");
getEntity().setFileName(mConfigHandler.getUrl().substring(lastIndex + 1));
mConfigHandler.setTempFilePath(filePath);
return this;
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*
* @param filePath 路径必须为文件路径不能为文件夹路径
* @param forceDownload {@code true}强制下载不考虑文件路径是否被占用
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpStartTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
mConfigHandler.setTempFilePath(filePath);
mConfigHandler.setForceDownload(forceDownload);
return this;
}
@Override public DownloadEntity getEntity() {
return (DownloadEntity) super.getEntity();
}
}

@ -0,0 +1,113 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.manager.SubTaskManager;
import java.util.List;
/**
* Created by AriaL on 2017/6/29.
* 下载任务组
*/
public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
private HttpGroupConfigHandler<GroupNormalTarget> mConfigHandler;
GroupNormalTarget(long taskId, String targetName) {
setTargetName(targetName);
mConfigHandler = new HttpGroupConfigHandler<>(this, taskId);
}
/**
* 设置http请求参数header等信息
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpDelegate<GroupNormalTarget> option() {
return new HttpDelegate<>(this, getTaskWrapper());
}
/**
* 获取子任务管理器
*
* @return 子任务管理器
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public SubTaskManager getSubTaskManager() {
return mConfigHandler.getSubTaskManager();
}
/**
* 设置任务组别名
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupNormalTarget setGroupAlias(String alias) {
mConfigHandler.setGroupAlias(alias);
return this;
}
/**
* 更新组合任务下载地址
*
* @param urls 新的组合任务下载地址列表
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupNormalTarget updateUrls(List<String> urls) {
return mConfigHandler.updateUrls(urls);
}
/**
* 更新任务组的文件夹路径在Aria中任务组的所有子任务都会下载到以任务组组名的文件夹中
* groupDirPath = "/mnt/sdcard/download/group_test"
* <pre>
* {@code
* + mnt
* + sdcard
* + download
* + group_test
* - task1.apk
* - task2.apk
* - task3.apk
* ....
*
* }
* </pre>
*
* @param dirPath 任务组保存文件夹路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupNormalTarget modifyDirPath(String dirPath) {
return mConfigHandler.setDirPath(dirPath);
}
/**
* 更新子任务文件名该方法必须在{@link #modifyDirPath(String)}之后调用否则不生效
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupNormalTarget modifySubFileName(List<String> subTaskFileName) {
return mConfigHandler.setSubFileName(subTaskFileName);
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
}

@ -16,72 +16,33 @@
package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.http.GetDelegate;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.common.http.PostDelegate;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.exception.ParamException;
import com.arialyy.aria.core.manager.SubTaskManager;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
import java.util.List;
import java.util.Map;
/**
* Created by AriaL on 2017/6/29.
* 下载任务组
*/
public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> {
private HttpDelegate<DownloadGroupTarget> mHttpDelegate;
private HttpGroupConfigHandler mConfigHandler;
public class GroupStartTarget extends AbsStartTarget<GroupStartTarget> {
private HttpGroupConfigHandler<GroupStartTarget> mConfigHandler;
DownloadGroupTarget(DownloadGroupEntity groupEntity, String targetName) {
GroupStartTarget(List<String> urls, String targetName) {
setTargetName(targetName);
if (groupEntity.getUrls() != null && !groupEntity.getUrls().isEmpty()) {
init(groupEntity.getUrls());
} else {
throw new ParamException("组合任务只任务下载地址为空");
}
}
DownloadGroupTarget(List<String> urls, String targetName) {
setTargetName(targetName);
init(urls);
}
private void init(List<String> urls) {
mConfigHandler = new HttpGroupConfigHandler(this,
TaskWrapperManager.getInstance().getDGTaskWrapper(DGTaskWrapper.class, urls));
mHttpDelegate = new HttpDelegate<>(this);
mConfigHandler = new HttpGroupConfigHandler<>(this, -1);
mConfigHandler.setGroupUrl(urls);
}
/**
* Post处理
* 设置http请求参数header等信息
*/
@CheckResult
public PostDelegate asPost() {
mHttpDelegate = new PostDelegate<>(this);
return (PostDelegate) mHttpDelegate;
}
/**
* get处理
*/
@CheckResult
public GetDelegate asGet() {
mHttpDelegate = new GetDelegate<>(this);
return (GetDelegate) mHttpDelegate;
}
/**
* 更新组合任务下载地址
*
* @param urls 新的组合任务下载地址列表
*/
@CheckResult
public DownloadGroupTarget updateUrls(List<String> urls) {
return mConfigHandler.updateUrls(urls);
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpDelegate<GroupStartTarget> option() {
return new HttpDelegate<>(this, getTaskWrapper());
}
/**
@ -92,8 +53,8 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> {
*
* @param fileSize 任务组总大小
*/
@CheckResult
public DownloadGroupTarget setFileSize(long fileSize) {
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupStartTarget setFileSize(long fileSize) {
if (fileSize <= 0) {
ALog.e(TAG, "文件大小不能小于 0");
return this;
@ -111,18 +72,20 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> {
* 2如果你的知道组合任务的总长度请使用{@link #setFileSize(long)}设置组合任务的长度
* 3由于网络或其它原因的存在这种方式获取的组合任务大小有可能是不准确的
*/
@CheckResult
public DownloadGroupTarget unknownSize() {
getTaskWrapper().setUnknownSize(true);
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupStartTarget unknownSize() {
((DGTaskWrapper) getTaskWrapper()).setUnknownSize(true);
return this;
}
/**
* 如果你是使用{@link DownloadReceiver#load(DownloadGroupEntity)}进行下载操作那么你需要设置任务组的下载地址
* 获取子任务管理器
*
* @return 子任务管理器
*/
@CheckResult
public DownloadGroupTarget setGroupUrl(List<String> urls) {
return mConfigHandler.setGroupUrl(urls);
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public SubTaskManager getSubTaskManager() {
return mConfigHandler.getSubTaskManager();
}
/**
@ -130,11 +93,20 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> {
*
* @deprecated {@link #setSubFileName(List)} 请使用该api
*/
@CheckResult
@Deprecated public DownloadGroupTarget setSubTaskFileName(List<String> subTaskFileName) {
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
@Deprecated public GroupStartTarget setSubTaskFileName(List<String> subTaskFileName) {
return setSubFileName(subTaskFileName);
}
/**
* 设置任务组别名
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupStartTarget setGroupAlias(String alias) {
mConfigHandler.setGroupAlias(alias);
return this;
}
/**
* 设置任务组的文件夹路径在Aria中任务组的所有子任务都会下载到以任务组组名的文件夹中
* groupDirPath = "/mnt/sdcard/download/group_test"
@ -154,54 +126,29 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> {
*
* @param dirPath 任务组保存文件夹路径
*/
@CheckResult
public DownloadGroupTarget setDirPath(String dirPath) {
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupStartTarget setDirPath(String dirPath) {
return mConfigHandler.setDirPath(dirPath);
}
/**
* 设置子任务文件名该方法必须在{@link #setDirPath(String)}之后调用否则不生效
*/
@CheckResult
public DownloadGroupTarget setSubFileName(List<String> subTaskFileName) {
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupStartTarget setSubFileName(List<String> subTaskFileName) {
return mConfigHandler.setSubFileName(subTaskFileName);
}
/**
* 如果你需要使用header中特定的key来设置文件长度或有定制文件长度的需要那么你可以通过该方法自行处理文件长度
*/
public DownloadGroupTarget setFileLenAdapter(IHttpFileLenAdapter adapter) {
return mHttpDelegate.setFileLenAdapter(adapter);
}
@Override public int getTargetType() {
return GROUP_HTTP;
}
@Override protected boolean checkEntity() {
return mConfigHandler.checkEntity();
}
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public GroupStartTarget setFileLenAdapter(IHttpFileLenAdapter adapter) {
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
if (adapter == null) {
throw new IllegalArgumentException("adapter为空");
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
@CheckResult
public DownloadGroupTarget addHeader(@NonNull String key, @NonNull String value) {
return mHttpDelegate.addHeader(key, value);
}
@CheckResult
public DownloadGroupTarget addHeaders(Map<String, String> headers) {
return mHttpDelegate.addHeaders(headers);
}
@CheckResult
public DownloadGroupTarget setUrlProxy(Proxy proxy) {
return mHttpDelegate.setUrlProxy(proxy);
getTaskWrapper().asHttp().setFileLenAdapter(adapter);
return this;
}
}

@ -16,24 +16,19 @@
package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.RecordUtil;
import com.arialyy.aria.util.DbDataHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Created by lyy on 2019/4/9.
*
* http组合任务功能代理
*/
class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget> {
class HttpGroupConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHandler<TARGET> {
/**
* 子任务下载地址
@ -45,23 +40,27 @@ class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget>
*/
private List<String> mSubNameTemp = new ArrayList<>();
HttpGroupConfigHandler(DownloadGroupTarget target, DGTaskWrapper wrapper) {
super(target, wrapper);
mUrls.addAll(wrapper.getEntity().getUrls());
HttpGroupConfigHandler(TARGET target, long taskId) {
super(target, taskId);
mUrls.addAll(getEntity().getUrls());
}
@CheckResult
DownloadGroupTarget setGroupUrl(List<String> urls) {
void setGroupUrl(List<String> urls) {
if (urls == null || urls.isEmpty()) {
throw new NullPointerException("组合任务子任务下载地址列表为空");
}
mUrls.clear();
mUrls.addAll(urls);
return getTarget();
String groupHash = CommonUtil.getMd5Code(urls);
getEntity().setGroupHash(groupHash);
getEntity().setSubEntities(DbDataHelper.createHttpSubTask(groupHash, mUrls));
}
/**
* 设置子任务文件名该方法必须在{@link #setDirPath(String)}之后调用否则不生效
*/
@CheckResult
DownloadGroupTarget setSubFileName(List<String> subTaskFileName) {
TARGET setSubFileName(List<String> subTaskFileName) {
if (subTaskFileName == null || subTaskFileName.isEmpty()) {
ALog.w(TAG, "修改子任务的文件名失败:列表为null");
return getTarget();
@ -72,6 +71,7 @@ class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget>
}
mSubNameTemp.clear();
mSubNameTemp.addAll(subTaskFileName);
getTaskWrapper().setSubNameTemp(mSubNameTemp);
return getTarget();
}
@ -81,7 +81,7 @@ class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget>
* @param urls 新的组合任务下载地址列表
*/
@CheckResult
DownloadGroupTarget updateUrls(List<String> urls) {
TARGET updateUrls(List<String> urls) {
if (urls == null || urls.isEmpty()) {
throw new NullPointerException("下载地址列表为空");
}
@ -91,7 +91,6 @@ class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget>
mUrls.clear();
mUrls.addAll(urls);
String newHash = CommonUtil.getMd5Code(urls);
setGroupHash(newHash);
getEntity().setGroupHash(newHash);
getEntity().update();
if (getEntity().getSubEntities() != null && !getEntity().getSubEntities().isEmpty()) {
@ -102,147 +101,4 @@ class HttpGroupConfigHandler extends AbsGroupConfigHandler<DownloadGroupTarget>
}
return getTarget();
}
@Override public boolean checkEntity() {
if (!checkDirPath()) {
return false;
}
if (!checkSubName()) {
return false;
}
if (!checkUrls()) {
return false;
}
if (!getTaskWrapper().isUnknownSize() && getTaskWrapper().getEntity().getFileSize() == 0) {
ALog.e(TAG, "组合任务必须设置文件文件大小,默认需要强制设置文件大小。如果无法获取到总长度,请调用#unknownSize()来标志该组合任务");
return false;
}
if (getTaskWrapper().asHttp().getRequestEnum() == RequestEnum.POST) {
for (DTaskWrapper subTask : getTaskWrapper().getSubTaskWrapper()) {
subTask.asHttp().setRequestEnum(RequestEnum.POST);
}
}
if (isNeedModifyPath()) {
reChangeDirPath(getDirPathTemp());
}
if (!mSubNameTemp.isEmpty()) {
updateSingleSubFileName();
}
saveEntity();
return true;
}
private void saveEntity() {
getEntity().save();
DbEntity.saveAll(getEntity().getSubEntities());
}
/**
* 更新所有改动的子任务文件名
*/
private void updateSingleSubFileName() {
List<DTaskWrapper> entities = getTaskWrapper().getSubTaskWrapper();
int i = 0;
for (DTaskWrapper taskWrapper : entities) {
if (i < mSubNameTemp.size()) {
String newName = mSubNameTemp.get(i);
DownloadEntity entity = taskWrapper.getEntity();
if (!newName.equals(entity.getFileName())) {
String oldPath = getEntity().getDirPath() + "/" + entity.getFileName();
String newPath = getEntity().getDirPath() + "/" + newName;
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=? or isComplete='true'",
newPath)) {
ALog.w(TAG, String.format("更新文件名失败,路径【%s】已存在或文件已下载", newPath));
return;
}
RecordUtil.modifyTaskRecord(oldPath, newPath);
entity.setFilePath(newPath);
entity.setFileName(newName);
}
}
i++;
}
}
/**
* 检查urls是否合法并删除不合法的子任务
*
* @return {@code true} 合法
*/
private boolean checkUrls() {
if (mUrls.isEmpty()) {
ALog.e(TAG, "下载失败,子任务下载列表为null");
return false;
}
Set<String> repeated = new HashSet<>();
List<String> results = new ArrayList<>();
for (String url : mUrls) {
if (!repeated.add(url)) {
results.add(url);
}
}
if (!results.isEmpty()) {
ALog.e(TAG, String.format("组合任务中有url重复,重复的url:%s", Arrays.toString(results.toArray())));
return false;
}
Set<Integer> delItem = new HashSet<>();
int i = 0;
for (String url : mUrls) {
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "子任务url为null,即将删除该子任务。");
delItem.add(i);
continue;
} else if (!url.startsWith("http")) {
ALog.e(TAG, "子任务url【" + url + "】错误,即将删除该子任务。");
delItem.add(i);
continue;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "子任务url【" + url + "】不合法,即将删除该子任务。");
delItem.add(i);
continue;
}
i++;
}
for (int index : delItem) {
mUrls.remove(index);
if (mSubNameTemp != null && !mSubNameTemp.isEmpty()) {
mSubNameTemp.remove(index);
}
}
getEntity().setGroupHash(CommonUtil.getMd5Code(mUrls));
return true;
}
/**
* 如果用户设置了子任务文件名检查子任务文件名
*
* @return {@code true} 合法
*/
private boolean checkSubName() {
if (mSubNameTemp == null || mSubNameTemp.isEmpty()) {
return true;
}
if (mUrls.size() != mSubNameTemp.size()) {
ALog.e(TAG, "子任务文件名必须和子任务数量一致");
return false;
}
return true;
}
}

@ -0,0 +1,85 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.download.m3u8.M3U8Delegate;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
private DNormalConfigHandler<HttpNormalTarget> mConfigHandler;
HttpNormalTarget(long taskId, String targetName) {
mConfigHandler = new DNormalConfigHandler<>(this, taskId, targetName);
}
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public M3U8Delegate<HttpNormalTarget> asM3U8() {
return new M3U8Delegate<>(this, getTaskWrapper());
}
/**
* 设置http请求参数header等信息
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpDelegate<HttpNormalTarget> option() {
return new HttpDelegate<>(this, getTaskWrapper());
}
/**
* 更新文件保存路径
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpNormalTarget modifyFilePath(String filePath) {
mConfigHandler.setTempFilePath(filePath);
return this;
}
/**
* 从header中获取文件描述信息
*/
public String getContentDisposition() {
return getEntity().getDisposition();
}
/**
* 更新下载地址
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpNormalTarget updateUrl(String newUrl) {
return mConfigHandler.updateUrl(newUrl);
}
@Override public DownloadEntity getEntity() {
return (DownloadEntity) super.getEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
}

@ -0,0 +1,98 @@
/*
* 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.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.download.m3u8.M3U8Delegate;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
public class HttpStartTarget extends AbsStartTarget<HttpStartTarget> {
private DNormalConfigHandler<HttpStartTarget> mConfigHandler;
HttpStartTarget(String url, String targetName) {
mConfigHandler = new DNormalConfigHandler<>(this, -1, targetName);
mConfigHandler.setUrl(url);
}
@CheckResult(suggest = Suggest.TASK_CONTROLLER) public M3U8Delegate<HttpStartTarget> asM3U8() {
return new M3U8Delegate<>(this, getTaskWrapper());
}
/**
* 设置http请求参数header等信息
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpDelegate<HttpStartTarget> option() {
return new HttpDelegate<>(this, getTaskWrapper());
}
/**
* 是否使用服务器通过content-disposition传递的文件名内容格式{@code attachment;filename=***}
* 如果获取不到服务器文件名则使用用户设置的文件名
*
* @param use {@code true} 使用
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpStartTarget useServerFileName(boolean use) {
getTaskWrapper().asHttp().setUseServerFileName(use);
return this;
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*
* @param filePath 路径必须为文件路径不能为文件夹路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpStartTarget setFilePath(@NonNull String filePath) {
mConfigHandler.setTempFilePath(filePath);
return this;
}
/**
* 设置文件存储路径如果需要修改新的文件名修改路径便可
* 原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip只需要重新设置文件路径为/mnt/sdcard/game.zip
*
* @param filePath 路径必须为文件路径不能为文件夹路径
* @param forceDownload {@code true}强制下载不考虑文件路径是否被占用
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpStartTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
mConfigHandler.setTempFilePath(filePath);
mConfigHandler.setForceDownload(forceDownload);
return this;
}
/**
* 如果你需要使用header中特定的key来设置文件长度或有定制文件长度的需要那么你可以通过该方法自行处理文件长度
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpStartTarget setFileLenAdapter(IHttpFileLenAdapter adapter) {
if (adapter == null) {
throw new IllegalArgumentException("adapter为空");
}
getTaskWrapper().asHttp().setFileLenAdapter(adapter);
return this;
}
}

@ -21,9 +21,9 @@ import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.common.ftp.AbsFtpInfoThread;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.CommonUtil;
import java.nio.charset.Charset;
@ -61,7 +61,7 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DGTaskWrapp
DownloadEntity entity = new DownloadEntity();
entity.setUrl(
urlEntity.scheme + "://" + urlEntity.hostName + ":" + urlEntity.port + "/" + remotePath);
entity.setDownloadPath(mEntity.getDirPath() + "/" + remotePath);
entity.setFilePath(mEntity.getDirPath() + "/" + remotePath);
int lastIndex = remotePath.lastIndexOf("/");
String fileName = lastIndex < 0 ? CommonUtil.keyToHashKey(remotePath)
: remotePath.substring(lastIndex + 1);
@ -73,18 +73,25 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DGTaskWrapp
entity.setFileSize(ftpFile.getSize());
entity.insert();
DTaskWrapper taskWrapper = new DTaskWrapper(entity);
taskWrapper.setGroupTask(true);
taskWrapper.setGroupHash(mEntity.getGroupHash());
taskWrapper.setRequestType(AbsTaskWrapper.D_FTP);
DTaskWrapper subWrapper = new DTaskWrapper(entity);
subWrapper.setGroupTask(true);
subWrapper.setGroupHash(mEntity.getGroupHash());
subWrapper.setRequestType(AbsTaskWrapper.D_FTP);
urlEntity.url = entity.getUrl();
urlEntity.remotePath = remotePath;
taskWrapper.asFtp().setUrlEntity(urlEntity);
cloneInfo(subWrapper, urlEntity);
if (mEntity.getUrls() == null) {
mEntity.setUrls(new ArrayList<String>());
}
mEntity.getSubEntities().add(entity);
mTaskWrapper.getSubTaskWrapper().add(taskWrapper);
mTaskWrapper.getSubTaskWrapper().add(subWrapper);
}
private void cloneInfo(DTaskWrapper subWrapper, FtpUrlEntity urlEntity) {
subWrapper.asFtp().setUrlEntity(urlEntity);
subWrapper.asFtp().setCharSet(mTaskWrapper.asFtp().getCharSet());
subWrapper.asFtp().setProxy(mTaskWrapper.asFtp().getProxy());
}
}

@ -15,11 +15,12 @@
*/
package com.arialyy.aria.core.download.m3u8;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
/**
* m3u8 委托
@ -27,9 +28,9 @@ import com.arialyy.aria.util.ALog;
public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET> {
private DTaskWrapper mTaskWrapper;
public M3U8Delegate(TARGET target) {
super(target);
mTaskWrapper = (DTaskWrapper) mTarget.getTaskWrapper();
public M3U8Delegate(TARGET target, AbsTaskWrapper wrapper) {
super(target, wrapper);
mTaskWrapper = (DTaskWrapper) getTaskWrapper();
mTaskWrapper.setRequestType(AbsTaskWrapper.M3U8_VOD);
}
@ -38,7 +39,8 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param merge {@code true}合并所有ts文件为一个
*/
public M3U8Delegate merge(boolean merge) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8Delegate<TARGET> merge(boolean merge) {
mTaskWrapper.asM3U8().setMergeFile(merge);
return this;
}
@ -47,7 +49,8 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
* 如果你希望使用自行处理ts文件的合并可以使用{@link ITsMergeHandler}处理ts文件的合并
* 需要注意的是只有{@link #merge(boolean)}设置合并ts文件该方法才会生效
*/
public M3U8Delegate setMergeHandler(ITsMergeHandler handler) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8Delegate<TARGET> setMergeHandler(ITsMergeHandler handler) {
mTaskWrapper.asM3U8().setMergeHandler(handler);
return this;
}
@ -58,7 +61,8 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param converter {@link IVodTsUrlConverter}
*/
public M3U8Delegate setTsUrlConvert(IVodTsUrlConverter converter) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8Delegate<TARGET> setTsUrlConvert(IVodTsUrlConverter converter) {
mTaskWrapper.asM3U8().setVodUrlConverter(converter);
return this;
}
@ -68,7 +72,8 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param bandWidth 指定的码率
*/
public M3U8Delegate setBandWidth(int bandWidth) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8Delegate<TARGET> setBandWidth(int bandWidth) {
mTaskWrapper.asM3U8().setBandWidth(bandWidth);
return this;
}
@ -79,7 +84,8 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
*
* @param converter {@link IBandWidthUrlConverter}
*/
public M3U8Delegate setBandWidthUrlConverter(IBandWidthUrlConverter converter) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8Delegate<TARGET> setBandWidthUrlConverter(IBandWidthUrlConverter converter) {
mTaskWrapper.asM3U8().setBandWidthUrlConverter(converter);
return this;
}
@ -87,14 +93,16 @@ public class M3U8Delegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET>
/**
* 处理点播文件的下载参数
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8VodDelegate<TARGET> asVod() {
return new M3U8VodDelegate<>(mTarget);
return new M3U8VodDelegate<>(mTarget, mTaskWrapper);
}
/**
* 处理直播类的下载
*/
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8LiveDelegate<TARGET> asLive() {
return new M3U8LiveDelegate<>(mTarget);
return new M3U8LiveDelegate<>(mTarget, mTaskWrapper);
}
}

@ -15,7 +15,9 @@
*/
package com.arialyy.aria.core.download.m3u8;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
@ -26,9 +28,9 @@ import com.arialyy.aria.util.ALog;
*/
public class M3U8LiveDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET> {
M3U8LiveDelegate(TARGET target) {
super(target);
mTarget.getTaskWrapper().setRequestType(AbsTaskWrapper.M3U8_LIVE);
M3U8LiveDelegate(TARGET target, AbsTaskWrapper wrapper) {
super(target, wrapper);
getTaskWrapper().setRequestType(AbsTaskWrapper.M3U8_LIVE);
}
/**
@ -37,8 +39,9 @@ public class M3U8LiveDelegate<TARGET extends AbsTarget> extends BaseDelegate<TAR
*
* @param converter {@link ILiveTsUrlConverter}
*/
public M3U8LiveDelegate setLiveTsUrlConvert(ILiveTsUrlConverter converter) {
((DTaskWrapper) mTarget.getTaskWrapper()).asM3U8().setLiveTsUrlConverter(converter);
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8LiveDelegate<TARGET> setLiveTsUrlConvert(ILiveTsUrlConverter converter) {
((DTaskWrapper) getTaskWrapper()).asM3U8().setLiveTsUrlConverter(converter);
return this;
}
@ -47,12 +50,13 @@ public class M3U8LiveDelegate<TARGET extends AbsTarget> extends BaseDelegate<TAR
*
* @param interval 更新间隔单位微秒
*/
public M3U8LiveDelegate setM3U8FileUpdateInterval(long interval) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8LiveDelegate<TARGET> setM3U8FileUpdateInterval(long interval) {
if (interval <= 1) {
ALog.e(TAG, "间隔时间错误");
return this;
}
((DTaskWrapper) mTarget.getTaskWrapper()).asM3U8().setLiveUpdateInterval(interval);
((DTaskWrapper) getTaskWrapper()).asM3U8().setLiveUpdateInterval(interval);
return this;
}
}

@ -15,7 +15,9 @@
*/
package com.arialyy.aria.core.download.m3u8;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.BaseDelegate;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.event.PeerIndexEvent;
@ -30,9 +32,9 @@ import com.arialyy.aria.util.ALog;
public class M3U8VodDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARGET> {
private DTaskWrapper mTaskWrapper;
M3U8VodDelegate(TARGET target) {
super(target);
mTaskWrapper = (DTaskWrapper) mTarget.getTaskWrapper();
M3U8VodDelegate(TARGET target, AbsTaskWrapper wrapper) {
super(target, wrapper);
mTaskWrapper = (DTaskWrapper) getTaskWrapper();
mTaskWrapper.setRequestType(AbsTaskWrapper.M3U8_VOD);
}
@ -41,7 +43,8 @@ public class M3U8VodDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARG
*
* @param fileSize 文件长度
*/
public M3U8VodDelegate setFileSize(long fileSize) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8VodDelegate<TARGET> setFileSize(long fileSize) {
if (fileSize <= 0) {
ALog.e(TAG, "文件长度错误");
return this;
@ -55,7 +58,8 @@ public class M3U8VodDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARG
*
* @param num 同时下载的ts分片数量
*/
public M3U8VodDelegate setMaxTsQueueNum(int num) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8VodDelegate<TARGET> setMaxTsQueueNum(int num) {
if (num < 1) {
ALog.e(TAG, "同时下载的分片数量不能小于1");
return this;
@ -74,7 +78,8 @@ public class M3U8VodDelegate<TARGET extends AbsTarget> extends BaseDelegate<TARG
*
* @param index 指定的切片位置
*/
public M3U8VodDelegate setPeerIndex(int index) {
@CheckResult(suggest = Suggest.TO_CONTROLLER)
public M3U8VodDelegate<TARGET> setPeerIndex(int index) {
if (index < 1) {
ALog.e(TAG, "切片索引不能小于1");
return this;

@ -175,6 +175,10 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
this.stopTime = stopTime;
}
public long getId() {
return getRowID();
}
/**
* 实体唯一标识符
* 下载实体下载url

@ -26,7 +26,7 @@ import java.util.List;
*/
public abstract class AbsGroupEntity extends AbsEntity implements Parcelable {
/**
* 组名组名为任务地址相加的url的Md5
* 任务地址相加的url的Md5
*/
@Unique protected String groupHash;
@ -61,6 +61,10 @@ public abstract class AbsGroupEntity extends AbsEntity implements Parcelable {
this.urls = urls;
}
/**
* 组合任务等hash为 为子任务地址相加的url的Md5
* ftpdir为ftpdir下载地址
*/
public String getGroupHash() {
return groupHash;
}

@ -15,30 +15,18 @@
*/
package com.arialyy.aria.core.inf;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.command.CancelCmd;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.controller.NormalController;
import com.arialyy.aria.core.common.controller.StartController;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.RecordUtil;
/**
* Created by AriaL on 2017/7/3.
*/
public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHandler {
public abstract class AbsTarget<TARGET extends AbsTarget> {
protected String TAG;
private AbsEntity mEntity;
@ -54,36 +42,6 @@ public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHand
mEntity = wrapper.getEntity();
}
/**
* 重置状态将任务状态设置为未开始状态
* 注意如果在后续方法调用链中没有调用 {@link #start()}{@link #stop()}{@link #cancel()}{@link #resume()}
* 等操作任务的方法那么你需要调用{@link #save()}才能将修改保存到数据库
*/
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?")
public TARGET resetState() {
mTaskWrapper.getEntity().setState(IEntity.STATE_WAIT);
mTaskWrapper.setRefreshInfo(true);
return (TARGET) this;
}
/**
* 删除记录如果任务正在执行则会删除正在下载的任务
*/
public void removeRecord() {
if (isRunning()) {
ALog.d("AbsTarget", "任务正在下载,即将删除任务");
cancel();
} else {
if (mEntity instanceof AbsNormalEntity) {
RecordUtil.delTaskRecord((AbsNormalEntity) mEntity, mTaskWrapper.isRemoveFile());
} else if (mEntity instanceof DownloadGroupEntity) {
RecordUtil.delGroupTaskRecord(((DownloadGroupEntity) mEntity), mTaskWrapper.isRemoveFile(),
true);
}
TaskWrapperManager.getInstance().removeTaskWrapper(mEntity.getKey());
}
}
public AbsEntity getEntity() {
return mEntity;
}
@ -99,45 +57,19 @@ public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHand
/**
* 获取任务实体
*/
public AbsTaskWrapper getTaskWrapper() {
protected AbsTaskWrapper getTaskWrapper() {
return mTaskWrapper;
}
/**
* 获取任务进度如果任务存在则返回当前进度
*
* @return 该任务进度
*/
public long getCurrentProgress() {
return mEntity == null ? -1 : mEntity.getCurrentProgress();
}
/**
* 获取任务文件大小
*
* @return 文件大小
*/
public long getFileSize() {
return mEntity == null ? 0 : mEntity.getFileSize();
}
/**
* 获取单位转换后的文件大小
*
* @return 文件大小{@code xxx mb}
*/
public String getConvertFileSize() {
return mEntity == null ? "0b" : CommonUtil.formatFileSize(mEntity.getFileSize());
}
/**
* 设置扩展字段用来保存你的其它数据如果你的数据比较多你可以把你的数据转换为JSON字符串然后再存到Aria中
* 注意如果在后续方法调用链中没有调用 {@link #start()}{@link #stop()}{@link #cancel()}{@link #resume()}
* 等操作任务的方法那么你需要调用{@link #save()}才能将修改保存到数据库
* 设置扩展字段用来保存你的其它数据如果你的数据比较多你可以把你的数据转换为JSON字符串然后再存到数据库中
* 注意如果在后续方法调用链中没有调用 {@link ITargetHandler#start()}{@link ITargetHandler#stop()}{@link
* ITargetHandler#cancel()}{@link ITargetHandler#resume()}
* 等操作任务的方法那么你需要调用{@link NormalController#save()}才能将修改保存到数据库
*
* @param str 扩展数据
*/
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?")
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public TARGET setExtendField(String str) {
if (TextUtils.isEmpty(str)) return (TARGET) this;
if (TextUtils.isEmpty(mEntity.getStr()) || !mEntity.getStr().equals(str)) {
@ -150,219 +82,15 @@ public abstract class AbsTarget<TARGET extends AbsTarget> implements ITargetHand
}
/**
* 获取存放的扩展字段
* 设置扩展字段{@link #setExtendField(String)}
*/
public String getExtendField() {
return mEntity.getStr();
}
/**
* 获取任务状态
*
* @return {@link IEntity}
*/
public int getTaskState() {
return mEntity.getState();
}
/**
* 获取任务进度百分比
*
* @return 返回任务进度
*/
public int getPercent() {
if (mEntity == null) {
ALog.e("AbsTarget", "下载管理器中没有该任务");
return 0;
}
if (mEntity.getFileSize() != 0) {
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize());
}
return 0;
}
/**
* 检查实体是否合法如果实体合法将保存实体到数据库或更新数据库中的实体对象
*
* @return {@code true} 合法
*/
protected abstract boolean checkEntity();
protected int checkTaskType() {
int taskType = 0;
if (mTaskWrapper instanceof DTaskWrapper) {
taskType = ITask.DOWNLOAD;
} else if (mTaskWrapper instanceof DGTaskWrapper) {
taskType = ITask.DOWNLOAD_GROUP;
} else if (mTaskWrapper instanceof UTaskWrapper) {
taskType = ITask.UPLOAD;
}
return taskType;
}
/**
* 如果检查实体失败将错误回调
*/
protected boolean checkConfig() {
boolean b = checkEntity();
ISchedulers schedulers = getScheduler();
if (!b && schedulers != null) {
new Handler(Looper.getMainLooper(), schedulers).obtainMessage(ISchedulers.CHECK_FAIL,
checkTaskType(), -1, null).sendToTarget();
}
return b;
}
private ISchedulers getScheduler() {
int type = getTargetType();
switch (type) {
case D_FTP:
case D_HTTP:
return DownloadSchedulers.getInstance();
case U_FTP:
case U_HTTP:
return UploadSchedulers.getInstance();
case GROUP_HTTP:
case GROUP_FTP_DIR:
return DownloadGroupSchedulers.getInstance();
}
return null;
}
/**
* 保存修改
*/
@Override public void save() {
if (!checkConfig()) {
ALog.e(TAG, "保存修改失败");
} else {
ALog.i(TAG, "保存成功");
}
}
/**
* 任务是否在执行
*
* @return {@code true} 任务正在执行
*/
public abstract boolean isRunning();
/**
* 任务是否存在
*
* @return {@code true} 任务存在
*/
public abstract boolean taskExists();
/**
* 设置target类型
*
* @return {@link #D_HTTP}{@link #U_HTTP}{@link #D_FTP}{@link #U_FTP}{@link
* #GROUP_HTTP}{@link #GROUP_FTP_DIR}
*/
public abstract int getTargetType();
/**
* 添加任务
*/
@Override public void add() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CREATE,
checkTaskType()));
}
}
/**
* 开始任务
*/
@Override public void start() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START,
checkTaskType()));
}
}
/**
* 停止任务
*
* @see #stop()
*/
@Deprecated public void pause() {
stop();
}
@Override public void stop() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP,
checkTaskType()));
}
}
/**
* 恢复任务
*/
@Override public void resume() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START,
checkTaskType()));
}
}
/**
* 删除任务
*/
@Override public void cancel() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL,
checkTaskType()));
}
}
/**
* 任务重试
*/
@Override public void reTry() {
if (checkConfig()) {
int taskType = checkTaskType();
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_STOP, taskType));
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_START, taskType));
}
}
/**
* 删除任务
*
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录
*/
@Override public void cancel(boolean removeFile) {
if (checkConfig()) {
CancelCmd cancelCmd =
(CancelCmd) CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_CANCEL,
checkTaskType());
cancelCmd.removeFile = removeFile;
EventMsgUtil.getDefault().post(cancelCmd);
}
}
/**
* 重新下载
* 重置状态将任务状态设置为未开始状态
* 注意如果在后续方法调用链中没有调用 {@link NormalController#stop()}{@link NormalController#cancel()}
* {@link NormalController#resume()}{@link StartController#start()}{@link StartController#add()}
* 等操作任务的方法那么你需要调用{@link NormalController#save()}才能将修改保存到数据库
*/
@Override public void reStart() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CommonUtil.createNormalCmd(mTaskWrapper, NormalCmdFactory.TASK_RESTART,
checkTaskType()));
}
@CheckResult(suggest = "after use #start()、#stop()、#cancel()、#resume()、#save()?")
public TARGET resetState() {
getTaskWrapper().getEntity().setState(IEntity.STATE_WAIT);
getTaskWrapper().setRefreshInfo(true);
return (TARGET) this;
}
}

@ -39,28 +39,4 @@ public interface IConfigHandler {
* @return {@code true} 任务正在执行{@code false} 任务没有执行
*/
boolean isRunning();
/**
* 检查下载实体判断实体是否合法 合法标准为
* 1下载路径不为null并且下载路径是正常的http或ftp路径
* 2保存路径不为null并且保存路径是android文件系统路径
* 3保存路径不能重复
*
* @return {@code true}合法
*/
boolean checkEntity();
/**
* 检查并设置普通任务的文件保存路径
*
* @return {@code true}保存路径合法
*/
boolean checkFilePath();
/**
* 检查普通任务的下载地址
*
* @return {@code true}地址合法
*/
boolean checkUrl();
}

@ -1,57 +0,0 @@
/*
* 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.aria.core.inf;
import android.support.annotation.CheckResult;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/3/9.
*/
public interface IFtpTarget<TARGET extends ITargetHandler> {
/**
* 设置字符编码
*/
@CheckResult
TARGET charSet(String charSet);
/**
* ftp 用户登录信
*
* @param userName ftp用户名
* @param password ftp用户密码
*/
@CheckResult
TARGET login(String userName, String password);
/**
* ftp 用户登录信息
*
* @param userName ftp用户名
* @param password ftp用户密码
* @param account ftp账号
*/
@CheckResult
TARGET login(String userName, String password, String account);
///**
// * 设置代理
// *
// * @param proxy {@link Proxy}
// */
//@CheckResult
//TARGET setProxy(Proxy proxy);
}

@ -1,50 +0,0 @@
/*
* 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.aria.core.inf;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import java.net.Proxy;
import java.util.Map;
/**
* Created by laoyuyu on 2018/3/9.
* D_HTTP Header功能接口
*/
public interface IHttpHeaderDelegate<TARGET extends ITargetHandler> {
/**
* 给url请求添加Header数据
* 如果新的header数据和数据保存的不一致则更新数据库中对应的header数据
*
* @param key header对应的key
* @param value header对应的value
*/
@CheckResult
TARGET addHeader(@NonNull String key, @NonNull String value);
/**
* 给url请求添加一组header数据
* 如果新的header数据和数据保存的不一致则更新数据库中对应的header数据
*
* @param headers 一组http header数据
*/
@CheckResult
TARGET addHeaders(Map<String, String> headers);
@CheckResult
TARGET setUrlProxy(Proxy proxy);
}

@ -15,19 +15,17 @@
*/
package com.arialyy.aria.core.manager;
import com.arialyy.aria.core.download.DGEntityWrapper;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.DbDataHelper;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Aria.Lao on 2017/11/1. 组合任务wrapper
*/
class DGTaskWrapperFactory implements IGTEFactory<DownloadGroupEntity, DGTaskWrapper> {
class DGTaskWrapperFactory implements IGroupWrapperFactory<DownloadGroupEntity, DGTaskWrapper> {
private static final String TAG = "DTaskWrapperFactory";
private static volatile DGTaskWrapperFactory INSTANCE = null;
@ -43,40 +41,49 @@ class DGTaskWrapperFactory implements IGTEFactory<DownloadGroupEntity, DGTaskWra
return INSTANCE;
}
@Override public DGTaskWrapper getGTE(String groupHash, List<String> urls) {
DownloadGroupEntity entity = DbDataHelper.getOrCreateHttpDGEntity(groupHash, urls);
@Override public DGTaskWrapper getGroupWrapper(long taskId) {
if (taskId == -1) {
return new DGTaskWrapper(new DownloadGroupEntity());
}
DownloadGroupEntity entity = getOrCreateHttpDGEntity(taskId);
DGTaskWrapper wrapper = new DGTaskWrapper(entity);
wrapper.setSubTaskWrapper(createDGSubTaskWrapper(entity));
if (entity.getSubEntities() != null && !entity.getSubEntities().isEmpty()) {
wrapper.setSubTaskWrapper(DbDataHelper.createDGSubTaskWrapper(entity));
}
return wrapper;
}
@Override public DGTaskWrapper getFTE(String ftpUrl) {
DownloadGroupEntity entity = DbDataHelper.getOrCreateFtpDGEntity(ftpUrl);
DGTaskWrapper fte = new DGTaskWrapper(entity);
fte.asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(ftpUrl));
if (fte.getEntity().getSubEntities() == null) {
fte.getEntity().setSubEntities(new ArrayList<DownloadEntity>());
}
if (fte.getSubTaskWrapper() == null) {
fte.setSubTaskWrapper(new ArrayList<DTaskWrapper>());
}
return fte;
}
//@Override public DGTaskWrapper getFtpDirWrapper(long taskId) {
// DownloadGroupEntity entity = DbDataHelper.getOrCreateFtpDGEntity(ftpUrl);
// DGTaskWrapper fte = new DGTaskWrapper(entity);
// fte.asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(ftpUrl));
//
// if (fte.getEntity().getSubEntities() == null) {
// fte.getEntity().setSubEntities(new ArrayList<DownloadEntity>());
// }
// if (fte.getSubTaskWrapper() == null) {
// fte.setSubTaskWrapper(new ArrayList<DTaskWrapper>());
// }
// return fte;
//}
/**
* 创建任务组子任务的任务实体
* 获取组合任务实体 如果数据库不存在该实体则新创建一个新的任务组实体
*/
private List<DTaskWrapper> createDGSubTaskWrapper(DownloadGroupEntity dge) {
List<DTaskWrapper> list = new ArrayList<>();
for (DownloadEntity entity : dge.getSubEntities()) {
DTaskWrapper taskEntity = new DTaskWrapper(entity);
taskEntity.setGroupHash(dge.getKey());
taskEntity.setGroupTask(true);
list.add(taskEntity);
private DownloadGroupEntity getOrCreateHttpDGEntity(long taskId) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.rowid=?",
String.valueOf(taskId));
DownloadGroupEntity groupEntity;
if (wrapper != null && !wrapper.isEmpty()) {
groupEntity = wrapper.get(0).groupEntity;
if (groupEntity == null) {
groupEntity = new DownloadGroupEntity();
}
return list;
} else {
groupEntity = new DownloadGroupEntity();
}
return groupEntity;
}
}

@ -21,13 +21,12 @@ import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IEntity;
import java.io.File;
import java.util.UUID;
/**
* 创建下载任务wrapper Created by Aria.Lao on 2017/11/1.
*/
class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapper> {
private static final String TAG = "DTaskWrapperFactory";
private final String TAG = "DTaskWrapperFactory";
private static volatile DTaskWrapperFactory INSTANCE = null;
private DTaskWrapperFactory() {
@ -43,34 +42,27 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
}
/**
* 通过下载实体创建任务实体
* 通过下载地址创建任务实体
*/
private DTaskWrapper create(DownloadEntity entity) {
return new DTaskWrapper(entity);
@Override public DTaskWrapper create(long taskId) {
if (taskId == -1) {
return new DTaskWrapper(new DownloadEntity());
}
/**
* 通过下载地址创建任务实体
*/
@Override public DTaskWrapper create(String downloadUrl) {
return create(getEntity(downloadUrl));
return new DTaskWrapper(getEntity(taskId));
}
/**
* 如果任务存在但是下载实体不存在则通过下载地址获取下载实体
*
* @param downloadUrl 下载地址
*/
private DownloadEntity getEntity(String downloadUrl) {
private DownloadEntity getEntity(long taskId) {
DownloadEntity entity =
DownloadEntity.findFirst(DownloadEntity.class, "url=? and isGroupChild='false'",
downloadUrl);
DownloadEntity.findFirst(DownloadEntity.class, "rowid=? and isGroupChild='false'",
String.valueOf(taskId));
if (entity == null) {
entity = new DownloadEntity();
entity.setUrl(downloadUrl);
entity.setGroupChild(false);
entity.setGroupHash(null);
entity.setFilePath(UUID.randomUUID().toString().replace("-", "")); //设置临时路径
return entity;
}
File file = new File(entity.getFilePath());
@ -91,7 +83,8 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
if (count == record.threadNum) {
resetEntity(entity);
}
} else if (!file.exists() && record.taskType != TaskRecord.TYPE_M3U8_VOD) { // 非分块文件需要判断文件是否存在
} else if (!file.exists()
&& record.taskType != TaskRecord.TYPE_M3U8_VOD) { // 非分块文件需要判断文件是否存在
resetEntity(entity);
}
}

@ -17,30 +17,19 @@ package com.arialyy.aria.core.manager;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import java.util.List;
/**
* 任务组通过组创建任务
* Created by Aria.Lao on 2017/11/1.
*/
interface IGTEFactory<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskWrapper<ENTITY>> {
interface IGroupWrapperFactory<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskWrapper<ENTITY>> {
/**
* 获取任务组的任务实体
* 1创建实体和任务实体之间的关联
* 2如果在数据库中查找不到对应的数据则新创建任务实体
*
* @param groupHash 任务组名
* @param urls 子任务的下载地址
* @param taskId 组合任务任务Id
*/
TASK_ENTITY getGTE(String groupHash, List<String> urls);
/**
* 获取FTP文件夹的任务实体该方法需要以下操作
* 1创建实体和任务实体之间的关联
* 2如果在数据库中查找不到对应的数据则新创建任务实体
*
* @param ftpUrl ftp文件夹下载路径
*/
TASK_ENTITY getFTE(String ftpUrl);
TASK_ENTITY getGroupWrapper(long taskId);
}

@ -26,5 +26,5 @@ interface INormalTEFactory<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTask
/**
* 通过key创建任务只适应于单任务
*/
TASK_ENTITY create(String key);
TASK_ENTITY create(long taskId);
}

@ -22,7 +22,6 @@ import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@ -48,7 +47,7 @@ public class TaskWrapperManager {
lock = new ReentrantLock();
}
private IGTEFactory chooseGroupFactory(Class clazz) {
private IGroupWrapperFactory chooseGroupFactory(Class clazz) {
if (clazz == DGTaskWrapper.class) {
return DGTaskWrapperFactory.getInstance();
}
@ -65,52 +64,26 @@ public class TaskWrapperManager {
}
/**
* 从缓存中获取单任务实体如果任务实体不存在则创建任务实体
* 获取普通任务的Wrapper
*
* @param key 下载任务key为下载地址上传任务key为本地文件路径
* @return 创建失败返回null成功返回{@link DTaskWrapper}或者{@link UTaskWrapper}
*/
public <TE extends AbsTaskWrapper> TE getHttpTaskWrapper(Class<TE> clazz, String key) {
public <TW extends AbsTaskWrapper> TW getNormalTaskWrapper(Class<TW> clazz, long taskId) {
final Lock lock = this.lock;
lock.lock();
try {
AbsTaskWrapper wrapper = cache.get(convertKey(key));
AbsTaskWrapper wrapper = cache.get(convertKey(clazz, taskId));
if (wrapper == null || wrapper.getClass() != clazz) {
INormalTEFactory factory = chooseNormalFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
wrapper = factory.create(key);
cache.put(convertKey(key), wrapper);
wrapper = factory.create(taskId);
cache.put(convertKey(clazz, taskId), wrapper);
}
return (TE) wrapper;
} finally {
lock.unlock();
}
}
/**
* 从缓存中获取FTP文件夹任务实体如果任务实体不存在则创建任务实体
*
* @param key 下载任务key为下载地址上传任务key为本地文件路径
* @return 创建失败返回null成功返回{@link DTaskWrapper}
*/
public <TE extends AbsTaskWrapper> TE getFtpTaskWrapper(Class<TE> clazz, String key) {
final Lock lock = this.lock;
lock.lock();
try {
AbsTaskWrapper tEntity = cache.get(convertKey(key));
if (tEntity == null || tEntity.getClass() != clazz) {
IGTEFactory factory = chooseGroupFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
tEntity = factory.getFTE(key);
cache.put(convertKey(key), tEntity);
}
return (TE) tEntity;
return (TW) wrapper;
} finally {
lock.unlock();
}
@ -119,29 +92,24 @@ public class TaskWrapperManager {
/**
* 从缓存中获取HTTP任务组的任务实体如果任务实体不存在则创建任务实体 获取{}
*
* @param urls HTTP任务组的子任务下载地址列表
* @param taskId 任务ID
* @return 地址列表为null或创建实体失败返回null成功返回{@link DGTaskWrapper}
*/
public <TE extends AbsTaskWrapper> TE getDGTaskWrapper(Class<TE> clazz, List<String> urls) {
if (urls == null || urls.isEmpty()) {
ALog.e(TAG, "获取HTTP任务组实体失败:任务组的子任务下载地址列表为null");
return null;
}
public <TW extends AbsTaskWrapper> TW getGroupWrapper(Class<TW> clazz, long taskId) {
final Lock lock = this.lock;
lock.lock();
try {
String groupHash = CommonUtil.getMd5Code(urls);
AbsTaskWrapper tWrapper = cache.get(convertKey(groupHash));
AbsTaskWrapper tWrapper = cache.get(convertKey(clazz, taskId));
if (tWrapper == null || tWrapper.getClass() != clazz) {
IGTEFactory factory = chooseGroupFactory(clazz);
IGroupWrapperFactory factory = chooseGroupFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
tWrapper = factory.getGTE(groupHash, urls);
cache.put(convertKey(groupHash), tWrapper);
tWrapper = factory.getGroupWrapper(taskId);
cache.put(convertKey(clazz, taskId), tWrapper);
}
return (TE) tWrapper;
return (TW) tWrapper;
} finally {
lock.unlock();
}
@ -150,11 +118,11 @@ public class TaskWrapperManager {
/**
* 更新任务Wrapper
*/
public void putTaskWrapper(String key, AbsTaskWrapper tEntity) {
public void putTaskWrapper(AbsTaskWrapper wrapper) {
final Lock lock = this.lock;
lock.lock();
try {
cache.put(convertKey(key), tEntity);
cache.put(convertKey(wrapper.getClass(), wrapper.getEntity().getId()), wrapper);
} finally {
lock.unlock();
}
@ -165,15 +133,16 @@ public class TaskWrapperManager {
*
* @return {@code false} 实体为null添加失败
*/
public boolean addTaskWrapper(AbsTaskWrapper te) {
if (te == null) {
public boolean addTaskWrapper(AbsTaskWrapper wrapper) {
if (wrapper == null) {
ALog.e(TAG, "任务实体添加失败");
return false;
}
final Lock lock = this.lock;
lock.lock();
try {
return cache.put(convertKey(te.getKey()), te) != null;
return cache.put(convertKey(wrapper.getClass(), wrapper.getEntity().getId()), wrapper)
!= null;
} finally {
lock.unlock();
}
@ -182,24 +151,17 @@ public class TaskWrapperManager {
/**
* 通过key删除任务实体 当任务complete或删除记录时将删除缓存
*/
public AbsTaskWrapper removeTaskWrapper(String key) {
public AbsTaskWrapper removeTaskWrapper(AbsTaskWrapper wrapper) {
final Lock lock = this.lock;
lock.lock();
try {
return cache.remove(convertKey(key));
return cache.remove(convertKey(wrapper.getClass(), wrapper.getEntity().getId()));
} finally {
lock.unlock();
}
}
private String convertKey(String key) {
key = key.trim();
final Lock lock = this.lock;
lock.lock();
try {
return CommonUtil.keyToHashKey(key);
} finally {
lock.unlock();
}
private String convertKey(Class clazz, long taskId) {
return CommonUtil.keyToHashKey(clazz.getName() + taskId);
}
}

@ -17,8 +17,6 @@ package com.arialyy.aria.core.manager;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.Regular;
import java.util.regex.Pattern;
/**
* Created by Aria.Lao on 2017/11/1. 任务实体工厂
@ -39,29 +37,21 @@ class UTaskWrapperFactory implements INormalTEFactory<UploadEntity, UTaskWrapper
return INSTANCE;
}
private UTaskWrapper create(UploadEntity entity) {
return new UTaskWrapper(entity);
@Override public UTaskWrapper create(long taskId) {
if (taskId == -1) {
return new UTaskWrapper(new UploadEntity());
}
@Override public UTaskWrapper create(String key) {
return create(getUploadEntity(key));
return new UTaskWrapper(getUploadEntity(taskId));
}
/**
* 从数据中读取上传实体如果数据库查不到则新创建一个上传实体
*
* @param filePath 上传文件的文件路径
*/
private UploadEntity getUploadEntity(String filePath) {
UploadEntity entity = UploadEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
private UploadEntity getUploadEntity(long taskId) {
UploadEntity entity =
UploadEntity.findFirst(UploadEntity.class, "rowid=?", String.valueOf(taskId));
if (entity == null) {
entity = new UploadEntity();
String regex = Regular.REG_FILE_NAME;
Pattern p = Pattern.compile(regex);
String[] strs = p.split(filePath);
String fileName = strs[strs.length - 1];
entity.setFileName(fileName);
entity.setFilePath(filePath);
}
return entity;
}

@ -301,10 +301,10 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
}
if (what == CANCEL || what == COMPLETE) {
TaskWrapperManager.getInstance().removeTaskWrapper(task.getKey());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
} else {
if (what != RUNNING) {
TaskWrapperManager.getInstance().putTaskWrapper(task.getKey(), task.getTaskWrapper());
TaskWrapperManager.getInstance().putTaskWrapper(task.getTaskWrapper());
}
}
normalTaskCallback(what, task);
@ -487,7 +487,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
|| task.getTaskWrapper().getEntity().getFailNum() > reTryNum) {
mQueue.removeTaskFormQueue(task.getKey());
startNextTask(task.getSchedulerType());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getKey());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
normalTaskCallback(FAIL, task);
return;
}
@ -504,7 +504,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskWrapper, TASK extends IT
} else {
mQueue.removeTaskFormQueue(task.getKey());
startNextTask(task.getSchedulerType());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getKey());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
}
}
}, interval, TimeUnit.MILLISECONDS);

@ -0,0 +1,109 @@
/*
* 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.aria.core.upload;
import android.text.TextUtils;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import java.io.File;
public class CheckUEntityUtil {
private final String TAG = "CheckUEntityUtil";
private UTaskWrapper mWrapper;
private UploadEntity mEntity;
public static CheckUEntityUtil newInstance(UTaskWrapper wrapper) {
return new CheckUEntityUtil(wrapper);
}
private CheckUEntityUtil(UTaskWrapper wrapper) {
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}
public boolean checkEntity() {
boolean b = checkFtps() && checkUrl() && checkFilePath();
if (b) {
mEntity.save();
}
if (mWrapper.asFtp().getUrlEntity() != null && mWrapper.asFtp().getUrlEntity().isFtps) {
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return b;
}
private boolean checkFilePath() {
String filePath = mEntity.getFilePath();
if (TextUtils.isEmpty(filePath)) {
ALog.e(TAG, "上传失败,文件路径为null");
return false;
} else if (!filePath.startsWith("/")) {
ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法");
return false;
}
File file = new File(mEntity.getFilePath());
if (!file.exists()) {
ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在");
return false;
}
if (file.isDirectory()) {
ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹");
return false;
}
return true;
}
private boolean checkUrl() {
final String url = mWrapper.getTempUrl();
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "上传失败,url为null");
return false;
} else if (!CheckUtil.checkUrlNotThrow(url)) {
ALog.e(TAG, "上传失败,url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "上传失败,url【" + url + "】不合法");
return false;
}
mEntity.setUrl(url);
return true;
}
private boolean checkFtps() {
if (mWrapper.asFtp().getUrlEntity().isFtps) {
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(mWrapper.asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return true;
}
}

@ -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.aria.core.upload;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.util.CommonUtil;
/**
* Created by Aria.Lao on 2017/7/27.
* ftp单任务上传
*/
public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
private UNormalConfigHandler<FtpNormalTarget> mConfigHandler;
FtpNormalTarget(long taskId, String targetName) {
mConfigHandler = new UNormalConfigHandler<>(this, taskId, targetName);
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(getEntity().getUrl()));
getTaskWrapper().setRequestType(AbsTaskWrapper.U_FTP);
}
/**
* 设置登陆字符串编码ftps等参数
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDelegate<FtpNormalTarget> option() {
return new FtpDelegate<>(this, getTaskWrapper());
}
@Override public UploadEntity getEntity() {
return (UploadEntity) super.getEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
}

@ -0,0 +1,65 @@
/*
* 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.aria.core.upload;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
/**
* Created by Aria.Lao on 2017/7/27.
* ftp单任务上传
*/
public class FtpStartTarget extends AbsStartTarget<FtpStartTarget> {
private UNormalConfigHandler<FtpStartTarget> mConfigHandler;
FtpStartTarget(String filePath, String targetName) {
mConfigHandler = new UNormalConfigHandler<>(this, -1, targetName);
mConfigHandler.setFilePath(filePath);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_FTP);
}
/**
* 设置上传路径
*
* @param tempUrl 上传路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpStartTarget setUploadUrl(String tempUrl) {
mConfigHandler.setTempUrl(tempUrl);
return this;
}
/**
* FTP文件上传拦截器如果远端已有同名文件可使用该拦截器控制覆盖文件或修改该文件上传到服务器端端的文件名
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpStartTarget setUploadInterceptor(@NonNull IFtpUploadInterceptor uploadInterceptor) {
return mConfigHandler.setUploadInterceptor(uploadInterceptor);
}
/**
* 设置登陆字符串编码ftps等参数
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public FtpDelegate<FtpStartTarget> option() {
return new FtpDelegate<>(this, getTaskWrapper());
}
}

@ -1,110 +0,0 @@
/*
* 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.aria.core.upload;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.ftp.FTPSDelegate;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.util.CheckUtil;
import java.net.Proxy;
/**
* Created by Aria.Lao on 2017/7/27.
* ftp单任务上传
*/
public class FtpUploadTarget extends AbsUploadTarget<FtpUploadTarget>
implements IFtpTarget<FtpUploadTarget> {
private FtpDelegate<FtpUploadTarget> mFtpDelegate;
private UNormalConfigHandler<FtpUploadTarget> mConfigHandler;
FtpUploadTarget(String filePath, String targetName) {
mConfigHandler = new UNormalConfigHandler<>(this, filePath, targetName);
initTask();
}
private void initTask() {
getTaskWrapper().setRequestType(AbsTaskWrapper.U_FTP);
mFtpDelegate = new FtpDelegate<>(this);
}
/**
* 设置上传路径
*
* @param tempUrl 上传路径
*/
public FtpUploadTarget setUploadUrl(String tempUrl) {
mConfigHandler.setTempUrl(tempUrl);
return this;
}
/**
* FTP文件上传拦截器如果远端已有同名文件可使用该拦截器控制覆盖文件或修改该文件上传到服务器端端的文件名
*/
@CheckResult
public FtpUploadTarget setUploadInterceptor(@NonNull IFtpUploadInterceptor uploadInterceptor) {
return mConfigHandler.setUploadInterceptor(uploadInterceptor);
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSDelegate#setStorePath(String)} {@link FTPSDelegate#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSDelegate<FtpUploadTarget> asFtps() {
if (getTaskWrapper().asFtp().getUrlEntity() == null) {
FtpUrlEntity urlEntity = new FtpUrlEntity();
urlEntity.isFtps = true;
getTaskWrapper().asFtp().setUrlEntity(urlEntity);
}
return new FTPSDelegate<>(this);
}
@CheckResult
@Override public FtpUploadTarget charSet(String charSet) {
return mFtpDelegate.charSet(charSet);
}
@Override public FtpUploadTarget login(String userName, String password) {
return mFtpDelegate.login(userName, password);
}
@Override public FtpUploadTarget login(String userName, String password, String account) {
CheckUtil.checkFtpUploadUrl(mConfigHandler.getTempUrl());
return mFtpDelegate.login(userName, password, account);
}
@Override protected boolean checkEntity() {
return mConfigHandler.checkEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
@Override public int getTargetType() {
return U_FTP;
}
}

@ -0,0 +1,63 @@
/*
* 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.aria.core.upload;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
/**
* Created by lyy on 2017/2/28.
* http 单文件上传
*/
public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
private UNormalConfigHandler<HttpNormalTarget> mConfigHandler;
HttpNormalTarget(long taskId, String targetName) {
mConfigHandler = new UNormalConfigHandler<>(this, taskId, targetName);
getTaskWrapper().setSupportBP(false);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_HTTP);
}
/**
* 设置上传路径
*
* @param tempUrl 上传路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpNormalTarget setUploadUrl(String tempUrl) {
mConfigHandler.setTempUrl(tempUrl);
return this;
}
/**
* 设置http请求参数header等信息
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpDelegate<HttpNormalTarget> option() {
return new HttpDelegate<>(this, getTaskWrapper());
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
}

@ -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.aria.core.upload;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.Suggest;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
/**
* Created by lyy on 2017/2/28.
* http 单文件上传
*/
public class HttpStartTarget extends AbsStartTarget<HttpStartTarget> {
private UNormalConfigHandler<HttpStartTarget> mConfigHandler;
HttpStartTarget(String filePath, String targetName) {
mConfigHandler = new UNormalConfigHandler<>(this, -1, targetName);
mConfigHandler.setFilePath(filePath);
//http暂时不支持断点上传
getTaskWrapper().setSupportBP(false);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_HTTP);
}
/**
* 设置上传路径
*
* @param tempUrl 上传路径
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpStartTarget setUploadUrl(String tempUrl) {
mConfigHandler.setTempUrl(tempUrl);
return this;
}
/**
* 设置http请求参数header等信息
*/
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
public HttpDelegate<HttpStartTarget> option() {
return new HttpDelegate<>(this, getTaskWrapper());
}
}

@ -15,15 +15,13 @@
*/
package com.arialyy.aria.core.upload;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IConfigHandler;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.UploadTaskQueue;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
@ -31,42 +29,36 @@ import java.io.File;
* Created by Aria.Lao on 2019/4/5.
* 普通上传任务通用功能处理
*/
class UNormalConfigHandler<TARGET extends AbsUploadTarget> implements IConfigHandler {
class UNormalConfigHandler<TARGET extends AbsTarget> implements IConfigHandler {
private String TAG = "UNormalDelegate";
private UploadEntity mEntity;
private TARGET mTarget;
/**
* 上传路径
*/
private String mTempUrl;
private UTaskWrapper mWrapper;
UNormalConfigHandler(TARGET target, String filePath, String targetName) {
UNormalConfigHandler(TARGET target, long taskId, String targetName) {
mTarget = target;
initTarget(filePath, targetName);
initTarget(taskId, targetName);
}
private void initTarget(String filePath, String targetName) {
UTaskWrapper taskWrapper =
TaskWrapperManager.getInstance().getHttpTaskWrapper(UTaskWrapper.class, filePath);
mEntity = taskWrapper.getEntity();
File file = new File(filePath);
mEntity.setFileName(file.getName());
mEntity.setFileSize(file.length());
private void initTarget(long taskId, String targetName) {
mWrapper = TaskWrapperManager.getInstance().getNormalTaskWrapper(UTaskWrapper.class, taskId);
mEntity = mWrapper.getEntity();
mTarget.setTargetName(targetName);
mTarget.setTaskWrapper(taskWrapper);
mTempUrl = mEntity.getUrl();
mTarget.setTaskWrapper(mWrapper);
getTaskWrapper().setTempUrl(mEntity.getUrl());
}
TARGET updateUrl(String newUrl) {
mTempUrl = newUrl;
return mTarget;
void setFilePath(String filePath) {
File file = new File(filePath);
mEntity.setFileName(file.getName());
mEntity.setFileSize(file.length());
}
TARGET setUploadInterceptor(IFtpUploadInterceptor uploadInterceptor) {
if (uploadInterceptor == null) {
throw new NullPointerException("ftp拦截器为空");
}
mTarget.getTaskWrapper().asFtp().setUploadInterceptor(uploadInterceptor);
getTaskWrapper().asFtp().setUploadInterceptor(uploadInterceptor);
return mTarget;
}
@ -83,73 +75,12 @@ class UNormalConfigHandler<TARGET extends AbsUploadTarget> implements IConfigHan
return task != null && task.isRunning();
}
@Override public boolean checkEntity() {
boolean b = checkUrl() && checkFilePath();
if (b) {
mEntity.save();
}
if (mTarget.getTaskWrapper().asFtp().getUrlEntity() != null && mTarget.getTaskWrapper()
.asFtp()
.getUrlEntity().isFtps) {
if (TextUtils.isEmpty(mTarget.getTaskWrapper().asFtp().getUrlEntity().storePath)) {
ALog.e(TAG, "证书路径为空");
return false;
}
if (TextUtils.isEmpty(mTarget.getTaskWrapper().asFtp().getUrlEntity().keyAlias)) {
ALog.e(TAG, "证书别名为空");
return false;
}
}
return b;
}
@Override public boolean checkFilePath() {
String filePath = mEntity.getFilePath();
if (TextUtils.isEmpty(filePath)) {
ALog.e(TAG, "上传失败,文件路径为null");
return false;
} else if (!filePath.startsWith("/")) {
ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法");
return false;
}
File file = new File(mEntity.getFilePath());
if (!file.exists()) {
ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在");
return false;
}
if (file.isDirectory()) {
ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹");
return false;
}
return true;
}
@Override public boolean checkUrl() {
final String url = mTempUrl;
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "上传失败,url为null");
return false;
} else if (!CheckUtil.checkUrlNotThrow(url)) {
ALog.e(TAG, "上传失败,url【" + url + "】错误");
return false;
}
int index = url.indexOf("://");
if (index == -1) {
ALog.e(TAG, "上传失败,url【" + url + "】不合法");
return false;
}
mEntity.setUrl(url);
return true;
}
void setTempUrl(String tempUrl) {
this.mTempUrl = tempUrl;
mTarget.getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(tempUrl));
getTaskWrapper().setTempUrl(tempUrl);
getTaskWrapper().asFtp().setUrlEntity(CommonUtil.getFtpUrlInfo(tempUrl));
}
public String getTempUrl() {
return mTempUrl;
private UTaskWrapper getTaskWrapper() {
return mWrapper;
}
}

@ -24,10 +24,23 @@ import com.arialyy.aria.core.inf.AbsTaskWrapper;
*/
public class UTaskWrapper extends AbsTaskWrapper<UploadEntity> {
/**
* 保存临时设置的上传路径
*/
private String tempUrl;
public UTaskWrapper(UploadEntity entity) {
super(entity);
}
public String getTempUrl() {
return tempUrl;
}
public void setTempUrl(String tempUrl) {
this.tempUrl = tempUrl;
}
/**
* 文件保存路径
*/

@ -22,8 +22,10 @@ import com.arialyy.annotations.TaskEnum;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.CancelAllCmd;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.common.AbsStartTarget;
import com.arialyy.aria.core.common.ProxyHelper;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.ReceiverType;
@ -55,38 +57,84 @@ public class UploadReceiver extends AbsReceiver {
}
/**
* 加载HTTP单文件上传任务
* 加载HTTP单文件上传任务用于任务第一次上传如果需要控制任务停止或删除等操作请使用{@link #load(long)}
*
* @param filePath 文件路径
*/
@CheckResult
public UploadTarget load(@NonNull String filePath) {
public HttpStartTarget load(@NonNull String filePath) {
CheckUtil.checkUploadPath(filePath);
return new UploadTarget(filePath, targetName);
return new HttpStartTarget(filePath, targetName);
}
/**
* 加载FTP单文件上传任务
* 用于任务停止删除等操作
*
* @param taskId 任务id可从{@link AbsStartTarget#start()}{@link AbsStartTarget#add()}{@link
* AbsEntity#getId()}读取任务id
*/
@CheckResult
public HttpNormalTarget load(long taskId) {
CheckUtil.checkTaskId(taskId);
return new HttpNormalTarget(taskId, targetName);
}
/**
* 加载FTP单文件上传任务用于任务第一次上传如果需要控制任务停止或删除等操作请使用{@link #load(long)}
*
* @param filePath 文件路径
*/
@CheckResult
public FtpUploadTarget loadFtp(@NonNull String filePath) {
public FtpStartTarget loadFtp(@NonNull String filePath) {
CheckUtil.checkUploadPath(filePath);
return new FtpUploadTarget(filePath, targetName);
return new FtpStartTarget(filePath, targetName);
}
/**
* 加载FTP单文件上传任务用于任务第一次上传如果需要控制任务停止或删除等操作请使用{@link #load(long)}
*
* @param taskId 任务id可从{@link AbsStartTarget#start()}{@link AbsStartTarget#add()}{@link
* AbsEntity#getId()}读取任务id
*/
@CheckResult
public FtpNormalTarget loadFtp(long taskId) {
CheckUtil.checkTaskId(taskId);
return new FtpNormalTarget(taskId, targetName);
}
/**
* 通过上传路径获取上传实体
* 如果任务不存在方便null
*/
public UploadEntity getUploadEntity(String filePath) {
public UploadEntity getUploadEntity(long taskId) {
if (taskId == -1) {
return null;
}
return DbEntity.findFirst(UploadEntity.class, "rowid=?", String.valueOf(taskId));
}
/**
* 获取第一个匹配url的下载实体如果你有多个任务的下载地址都相同请使用{@link #getUploadEntity(long)}
* {@link #getUploadEntity(String)}
*/
public UploadEntity getFirstUploadEntity(String filePath) {
if (TextUtils.isEmpty(filePath)) {
return null;
}
return DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
}
/**
* 通过上传路径获取上传实体
* 如果任务不存在方便null
*/
public List<UploadEntity> getUploadEntity(String filePath) {
if (TextUtils.isEmpty(filePath)) {
return null;
}
return DbEntity.findDatas(UploadEntity.class, "filePath=?", filePath);
}
/**
* 上传任务是否存在
*

@ -1,125 +0,0 @@
/*
* 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.aria.core.upload;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.http.HttpDelegate;
import com.arialyy.aria.core.common.http.PostDelegate;
import com.arialyy.aria.core.inf.AbsTaskWrapper;
import java.net.Proxy;
import java.util.Map;
/**
* Created by lyy on 2017/2/28.
* http 单文件上传
*/
public class UploadTarget extends AbsUploadTarget<UploadTarget> {
private HttpDelegate<UploadTarget> mHttpDelegate;
private UNormalConfigHandler<UploadTarget> mConfigHandler;
UploadTarget(String filePath, String targetName) {
mConfigHandler = new UNormalConfigHandler<>(this, filePath, targetName);
initTask();
}
private void initTask() {
//http暂时不支持断点上传
getTaskWrapper().setSupportBP(false);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_HTTP);
mHttpDelegate = new HttpDelegate<>(this);
}
/**
* 设置上传路径
*
* @param tempUrl 上传路径
*/
public UploadTarget setUploadUrl(String tempUrl) {
mConfigHandler.setTempUrl(tempUrl);
return this;
}
/**
* Post处理
*/
@CheckResult
public PostDelegate asPost() {
mHttpDelegate = new PostDelegate<>(this);
return (PostDelegate) mHttpDelegate;
}
/**
* 设置userAgent
*/
@CheckResult
public UploadTarget setUserAngent(@NonNull String userAgent) {
getTaskWrapper().asHttp().setUserAgent(userAgent);
return this;
}
/**
* 设置服务器需要的附件key
*
* @param attachment 附件key
*/
@CheckResult
public UploadTarget setAttachment(@NonNull String attachment) {
getTaskWrapper().asHttp().setAttachment(attachment);
return this;
}
/**
* 设置上传文件类型
*
* @param contentType tipmultipart/form-data
*/
@CheckResult
public UploadTarget setContentType(String contentType) {
getTaskWrapper().asHttp().setContentType(contentType);
return this;
}
@CheckResult
public UploadTarget addHeader(@NonNull String key, @NonNull String value) {
return mHttpDelegate.addHeader(key, value);
}
@CheckResult
public UploadTarget addHeaders(Map<String, String> headers) {
return mHttpDelegate.addHeaders(headers);
}
public UploadTarget setUrlProxy(Proxy proxy) {
return mHttpDelegate.setUrlProxy(proxy);
}
@Override protected boolean checkEntity() {
return mConfigHandler.checkEntity();
}
@Override public boolean isRunning() {
return mConfigHandler.isRunning();
}
@Override public boolean taskExists() {
return mConfigHandler.taskExists();
}
@Override public int getTargetType() {
return U_HTTP;
}
}

@ -15,6 +15,7 @@
*/
package com.arialyy.aria.core.upload.uploader;
import android.text.TextUtils;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.common.http.HttpTaskConfig;
@ -73,8 +74,8 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UTaskWrapper> {
mHttpConn.setDoInput(true);
mHttpConn.setRequestProperty("Connection", "Keep-Alive");
mHttpConn.setRequestProperty("Content-Type",
taskDelegate.getContentType() + "; boundary=" + BOUNDARY);
mHttpConn.setRequestProperty("User-Agent", taskDelegate.getUserAgent());
getContentType() + "; boundary=" + BOUNDARY);
mHttpConn.setRequestProperty("User-Agent", getUserAgent());
mHttpConn.setConnectTimeout(getTaskConfig().getConnectTimeOut());
mHttpConn.setReadTimeout(getTaskConfig().getIOTimeOut());
//mHttpConn.setRequestProperty("Range", "bytes=" + 0 + "-" + "100");
@ -119,6 +120,23 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UTaskWrapper> {
}
}
private String getContentType() {
HttpTaskConfig config = getTaskWrapper().asHttp();
return
(config.getHeaders() == null || TextUtils.isEmpty(config.getHeaders().get("Content-Type")))
?
"multipart/form-data" : config.getHeaders().get("Content-Type");
}
private String getUserAgent() {
HttpTaskConfig config = getTaskWrapper().asHttp();
return
(config.getHeaders() == null || TextUtils.isEmpty(config.getHeaders().get("User-Agent")))
?
"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"
: config.getHeaders().get("User-Agent");
}
/**
* 添加文件上传表单字段
*/

@ -30,6 +30,10 @@ public abstract class DbEntity {
}
protected long getRowID() {
return rowID;
}
/**
* 查询关联数据
* <code>

@ -112,6 +112,15 @@ public class CheckUtil {
}
}
/**
* 检测url是否合法如果url不合法将抛异常
*/
public static void checkTaskId(long taskId) {
if (taskId < 0) {
throw new IllegalArgumentException("任务id不能小于0");
}
}
/**
* 检测url是否合法如果url不合法将抛异常
*/

@ -17,8 +17,8 @@ package com.arialyy.aria.util;
import com.arialyy.aria.core.common.RecordWrapper;
import com.arialyy.aria.core.common.TaskRecord;
import com.arialyy.aria.core.common.ThreadRecord;
import com.arialyy.aria.core.download.DGEntityWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.orm.DbEntity;
@ -61,42 +61,29 @@ public class DbDataHelper {
}
/**
* 获取组合任务实体 如果数据库不存在该实体则新创建一个新的任务组实体
* 获取组合任务实体ftpDir任务实体
*
* @param groupHash 组合任务Hash
* @param urls 子任务url列表
* @param taskId 组合任务id
* @return 实体不存在返回null
*/
public static DownloadGroupEntity getOrCreateHttpDGEntity(String groupHash, List<String> urls) {
public static DownloadGroupEntity getDGEntity(long taskId) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.groupHash=?",
groupHash);
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.rowid=?",
String.valueOf(taskId));
DownloadGroupEntity groupEntity;
if (wrapper != null && !wrapper.isEmpty()) {
groupEntity = wrapper.get(0).groupEntity;
if (groupEntity == null) {
groupEntity = new DownloadGroupEntity();
groupEntity.setSubEntities(createHttpSubTask(groupHash, urls));
}
} else {
groupEntity = new DownloadGroupEntity();
groupEntity.setSubEntities(createHttpSubTask(groupHash, urls));
}
groupEntity.setGroupHash(groupHash);
groupEntity.setUrls(urls);
return groupEntity;
return wrapper == null || wrapper.size() == 0 ? null : wrapper.get(0).groupEntity;
}
/**
* 创建HTTP子任务实体
*/
private static List<DownloadEntity> createHttpSubTask(String groupHash, List<String> urls) {
public static List<DownloadEntity> createHttpSubTask(String groupHash, List<String> urls) {
List<DownloadEntity> list = new ArrayList<>();
for (int i = 0, len = urls.size(); i < len; i++) {
String url = urls.get(i);
DownloadEntity entity = new DownloadEntity();
entity.setUrl(url);
entity.setDownloadPath(groupHash + "_" + i);
entity.setFilePath(groupHash + "_" + i);
int lastIndex = url.lastIndexOf(File.separator);
entity.setFileName(url.substring(lastIndex + 1));
entity.setGroupHash(groupHash);
@ -127,4 +114,18 @@ public class DbDataHelper {
groupEntity.setGroupHash(ftpUrl);
return groupEntity;
}
/**
* 创建任务组子任务的任务实体
*/
public static List<DTaskWrapper> createDGSubTaskWrapper(DownloadGroupEntity dge) {
List<DTaskWrapper> list = new ArrayList<>();
for (DownloadEntity entity : dge.getSubEntities()) {
DTaskWrapper taskEntity = new DTaskWrapper(entity);
taskEntity.setGroupHash(dge.getKey());
taskEntity.setGroupTask(true);
list.add(taskEntity);
}
return list;
}
}

@ -36,7 +36,6 @@
<activity android:name=".core.download.fragment_download.FragmentActivity"/>
<activity android:name=".core.download.multi_download.MultiDownloadActivity"/>
<activity android:name=".core.download.HighestPriorityActivity"/>
<activity android:name="com.arialyy.simple.core.test.TestMutilTaskSysDownload"/>
<activity android:name=".core.download.group.DownloadGroupActivity"/>
<activity android:name=".core.download.FtpDownloadActivity"/>
<activity android:name=".core.download.group.FTPDirDownloadActivity"/>

@ -21,7 +21,7 @@ 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.DownloadTarget
import com.arialyy.aria.core.download.HttpNormalTarget
import com.arialyy.aria.core.download.DownloadTask
import com.arialyy.aria.core.inf.IEntity
import com.arialyy.simple.R
@ -39,7 +39,7 @@ class KotlinDownloadActivity : BaseActivity<ActivitySingleBinding>() {
private lateinit var mStart: Button
private lateinit var mStop: Button
private lateinit var mCancel: Button
private lateinit var target: DownloadTarget
private lateinit var target: HttpNormalTarget
override fun setLayoutId(): Int {
return R.layout.activity_single

@ -28,6 +28,7 @@ import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsDialog;
import com.arialyy.simple.R;
import com.arialyy.simple.util.AppUtil;
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
/**
@ -36,10 +37,10 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
public class DownloadDialog extends AbsDialog implements View.OnClickListener {
private HorizontalProgressBarWithNumber mPb;
private Button mStart;
private Button mStop;
private Button mCancel;
private TextView mSize;
private TextView mSpeed;
private DownloadEntity mEntity;
private static final String DOWNLOAD_URL =
"http://static.gaoshouyou.com/d/4b/d7/e04b308d9cd7f0ad4cac18d1a514544c.apk";
@ -57,22 +58,20 @@ public class DownloadDialog extends AbsDialog implements View.OnClickListener{
Aria.download(this).register();
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);
DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int p = (int) (entity.getCurrentProgress() * 100 / entity.getFileSize());
mEntity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
if (mEntity != null) {
mSize.setText(CommonUtil.formatFileSize(mEntity.getFileSize()));
int p = (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize());
mPb.setProgress(p);
int state = entity.getState();
int state = mEntity.getState();
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
setBtState(true);
}
mStart.setOnClickListener(this);
mStop.setOnClickListener(this);
mCancel.setOnClickListener(this);
}
@ -80,16 +79,28 @@ public class DownloadDialog extends AbsDialog implements View.OnClickListener{
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")
.start();
mStart.setText(getContext().getString(R.string.stop));
break;
case R.id.stop:
Aria.download(this).load(DOWNLOAD_URL).stop();
}
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
Aria.download(this).load(mEntity.getId()).stop();
mStart.setText(getContext().getString(R.string.resume));
} else {
Aria.download(this).load(mEntity.getId()).resume();
mStart.setText(getContext().getString(R.string.stop));
}
break;
case R.id.cancel:
Aria.download(this).load(DOWNLOAD_URL).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel();
mStart.setText(getContext().getString(R.string.start));
}
break;
}
}
@ -124,6 +135,5 @@ public class DownloadDialog extends AbsDialog implements View.OnClickListener{
private void setBtState(boolean startEnable) {
mStart.setEnabled(startEnable);
mCancel.setEnabled(!startEnable);
mStop.setEnabled(!startEnable);
}
}

@ -9,11 +9,12 @@ import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.T;
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.
@ -21,6 +22,8 @@ import com.arialyy.simple.databinding.DialogFragmentDownloadBinding;
@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";
@ -31,10 +34,16 @@ import com.arialyy.simple.databinding.DialogFragmentDownloadBinding;
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
Aria.download(getContext()).register();
DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
getBinding().setProgress((int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
mEntity = Aria.download(getContext()).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.stop).setOnClickListener(this);
@ -90,24 +99,30 @@ import com.arialyy.simple.databinding.DialogFragmentDownloadBinding;
getBinding().setSpeed("");
}
@Download.onNoSupportBreakPoint(DOWNLOAD_URL)
public void onNoSupportBreakPoint(DownloadTask task) {
T.showShort(getContext(), "该下载链接不支持断点");
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (!AppUtil.chekEntityValid(mEntity)) {
Aria.download(getContext())
.load(DOWNLOAD_URL)
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/放置江湖.apk")
.start();
getBinding().setStateStr(getString(R.string.stop));
break;
case R.id.stop:
Aria.download(getContext()).load(DOWNLOAD_URL).stop();
}
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:
Aria.download(getContext()).load(DOWNLOAD_URL).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(getContext()).load(mEntity.getId()).cancel();
}
break;
}
}

@ -26,11 +26,12 @@ 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.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsPopupWindow;
import com.arialyy.simple.R;
import com.arialyy.simple.util.AppUtil;
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
/**
@ -39,10 +40,10 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
public class DownloadPopupWindow extends AbsPopupWindow implements View.OnClickListener {
private HorizontalProgressBarWithNumber mPb;
private Button mStart;
private Button mStop;
private Button mCancel;
private TextView mSize;
private TextView mSpeed;
private DownloadEntity mEntity;
private static final String DOWNLOAD_URL =
"http://static.gaoshouyou.com/d/25/57/2e25bd9d4557ba31e9beebacfaf9e804.apk";
@ -59,44 +60,54 @@ public class DownloadPopupWindow extends AbsPopupWindow implements View.OnClickL
private void initWidget() {
mPb = mView.findViewById(R.id.progressBar);
mStart = mView.findViewById(R.id.start);
mStop = mView.findViewById(R.id.stop);
mCancel = mView.findViewById(R.id.cancel);
mSize = mView.findViewById(R.id.size);
mSpeed = mView.findViewById(R.id.speed);
mStart.setOnClickListener(this);
mStop.setOnClickListener(this);
mCancel.setOnClickListener(this);
if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize());
mPb.setProgress(p);
mEntity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
if (mEntity != null) {
mPb.setProgress(mEntity.getPercent());
mSize.setText(CommonUtil.formatFileSize(mEntity.getFileSize()));
if (mEntity.getState() == IEntity.STATE_RUNNING) {
mStart.setText(getContext().getString(R.string.stop));
} else {
mStart.setText(getContext().getString(R.string.resume));
}
Aria.download(this).register();
DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState();
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
setBtState(true);
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 (!AppUtil.chekEntityValid(mEntity)) {
Aria.download(this)
.load(DOWNLOAD_URL)
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/消消乐.apk")
.start();
mStart.setText(getContext().getString(R.string.stop));
break;
case R.id.stop:
Aria.download(this).load(DOWNLOAD_URL).stop();
}
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
Aria.download(this).load(mEntity.getId()).stop();
mStart.setText(getContext().getString(R.string.resume));
} else {
Aria.download(this).load(mEntity.getId()).resume();
mStart.setText(getContext().getString(R.string.stop));
}
break;
case R.id.cancel:
Aria.download(this).load(DOWNLOAD_URL).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel();
}
break;
}
}
@ -105,24 +116,16 @@ public class DownloadPopupWindow extends AbsPopupWindow implements View.OnClickL
}
private void setBtState(boolean startEnable) {
mStart.setEnabled(startEnable);
mCancel.setEnabled(!startEnable);
mStop.setEnabled(!startEnable);
}
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
mSize.setText(CommonUtil.formatFileSize(task.getFileSize()));
setBtState(false);
}
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
setBtState(true);
mSpeed.setText("0.0kb/s");
mStart.setText(getContext().getString(R.string.resume));
}
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
setBtState(true);
mPb.setProgress(0);
mSpeed.setText("0.0kb/s");
}

@ -17,19 +17,16 @@ package com.arialyy.simple.core.download;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.controller.ControllerType;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.FtpDownloadTarget;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T;
@ -49,7 +46,7 @@ import java.io.IOException;
public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding> {
private String mUrl, mFilePath;
private FtpDownloadModule mModule;
private FtpDownloadTarget mTarget;
private DownloadEntity mEntity;
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
@ -63,10 +60,10 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
if (entity == null) {
return;
}
mTarget = Aria.download(FtpDownloadActivity.this).loadFtp(entity.getUrl());
if (mTarget.getTaskState() == IEntity.STATE_STOP) {
mEntity = entity;
if (mEntity.getState() == IEntity.STATE_STOP) {
getBinding().setStateStr(getString(R.string.resume));
} else if (mTarget.isRunning()) {
} else if (mEntity.getState() == IEntity.STATE_RUNNING) {
getBinding().setStateStr(getString(R.string.stop));
}
@ -92,18 +89,30 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (mTarget.isRunning()) {
if (!AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).loadFtp(mUrl)
.setFilePath(mFilePath, true)
.option().login("N0rI", "0qcK")
.controller(ControllerType.START_CONTROLLER)
.start();
getBinding().setStateStr(getString(R.string.stop));
break;
}
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
getBinding().setStateStr(getString(R.string.resume));
Aria.download(this).loadFtp(mUrl).stop();
Aria.download(this).loadFtp(mEntity.getId()).stop();
} else {
Aria.download(this).loadFtp(mEntity.getId()).resume();
getBinding().setStateStr(getString(R.string.stop));
Aria.download(this).loadFtp(mUrl).login("N0rI", "0qcK")
.setFilePath(mFilePath, true)
.start();
}
break;
case R.id.cancel:
Aria.download(this).loadFtp(mUrl).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).loadFtp(mEntity.getId()).cancel();
}
break;
}
}
@ -174,5 +183,4 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
mModule.updateFilePath(this, String.valueOf(data));
}
}
}

@ -48,7 +48,7 @@ public class FtpDownloadModule extends BaseViewModule {
String url = AppUtil.getConfigValue(context, FTP_URL_KEY, ftpDefUrl);
String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY, ftpDefPath);
singDownloadInfo = Aria.download(context).getDownloadEntity(url);
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
if (singDownloadInfo == null) {
singDownloadInfo = new DownloadEntity();
singDownloadInfo.setUrl(url);

@ -27,15 +27,15 @@ 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.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityHighestPriorityBinding;
import com.arialyy.simple.core.download.multi_download.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;
@ -54,6 +54,7 @@ public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorit
private TextView mSize;
private TextView mSpeed;
private RecyclerView mList;
private DownloadEntity mEntity;
private String mTaskName = "光明大陆";
private static final String DOWNLOAD_URL =
@ -83,16 +84,20 @@ public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorit
}
private void initWidget() {
DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
mPb.setProgress(target.getPercent());
if (target.getTaskState() == IEntity.STATE_STOP) {
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 (target.isRunning()) {
} else if (mEntity.getState() == IEntity.STATE_RUNNING) {
setBtState(false);
}
mSize.setText(target.getConvertFileSize());
mSize.setText(mEntity.getConvertFileSize());
}
List<DownloadEntity> temp = Aria.download(this).getTaskList();
if (temp != null && !temp.isEmpty()) {
for (DownloadEntity entity : temp) {
@ -143,8 +148,7 @@ public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorit
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
String text = ((TextView) view).getText().toString();
if (text.equals("重新开始?") || text.equals("开始")) {
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this)
.load(DOWNLOAD_URL)
.setFilePath(Environment.getExternalStorageDirectory().getPath()
@ -152,15 +156,21 @@ public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorit
+ mTaskName
+ ".apk")
.setHighestPriority();
} else if (text.equals("恢复")) {
Aria.download(this).load(DOWNLOAD_URL).resume();
} else {
Aria.download(this).load(mEntity.getId()).resume();
}
((TextView) view).setText(getString(R.string.stop));
break;
case R.id.stop:
Aria.download(this).load(DOWNLOAD_URL).pause();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).stop();
}
((TextView) view).setText(getString(R.string.resume));
break;
case R.id.cancel:
Aria.download(this).load(DOWNLOAD_URL).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel();
}
break;
}
}

@ -50,13 +50,13 @@ public class HttpDownloadModule extends BaseViewModule {
String url = AppUtil.getConfigValue(context, HTTP_URL_KEY, defUrl);
String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath);
singDownloadInfo = Aria.download(context).getDownloadEntity(url);
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
if (singDownloadInfo == null) {
singDownloadInfo = new DownloadEntity();
singDownloadInfo.setUrl(url);
File temp = new File(defFilePath);
singDownloadInfo.setDownloadPath(filePath);
singDownloadInfo.setFileName(temp.getName());
File file = new File(defFilePath);
singDownloadInfo.setFilePath(filePath);
singDownloadInfo.setFileName(file.getName());
} else {
AppUtil.setConfigValue(context, HTTP_PATH_KEY, singDownloadInfo.getDownloadPath());
AppUtil.setConfigValue(context, HTTP_URL_KEY, singDownloadInfo.getUrl());
@ -79,7 +79,7 @@ public class HttpDownloadModule extends BaseViewModule {
File temp = new File(filePath);
AppUtil.setConfigValue(context, HTTP_PATH_KEY, filePath);
singDownloadInfo.setFileName(temp.getName());
singDownloadInfo.setDownloadPath(filePath);
singDownloadInfo.setFilePath(filePath);
liveData.postValue(singDownloadInfo);
}

@ -27,14 +27,11 @@ import android.view.Menu
import android.view.MenuItem
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.download.DownloadTarget
import com.arialyy.aria.core.download.DownloadTask
import com.arialyy.aria.core.inf.IEntity
import com.arialyy.aria.core.inf.IHttpFileLenAdapter
import com.arialyy.aria.core.scheduler.ISchedulers
import com.arialyy.aria.util.ALog
import com.arialyy.aria.util.CommonUtil
@ -46,7 +43,6 @@ 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>() {
@ -54,7 +50,7 @@ class KotlinDownloadActivity : BaseActivity<ActivitySingleKotlinBinding>() {
private var mUrl: String? = null
private var mFilePath: String? = null
private var mModule: HttpDownloadModule? = null
private var mTarget: DownloadTarget? = null
private val mTaskId: Long = -1
internal var receiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(
@ -99,11 +95,11 @@ class KotlinDownloadActivity : BaseActivity<ActivitySingleKotlinBinding>() {
if (entity == null) {
return@Observer
}
mTarget = Aria.download(this)
.load(entity.url)
if (mTarget!!.taskState == IEntity.STATE_STOP) {
if (entity.state == IEntity.STATE_STOP) {
binding.stateStr = getString(R.string.resume)
} else if (mTarget!!.isRunning) {
}
if (Aria.download(this).load(entity.id).isRunning) {
binding.stateStr = getString(R.string.stop)
}
@ -265,15 +261,15 @@ class KotlinDownloadActivity : BaseActivity<ActivitySingleKotlinBinding>() {
fun onClick(view: View) {
when (view.id) {
R.id.start -> if (mTarget!!.isRunning) {
R.id.start -> if (Aria.download(this).load(mTaskId).isRunning) {
Aria.download(this)
.load(mUrl!!)
.load(mTaskId)
.stop()
} else {
startD()
}
R.id.stop -> Aria.download(this).load(mUrl!!).stop()
R.id.cancel -> Aria.download(this).load(mUrl!!).cancel(true)
R.id.stop -> Aria.download(this).load(mTaskId).stop()
R.id.cancel -> Aria.download(this).load(mTaskId).cancel(true)
}
}

@ -32,7 +32,6 @@ 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.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
@ -56,7 +55,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
private String mUrl;
private String mFilePath;
private HttpDownloadModule mModule;
private DownloadTarget mTarget;
private DownloadEntity mEntity;
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
@ -96,10 +95,11 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
if (entity == null) {
return;
}
mTarget = Aria.download(SingleTaskActivity.this).load(entity.getUrl());
if (mTarget.getTaskState() == IEntity.STATE_STOP) {
mEntity = entity;
if (mEntity.getState() == IEntity.STATE_STOP) {
getBinding().setStateStr(getString(R.string.resume));
} else if (mTarget.isRunning()) {
} else if (mEntity.getState() == IEntity.STATE_RUNNING) {
getBinding().setStateStr(getString(R.string.stop));
}
@ -267,14 +267,19 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (mTarget.isRunning()) {
Aria.download(this).load(mUrl).stop();
} else {
if (!AppUtil.chekEntityValid(mEntity)) {
startD();
}
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
Aria.download(this).load(mEntity.getId()).stop();
} else {
Aria.download(this).load(mEntity.getId()).resume();
}
break;
case R.id.cancel:
Aria.download(this).load(mUrl).cancel(true);
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel(true);
}
break;
}
}
@ -282,10 +287,6 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
private void startD() {
Aria.download(SingleTaskActivity.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")
.useServerFileName(true)
.setFilePath(mFilePath, true)
.setFileLenAdapter(new IHttpFileLenAdapter() {

@ -21,14 +21,15 @@ import android.os.Environment;
import android.view.View;
import android.widget.Button;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsFragment;
import com.arialyy.simple.R;
import com.arialyy.simple.databinding.FragmentDownloadBinding;
import com.arialyy.simple.util.AppUtil;
/**
* Created by lyy on 2017/1/4.
@ -36,31 +37,30 @@ import com.arialyy.simple.databinding.FragmentDownloadBinding;
public class DownloadFragment extends AbsFragment<FragmentDownloadBinding>
implements View.OnClickListener {
Button mStart;
Button mStop;
Button mCancel;
private DownloadEntity mEntity;
private static final String DOWNLOAD_URL =
"https://res5.d.cn/2137e42d610b3488d9420c6421529386eee5bdbfd9be1fafe0a05d6dabaec8c156ddbd00581055bbaeac03904fb63310e80010680235d16bd4c040b50096a0c20dd1c4b0854529a1.apk";
@Override protected void init(Bundle savedInstanceState) {
mStart = mRootView.findViewById(R.id.start);
mStop = mRootView.findViewById(R.id.stop);
mCancel = mRootView.findViewById(R.id.cancel);
mStart.setOnClickListener(this);
mStop.setOnClickListener(this);
mCancel.setOnClickListener(this);
if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
getBinding().setProgress(target.getPercent());
mEntity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
if (mEntity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(mEntity.getFileSize()));
int state = mEntity.getState();
getBinding().setProgress(mEntity.getPercent());
if (mEntity.getState() == IEntity.STATE_RUNNING) {
getBinding().setStateStr(getString(R.string.stop));
} else {
getBinding().setStateStr(getString(R.string.resume));
}
DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState();
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
setBtState(true);
getBinding().setStateStr(getString(R.string.start));
}
Aria.download(this).register();
}
@ -68,34 +68,44 @@ public class DownloadFragment extends AbsFragment<FragmentDownloadBinding>
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")
.start();
getBinding().setStateStr(getString(R.string.stop));
break;
case R.id.stop:
Aria.download(this).load(DOWNLOAD_URL).pause();
}
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:
Aria.download(this).load(DOWNLOAD_URL).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel();
}
break;
}
}
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
getBinding().setFileSize(task.getConvertFileSize());
setBtState(false);
}
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
setBtState(true);
getBinding().setSpeed("");
getBinding().setStateStr(getString(R.string.resume));
}
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
setBtState(true);
getBinding().setProgress(0);
getBinding().setSpeed("");
getBinding().setStateStr(getString(R.string.cancel));
}
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
@ -119,10 +129,4 @@ public class DownloadFragment extends AbsFragment<FragmentDownloadBinding>
@Override protected void dataCallback(int result, Object obj) {
}
private void setBtState(boolean startEnable) {
mStart.setEnabled(startEnable);
mCancel.setEnabled(!startEnable);
mStop.setEnabled(!startEnable);
}
}

@ -23,8 +23,8 @@ import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTarget;
import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import com.arialyy.aria.util.ALog;
import com.arialyy.frame.util.show.L;
@ -32,6 +32,7 @@ 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.util.AppUtil;
import com.arialyy.simple.widget.SubStateLinearLayout;
import java.util.List;
import java.util.Map;
@ -43,7 +44,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
private SubStateLinearLayout mChildList;
private List<String> mUrls;
private DownloadGroupTarget mTarget;
private DownloadGroupEntity mEntity;
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
@ -52,21 +53,21 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
mChildList = getBinding().childList;
mUrls = getModule(GroupModule.class).getUrls();
DownloadGroupEntity entity = Aria.download(this).getDownloadGroupEntity(mUrls);
if (entity != null) {
mTarget = Aria.download(this).loadGroup(entity);
mChildList.addData(entity.getSubEntities());
mEntity = Aria.download(this).getGroupEntity(mUrls);
if (mEntity != null) {
mChildList.addData(mEntity.getSubEntities());
getBinding().setStateStr(
mTarget.isRunning() ? getString(R.string.stop) : getString(R.string.resume));
getBinding().setFileSize(entity.getConvertFileSize());
if (entity.getFileSize() == 0) {
mEntity.getState() == IEntity.STATE_RUNNING ? getString(R.string.stop)
: getString(R.string.resume));
getBinding().setFileSize(mEntity.getConvertFileSize());
if (mEntity.getFileSize() == 0) {
getBinding().setProgress(0);
} else {
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
getBinding().setProgress(mEntity.isComplete() ? 100
: (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize()));
}
ALog.d(TAG,
"size = " + entity.getSubEntities().size() + "; len = " + entity.getConvertFileSize());
"size = " + mEntity.getSubEntities().size() + "; len = " + mEntity.getConvertFileSize());
}
mChildList.setOnItemClickListener(new SubStateLinearLayout.OnItemClickListener() {
@ -89,16 +90,15 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (mTarget == null || !mTarget.isRunning()) {
if (!AppUtil.chekEntityValid(mEntity)) {
Aria.download(this)
.loadGroup(mUrls)
.setDirPath(
//Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_5")
Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_2")
.setGroupAlias("任务组测试")
//.setSubFileName(getModule(GroupModule.class).getSubName2())
//.setSubFileName(getModule(GroupModule.class).getSubName())
//.unknownSize()
.setSubFileName(getModule(GroupModule.class).getSubName())
.unknownSize()
.setFileLenAdapter(new IHttpFileLenAdapter() {
@Override public long handleFileLen(Map<String, List<String>> headers) {
@ -115,13 +115,19 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
//.updateUrls(temp)
.start();
getBinding().setStateStr(getString(R.string.stop));
break;
}
if (Aria.download(this).loadGroup(mEntity.getId()).isRunning()) {
Aria.download(this).loadGroup(mEntity.getId()).stop();
} else {
Aria.download(this).loadGroup(mUrls).stop();
getBinding().setStateStr(getString(R.string.resume));
Aria.download(this).loadGroup(mEntity.getId()).resume();
}
break;
case R.id.cancel:
Aria.download(this).loadGroup(mUrls).cancel(true);
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).loadGroup(mEntity.getId()).cancel(true);
}
break;
}
}
@ -200,7 +206,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
//Log.e(TAG, "gHash = "
// + groupTask.getEntity().getSubEntities().get(0).hashCode()
// + "; subHash = "
// + groupTask.getHttpTaskWrapper().getSubTaskEntities().get(0).getEntity().hashCode() +
// + groupTask.getNormalTaskWrapper().getSubTaskEntities().get(0).getEntity().hashCode() +
// "; subHash = " + subEntity.hashCode());
//int percent = subEntity.getPercent();
////如果你打开了速度单位转换配置,将可以通过以下方法获取带单位的下载速度,如:1 mb/s

@ -20,14 +20,15 @@ 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.controller.ControllerType;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.frame.util.show.L;
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.util.AppUtil;
import com.arialyy.simple.widget.SubStateLinearLayout;
/**
@ -36,22 +37,23 @@ import com.arialyy.simple.widget.SubStateLinearLayout;
public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBinding> {
private static final String dir = "ftp://9.9.9.50:21/upload/测试";
SubStateLinearLayout mChildList;
private SubStateLinearLayout mChildList;
private DownloadGroupEntity mEntity;
@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) {
mChildList.addData(entity.getSubEntities());
getBinding().setFileSize(entity.getConvertFileSize());
if (entity.getFileSize() == 0) {
mEntity = Aria.download(this).getFtpDirEntity(dir);
if (mEntity != null) {
mChildList.addData(mEntity.getSubEntities());
getBinding().setFileSize(mEntity.getConvertFileSize());
if (mEntity.getFileSize() == 0) {
getBinding().setProgress(0);
} else {
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
getBinding().setProgress(mEntity.isComplete() ? 100
: (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize()));
}
}
}
@ -63,20 +65,28 @@ public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBi
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (!AppUtil.chekEntityValid(mEntity)) {
Aria.download(this)
.loadFtpDir(dir)
.setDirPath(
Environment.getExternalStorageDirectory().getPath() + "/Download/ftp_dir")
.setGroupAlias("ftp文件夹下载")
//.setSubTaskFileName(getModule(GroupModule.class).getSubName())
.option()
.login("lao", "123456")
.controller(ControllerType.START_CONTROLLER)
.start();
break;
case R.id.stop:
Aria.download(this).loadFtpDir(dir).stop();
}
if (Aria.download(this).loadFtpDir(mEntity.getId()).isRunning()) {
Aria.download(this).loadFtpDir(mEntity.getId()).stop();
} else {
Aria.download(this).loadFtpDir(mEntity.getId()).resume();
}
break;
case R.id.cancel:
Aria.download(this).loadFtpDir(dir).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).loadFtpDir(mEntity.getId()).cancel();
}
break;
}
}

@ -27,8 +27,8 @@ import android.view.View;
import android.widget.Toast;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.controller.ControllerType;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.m3u8.ILiveTsUrlConverter;
import com.arialyy.aria.util.ALog;
@ -39,6 +39,7 @@ 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.util.AppUtil;
import java.io.File;
public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding> {
@ -46,7 +47,7 @@ public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding>
private String mUrl;
private String mFilePath;
private M3U8LiveModule mModule;
private DownloadTarget mTarget;
private DownloadEntity mEntity;
@Override
protected void init(Bundle savedInstanceState) {
@ -60,7 +61,7 @@ public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding>
if (entity == null) {
return;
}
mTarget = Aria.download(M3U8LiveDLoadActivity.this).load(entity.getUrl());
mEntity = entity;
getBinding().setStateStr(getString(R.string.start));
getBinding().setUrl(entity.getUrl());
getBinding().setFilePath(entity.getFilePath());
@ -211,15 +212,20 @@ public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding>
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
ALog.d(TAG, "isRunning = " + mTarget.isRunning());
if (mTarget.isRunning()) {
Aria.download(this).load(mUrl).stop();
} else {
if (!AppUtil.chekEntityValid(mEntity)) {
startD();
break;
}
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
Aria.download(this).load(mEntity.getId()).stop();
} else {
Aria.download(this).load(mEntity.getId()).resume();
}
break;
case R.id.cancel:
Aria.download(this).load(mUrl).cancel(true);
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel(true);
}
break;
}
}
@ -244,6 +250,7 @@ public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding>
return parentUrl + tsUrl;
}
})
.controller(ControllerType.START_CONTROLLER)
//.setLiveTsUrlConvert(new IVodTsUrlConverter() {
// @Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
// int peerIndex = m3u8Url.lastIndexOf("/");

@ -47,7 +47,7 @@ public class M3U8LiveModule extends BaseViewModule {
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).getDownloadEntity(url);
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
if (singDownloadInfo == null) {
singDownloadInfo = new DownloadEntity();
singDownloadInfo.setUrl(url);

@ -29,8 +29,9 @@ import android.widget.Toast;
import com.arialyy.annotations.Download;
import com.arialyy.annotations.M3U8;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.controller.ControllerType;
import com.arialyy.aria.core.common.controller.StartController;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.m3u8.IBandWidthUrlConverter;
import com.arialyy.aria.core.download.m3u8.ITsMergeHandler;
@ -46,6 +47,7 @@ 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.util.AppUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -58,8 +60,8 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
private String mUrl;
private String mFilePath;
private M3U8VodModule mModule;
private DownloadTarget mTarget;
private VideoPlayerFragment mVideoFragment;
private DownloadEntity mEntity;
@Override
protected void init(Bundle savedInstanceState) {
@ -73,10 +75,10 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
if (entity == null) {
return;
}
mTarget = Aria.download(M3U8VodDLoadActivity.this).load(entity.getUrl());
if (mTarget.getTaskState() == IEntity.STATE_STOP) {
mEntity = entity;
if (mEntity.getState() == IEntity.STATE_STOP) {
getBinding().setStateStr(getString(R.string.resume));
} else if (mTarget.isRunning()) {
} else if (mEntity.getState() == IEntity.STATE_RUNNING) {
getBinding().setStateStr(getString(R.string.stop));
}
@ -270,15 +272,20 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
ALog.d(TAG, "isRunning = " + mTarget.isRunning());
if (mTarget.isRunning()) {
Aria.download(this).load(mUrl).stop();
} else {
if (!AppUtil.chekEntityValid(mEntity)) {
startD();
break;
}
if (Aria.download(this).load(mEntity.getId()).isRunning()) {
Aria.download(this).load(mEntity.getId()).stop();
} else {
Aria.download(this).load(mEntity.getId()).resume();
}
break;
case R.id.cancel:
Aria.download(this).load(mUrl).cancel(true);
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel(true);
}
break;
}
}
@ -312,10 +319,15 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
return false;
}
})
//.asVod().setPeerIndex(50)
.controller(ControllerType.START_CONTROLLER)
.start();
//.start();
//.asVod().setPeerIndex(50)
//.start();
}
private Class<StartController> c = StartController.class;
@Override protected void dataCallback(int result, Object data) {
super.dataCallback(result, data);
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {

@ -49,7 +49,7 @@ public class M3U8VodModule extends BaseViewModule {
String url = AppUtil.getConfigValue(context, M3U8_URL_KEY, defUrl);
String filePath = AppUtil.getConfigValue(context, M3U8_PATH_KEY, this.filePath);
singDownloadInfo = Aria.download(context).getDownloadEntity(url);
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
if (singDownloadInfo == null) {
singDownloadInfo = new DownloadEntity();
singDownloadInfo.setUrl(url);

@ -33,6 +33,7 @@ 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;
@ -269,20 +270,23 @@ public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.Sim
}
private void cancel(AbsEntity entity) {
if (!AppUtil.chekEntityValid(entity)) {
return;
}
switch (entity.getTaskType()) {
case AbsTaskWrapper.D_FTP:
Aria.download(getContext())
.loadFtp((DownloadEntity) entity)
.loadFtp(entity.getId())
//.login("lao", "123456")
.cancel(true);
break;
case AbsTaskWrapper.D_FTP_DIR:
break;
case AbsTaskWrapper.D_HTTP:
Aria.download(getContext()).load((DownloadEntity) entity).cancel(true);
Aria.download(getContext()).load(entity.getId()).cancel(true);
break;
case AbsTaskWrapper.DG_HTTP:
Aria.download(getContext()).load((DownloadGroupEntity) entity).cancel(true);
Aria.download(getContext()).load(entity.getId()).cancel(true);
break;
}
}
@ -291,32 +295,35 @@ public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.Sim
switch (entity.getTaskType()) {
case AbsTaskWrapper.D_FTP:
//Aria.download(getContext()).loadFtp((DownloadEntity) entity).login("lao", "123456").start();
Aria.download(getContext()).loadFtp((DownloadEntity) entity).charSet("GBK").start();
Aria.download(getContext()).loadFtp(entity.getKey()).start();
break;
case AbsTaskWrapper.D_FTP_DIR:
break;
case AbsTaskWrapper.D_HTTP:
Aria.download(getContext()).load((DownloadEntity) entity).start();
Aria.download(getContext()).load(entity.getKey()).start();
break;
case AbsTaskWrapper.DG_HTTP:
Aria.download(getContext()).loadGroup((DownloadGroupEntity) entity).start();
Aria.download(getContext()).loadGroup(((DownloadGroupEntity) entity).getUrls()).start();
break;
}
}
private void stop(AbsEntity entity) {
if (!AppUtil.chekEntityValid(entity)) {
return;
}
switch (entity.getTaskType()) {
case AbsTaskWrapper.D_FTP:
//Aria.download(getContext()).loadFtp((DownloadEntity) entity).login("lao", "123456").stop();
Aria.download(getContext()).loadFtp((DownloadEntity) entity).charSet("GBK").stop();
Aria.download(getContext()).loadFtp(entity.getId()).stop();
break;
case AbsTaskWrapper.D_FTP_DIR:
break;
case AbsTaskWrapper.D_HTTP:
Aria.download(getContext()).load((DownloadEntity) entity).stop();
Aria.download(getContext()).load(entity.getId()).stop();
break;
case AbsTaskWrapper.DG_HTTP:
Aria.download(getContext()).loadGroup((DownloadGroupEntity) entity).stop();
Aria.download(getContext()).loadGroup(entity.getId()).stop();
break;
}
}

@ -1,91 +0,0 @@
package com.arialyy.simple.core.test;
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 TestFTPActivity 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/AriaPrj.rar";
@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, "onStart");
}
@Download.onTaskRunning protected void running(DownloadTask task) {
Log.d(TAG, "running,speed=" + task.getConvertSpeed());
}
@Download.onTaskResume void taskResume(DownloadTask task) {
Log.d(TAG, "resume");
}
@Download.onTaskStop void taskStop(DownloadTask task) {
Log.d(TAG, "stop");
}
@Download.onTaskCancel void taskCancel(DownloadTask task) {
Log.d(TAG, "cancel");
}
@Download.onTaskFail void taskFail(DownloadTask task) {
Log.d(TAG, "fail");
}
@Download.onTaskComplete void taskComplete(DownloadTask task) {
Log.d(TAG, "complete, md5 => " + CommonUtil.getFileMD5(new File(task.getKey())));
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.download(this)
.loadFtp(URL)
.setFilePath(FILE_PATH)
.login("lao", "123456")
//.asFtps() // ftps 配置
//.setStorePath("/mnt/sdcard/Download/server.crt") //设置证书路径
// .setAlias("www.laoyuyu.me") // 设置证书别名
.start();
break;
case R.id.stop:
Aria.download(this).loadFtp(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.download(this).loadFtp(FILE_PATH).cancel();
break;
}
}
}

@ -1,104 +0,0 @@
package com.arialyy.simple.core.test;
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.download.DownloadGroupTask;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityTestBinding;
import com.arialyy.simple.core.download.group.GroupModule;
import java.util.List;
/**
* Created by Administrator on 2018/4/12.
*/
public class TestFTPDirActivity extends BaseActivity<ActivityTestBinding> {
List<String> mUrls;
private static final String dir = "ftps://192.168.29.140:990/upload/测试";
@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();
mUrls = getModule(GroupModule.class).getUrls();
}
@DownloadGroup.onWait void taskWait(DownloadGroupTask task) {
L.d(TAG, task.getTaskName() + "wait");
}
@DownloadGroup.onPre() protected void onPre(DownloadGroupTask task) {
L.d(TAG, "group pre");
}
@DownloadGroup.onTaskPre() protected void onTaskPre(DownloadGroupTask task) {
L.d(TAG, "group task pre");
}
@DownloadGroup.onTaskStart() void taskStart(DownloadGroupTask task) {
L.d(TAG, "group task start");
}
@DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) {
L.d(TAG, "group task running");
}
@DownloadGroup.onTaskResume() void taskResume(DownloadGroupTask task) {
L.d(TAG, "group task resume");
}
@DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) {
L.d(TAG, "group task stop");
}
@DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) {
L.d(TAG, "group task cancel");
}
@DownloadGroup.onTaskFail() void taskFail(DownloadGroupTask task) {
L.d(TAG, "group task fail");
}
@DownloadGroup.onTaskComplete() void taskComplete(DownloadGroupTask task) {
L.d(TAG, "group task complete");
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
//Aria.download(this)
// .loadGroup(mUrls)
// .setDirPath(Environment.getExternalStorageDirectory().getPath() + "/download/test/")
// .resetState()
// .start();
Aria.download(this)
.loadFtpDir(dir)
.setDirPath(
Environment.getExternalStorageDirectory().getPath() + "/Download/ftp_dir")
.setGroupAlias("ftp文件夹下载")
//.setSubTaskFileName(getModule(GroupModule.class).getSubName())
.login("lao", "123456")
.asFtps()
.setStorePath("/mnt/sdcard/Download/server.crt")
.setAlias("www.laoyuyu.me")
.setStorePass("123456")
.start();
break;
case R.id.stop:
Aria.download(this).loadFtpDir(dir).stop();
break;
case R.id.cancel:
Aria.download(this).loadFtpDir(dir).cancel();
break;
}
}
}

@ -1,80 +0,0 @@
package com.arialyy.simple.core.test;
import android.os.Environment;
import android.view.View;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.TestActivityMultiBinding;
/**
* Created by AriaL on 2017/6/15.
*/
public class TestMutilTaskSysDownload extends BaseActivity<TestActivityMultiBinding> {
@Override protected int setLayoutId() {
return R.layout.test_activity_multi;
}
public void onClick(View view) {
String baseUrl = "http://file.bmob.cn/";
String[] urlArray = {
"M02/3B/A4/oYYBAFaOeUSAc1QiAAFTbmA7AHs052.jpg",
"M02/3B/A4/oYYBAFaOeUaAfYC-AAFD8zf9NXc879.jpg",
"M02/3B/A4/oYYBAFaOeUuAOxhnAACSdmbqSac702.jpg",
"M02/3B/A4/oYYBAFaOeU2AFAIGAAFICximvXc924.jpg",
"M02/3B/A4/oYYBAFaOeVCAPWMQAAFm2KWCq_E721.jpg",
"M02/3B/A4/oYYBAFaOeVOAbiv9AAFfCTTgr94948.jpg",
"M02/3B/A4/oYYBAFaOeVaAMR3tAAFf3yTuuCM577.jpg",
"M02/3B/A4/oYYBAFaOeVmACEWhAAEt72ecbpg468.jpg",
"M02/3B/A4/oYYBAFaOeVyAHHt4AAFg9e9bRio507.jpg",
"M02/3B/A4/oYYBAFaOeV-AClYXAAESLGY0gag424.jpg",
"M02/3B/A4/oYYBAFaOeWKAA7N0AAF3omYOJUI703.jpg",
"M02/3B/A4/oYYBAFaOeWWAD2lrAAFN7eRFxBs575.jpg",
"M02/3B/A4/oYYBAFaOeWiAdCVEAAFg4273Dus313.jpg",
"M02/3B/A4/oYYBAFaOeWyAJDm5AAF8JVoGVb0705.jpg",
"M02/3B/A4/oYYBAFaOeW-AUoA8AAGjKiHkXUo181.jpg",
"M02/3B/A4/oYYBAFaOeXKABIamAAFU7J7vraE265.jpg",
"M02/3B/A5/oYYBAFaOeXaAW09jAAFf37qdwDA457.jpg",
"M02/3B/A5/oYYBAFaOeXmAWmS7AAFtLNpWjgo967.jpg",
"M02/3B/A5/oYYBAFaOeX2AQf9cAAF2fhwS2UE145.jpg",
"M02/3B/A5/oYYBAFaOeYCAKGnLAAFVAzks-qU937.jpg",
"M02/3B/A5/oYYBAFaOeYOAMODNAAF6HjTTMq4819.jpg",
"M02/3B/A5/oYYBAFaOeYeAbn8uAAFLSQLw48Q042.jpg",
"M02/3B/A5/oYYBAFaOeYqAMJThAAFtrNe4UNM047.jpg",
"M02/3B/A5/oYYBAFaOeY2AbnQvAAFNSXWn0Dc026.jpg",
"M02/3B/A5/oYYBAFaOeZCAIsr0AAFHZFEVhPc682.jpg",
"M02/3B/A5/oYYBAFaOeZOAGvITAAFqPmfcc9c471.jpg",
"M02/3B/A5/oYYBAFaOeZaATvjbAAFHDmALnhE003.jpg",
"M02/3B/A5/oYYBAFaOeZmAJPuVAAFfPJC2wsE319.jpg",
"M02/3B/A5/oYYBAFaOeZyAXtAmAAFfArJNwtM371.jpg",
"M02/3B/A5/oYYBAFaOeZ-AGZN0AAFgqwYYCS8004.jpg",
"M02/3B/A5/oYYBAFaOeaOAbbrGAAFcq59JjUo205.jpg",
"M02/3B/A5/oYYBAFaOeaSAdFyoAACaxVxgUJA092.jpg"
};
int maxNum = Aria.get(this).getDownloadConfig().getMaxTaskNum();
Aria.get(this).setDownloadQueueMod(QueueMod.NOW);
for (int i = 0; i < urlArray.length; i++) {
Aria.download(this)
.load(baseUrl + urlArray[i])
.setFilePath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
//.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
.start();
//if (i < maxNum) {
// Aria.download(this)
// .load(baseUrl + urlArray[i])
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
// .start();
//} else {
// Aria.download(this)
// .load(baseUrl + urlArray[i])
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
// .add();
//}
}
}
}

@ -16,6 +16,7 @@
package com.arialyy.simple.core.upload;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@ -24,8 +25,10 @@ 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.controller.ControllerType;
import com.arialyy.aria.core.common.ftp.FtpInterceptHandler;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.ALog;
@ -40,7 +43,6 @@ import com.arialyy.simple.util.AppUtil;
import java.io.File;
import java.io.IOException;
import java.util.List;
import android.arch.lifecycle.ViewModelProviders;
/**
* Created by lyy on 2017/7/28. Ftp 文件上传demo
@ -50,6 +52,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private String mFilePath;
private String mUrl;
private UploadModule mModule;
private UploadEntity mEntity;
@Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传");
@ -64,6 +67,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
mModule = ViewModelProviders.of(this).get(UploadModule.class);
mModule.getFtpInfo(this).observe(this, new Observer<UploadEntity>() {
@Override public void onChanged(@Nullable UploadEntity entity) {
mEntity = entity;
if (entity != null) {
if (entity.getFileSize() != 0) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
@ -74,6 +78,10 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
getBinding().setFilePath(entity.getFilePath());
mUrl = entity.getUrl();
mFilePath = entity.getFilePath();
getBinding().setStateStr(getString(
entity.getState() == IEntity.STATE_RUNNING ? R.string.stop : R.string.resume));
} else {
getBinding().setStateStr(getString(R.string.resume));
}
}
});
@ -105,11 +113,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
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();
getBinding().setStateStr(getString(R.string.resume));
} else {
getBinding().setStateStr(getString(R.string.stop));
if (!AppUtil.chekEntityValid(mEntity)) {
Aria.upload(this).loadFtp(mFilePath).setUploadUrl(mUrl).setUploadInterceptor(
new IFtpUploadInterceptor() {
@ -121,13 +125,26 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
return builder.build();
}
})
//.login("lao", "123456")
.option()
.login("N0rI", "0qcK")
.controller(ControllerType.START_CONTROLLER)
.start();
getBinding().setStateStr(getString(R.string.stop));
break;
}
if (Aria.download(this).loadFtp(mEntity.getId()).isRunning()) {
Aria.download(this).loadFtp(mEntity.getId()).stop();
getBinding().setStateStr(getString(R.string.resume));
} else {
Aria.download(this).loadFtp(mEntity.getId()).resume();
getBinding().setStateStr(getString(R.string.stop));
}
break;
case R.id.cancel:
Aria.upload(this).loadFtp(mFilePath).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.upload(this).loadFtp(mEntity.getId()).cancel();
}
break;
}
}

@ -20,12 +20,14 @@ import android.os.Bundle;
import android.view.View;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityUploadBinding;
import com.arialyy.simple.util.AppUtil;
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
import java.io.File;
@ -36,7 +38,8 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
private static final String TAG = "HttpUploadActivity";
HorizontalProgressBarWithNumber mPb;
private static final String FILE_PATH = "/mnt/sdcard/test.apk";
private final String FILE_PATH = "/mnt/sdcard/test.apk";
private UploadEntity mEntity;
@Override protected int setLayoutId() {
return R.layout.activity_upload;
@ -45,6 +48,9 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
@Override protected void init(Bundle savedInstanceState) {
setTile("D_HTTP 上传");
super.init(savedInstanceState);
mEntity = Aria.upload(this).getFirstUploadEntity(FILE_PATH);
Aria.upload(this).register();
getBinding().upload.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
@ -70,16 +76,19 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
"http://lib-test.xzxyun.com:8042/Api/upload?data={\"type\":\"1\",\"fileType\":\".apk\"}")
//.setTempUrl("http://192.168.1.6:8080/upload/sign_file/").setAttachment("file")
//.addHeader("iplanetdirectorypro", "11a09102fb934ad0bc206f9c611d7933")
.asPost()
.start();
}
void stop() {
Aria.upload(this).load(FILE_PATH).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.upload(this).load(mEntity.getId()).stop();
}
}
void remove() {
Aria.upload(this).load(FILE_PATH).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.upload(this).load(mEntity.getId()).cancel();
}
}
@Upload.onPre public void onPre(UploadTask task) {

@ -39,7 +39,7 @@ public class UploadModule extends BaseViewModule {
String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
Environment.getExternalStorageDirectory().getPath() + "/AriaPrj.rar");
UploadEntity entity = Aria.upload(context).getUploadEntity(filePath);
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);
if (entity != null) {
uploadInfo = entity;
AppUtil.setConfigValue(context, FTP_URL_KEY, uploadInfo.getUrl());

@ -20,9 +20,12 @@ 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.controller.ControllerType;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.util.AppUtil;
import java.io.File;
/**
@ -33,6 +36,7 @@ public class AnyRunnModule {
String TAG = "AnyRunnModule";
private Context mContext;
private String mUrl;
private DownloadEntity mEntity;
public AnyRunnModule(Context context) {
Aria.download(this).register();
@ -78,33 +82,54 @@ public class AnyRunnModule {
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()
.start();
} 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)
.login("lao", "123456")
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/Download/")
.option()
.asFtps()
.setStorePath("/mnt/sdcard/Download/server.crt")
.setAlias("www.laoyuyu.me")
.setStorePass("123456")
.controller(ControllerType.START_CONTROLLER)
.start();
} else {
Aria.download(this).load(mEntity.getId()).resume();
}
}
public void stop(String url) {
Aria.download(this).load(url).stop();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).stop();
}
}
public void cancel(String url) {
Aria.download(this).load(url).cancel();
if (AppUtil.chekEntityValid(mEntity)) {
Aria.download(this).load(mEntity.getId()).cancel();
}
}
public void unRegister() {

@ -24,6 +24,7 @@ import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.simple.BuildConfig;
@ -34,6 +35,15 @@ 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下载示例代码
*/

@ -55,15 +55,6 @@
style="?buttonBarButtonStyle"
/>
<Button
android:id="@+id/stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onClick"
android:text="暂停"
style="?buttonBarButtonStyle"
/>
<Button
android:id="@+id/cancel"

@ -15,6 +15,11 @@
name="progress"
type="int"
/>
<variable
name="stateStr"
type="String"
/>
</data>
<LinearLayout
android:layout_width="match_parent"
@ -23,10 +28,11 @@
>
<include
layout="@layout/content_single"
layout="@layout/layout_content_single"
bind:fileSize="@{fileSize}"
bind:progress="@{progress}"
bind:speed="@{speed}"
bind:stateStr="@{stateStr}"
/>
</LinearLayout>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save