Merge branch 'v_3.0'

pull/330/head
AriaLyy 7 years ago
commit bc03b82e76
  1. 4
      Aria/build.gradle
  2. 6
      Aria/src/main/java/com/arialyy/aria/core/Aria.java
  3. 2
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  4. 26
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java
  5. 5
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpThreadTask.java
  6. 6
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  7. 10
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  8. 22
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  9. 6
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
  10. 2
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java
  11. 16
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  12. 15
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
  13. 15
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java
  14. 20
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  15. 10
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  16. 2
      Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
  17. 34
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  18. 19
      Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java
  19. 3
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  20. 8
      DEV_LOG.md
  21. 21
      README.md
  22. 10
      app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java
  23. 48
      app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
  24. 13
      app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java
  25. 19
      app/src/main/java/com/arialyy/simple/upload/HttpUploadActivity.java
  26. 2
      build.gradle

@ -23,8 +23,8 @@ dependencies {
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile project(':AriaAnnotations')
compile 'com.arialyy.aria:aria-ftp-plug:1.0.3'
// compile 'com.arialyy.aria:aria-ftp-plug:1.0.3'
// compile project(':AriaFtpPlug')
compile project(':AriaFtpPlug')
}
apply from: 'bintray-release.gradle'

@ -26,14 +26,8 @@ import android.app.Service;
import android.content.Context;
import android.os.Build;
import android.widget.PopupWindow;
import com.arialyy.annotations.Download;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.download.DownloadReceiver;
import com.arialyy.aria.core.scheduler.IDownloadSchedulerListener;
import com.arialyy.aria.core.scheduler.ISchedulerListener;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.upload.UploadReceiver;
import com.arialyy.aria.core.upload.UploadTask;
/**
* Created by lyy on 2016/12/1.

@ -69,8 +69,6 @@ import org.xml.sax.SAXException;
public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/";
public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/";
@SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null;
private Map<String, AbsReceiver> mReceivers = new ConcurrentHashMap<>();
public static Context APP;

@ -23,6 +23,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.Regular;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.regex.Matcher;
@ -77,11 +78,19 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
String remotePath =
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET);
FTPFile[] files = client.listFiles(remotePath);
String s = client.getReplyString();
ALog.i(TAG, s);
boolean isExist = files.length != 0;
if (!isExist && !isUpload) {
failDownload("文件不存在,任务链接【" + mTaskEntity.urlEntity.url + "】", false);
FTPFile[] files1 = client.listFiles();
failDownload("文件不存在,任务链接【" + mTaskEntity.urlEntity.url + "】,remotePath:" + remotePath,
false);
int i = remotePath.lastIndexOf(File.separator);
FTPFile[] files1;
if (i == -1) {
files1 = client.listFiles();
} else {
files1 = client.listFiles(remotePath.substring(0, i + 1));
}
if (files1.length > 0) {
ALog.i(TAG, "路径【" + setRemotePath() + "】下的文件列表 ===================================");
for (FTPFile file : files1) {
@ -89,7 +98,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
}
ALog.i(TAG,
"================================= --end-- ===================================");
}else {
} else {
String msg = client.getReplyString();
ALog.w(TAG, msg);
}
@ -105,7 +114,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
mTaskEntity.isNewTask = true;
} else {
client.disconnect();
failDownload("获取文件信息错误,错误码为:" + reply, true);
failDownload("获取文件信息错误,错误码为:" + reply + ",msg:" + client.getReplyString(), true);
return;
}
}
@ -196,13 +205,14 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
failDownload("无法连接到ftp服务器,错误码为:" + reply, true);
failDownload("无法连接到ftp服务器,错误码为:" + reply + ",msg:" + client.getReplyString(), true);
return null;
}
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8";
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
reply = client.sendCommand("OPTS UTF8", "ON");
if (!TextUtils.isEmpty(mTaskEntity.charSet) || (!FTPReply.isPositiveCompletion(reply)
&& reply != FTPReply.COMMAND_OK)) {
ALog.i(TAG, "FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码");
charSet = mTaskEntity.charSet;
}

@ -72,7 +72,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
}
}
if (client == null){
if (client == null) {
return null;
}
@ -87,7 +87,8 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
fail(STATE.CURRENT_LOCATION, "无法连接到ftp服务器,错误码为:" + reply, null);
fail(STATE.CURRENT_LOCATION,
"无法连接到ftp服务器,错误码为:" + reply + ",msg:" + client.getReplyString(), null);
return null;
}
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码

@ -232,7 +232,11 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
ALog.w(TAG,
"任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__重试失败,网络未连接");
}
if (mFailNum < RETRY_NUM && needRetry && NetUtils.isConnected(AriaManager.APP)) {
if (mFailNum < RETRY_NUM
&& needRetry
&& NetUtils.isConnected(AriaManager.APP)
&& !STATE.isCancel
&& !STATE.isStop) {
mFailTimer = new Timer(true);
mFailTimer.schedule(new TimerTask() {
@Override public void run() {

@ -108,7 +108,7 @@ public class DownloadReceiver extends AbsReceiver {
* </pre>
*/
@Deprecated public DownloadTarget load(@NonNull String url, boolean refreshInfo) {
CheckUtil.checkUrl(url);
url = CheckUtil.checkUrl(url);
return new DownloadTarget(url, targetName, refreshInfo);
}
@ -165,7 +165,7 @@ public class DownloadReceiver extends AbsReceiver {
* @param refreshInfo 是否刷新下载信息
*/
public FtpDownloadTarget loadFtp(@NonNull String url, boolean refreshInfo) {
CheckUtil.checkUrl(url);
url = CheckUtil.checkUrl(url);
return new FtpDownloadTarget(url, targetName, refreshInfo);
}
@ -183,7 +183,7 @@ public class DownloadReceiver extends AbsReceiver {
* 加载ftp文件夹下载地址
*/
public FtpDirDownloadTarget loadFtpDir(@NonNull String dirUrl) {
CheckUtil.checkUrl(dirUrl);
dirUrl = CheckUtil.checkUrl(dirUrl);
return new FtpDirDownloadTarget(dirUrl, targetName);
}
@ -239,7 +239,7 @@ public class DownloadReceiver extends AbsReceiver {
* 通过下载链接获取下载实体
*/
public DownloadEntity getDownloadEntity(String downloadUrl) {
CheckUtil.checkUrl(downloadUrl);
downloadUrl = CheckUtil.checkUrl(downloadUrl);
return DbEntity.findFirst(DownloadEntity.class, "url=? and isGroupChild='false'", downloadUrl);
}
@ -247,7 +247,7 @@ public class DownloadReceiver extends AbsReceiver {
* 通过下载链接获取保存在数据库的下载任务实体
*/
public DownloadTaskEntity getDownloadTask(String downloadUrl) {
CheckUtil.checkUrl(downloadUrl);
downloadUrl = CheckUtil.checkUrl(downloadUrl);
DownloadEntity entity = getDownloadEntity(downloadUrl);
if (entity == null || TextUtils.isEmpty(entity.getDownloadPath())) return null;
return DbEntity.findFirst(DownloadTaskEntity.class, "key=? and isGroupTask='false'",

@ -34,7 +34,7 @@ import org.apache.commons.net.ftp.FTPReply;
* Ftp下载任务
*/
class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> {
private final String TAG = "FtpThreadTask";
private final String TAG = "FtpDownloadThreadTask";
FtpThreadTask(StateConstance constance, IDownloadListener listener,
SubThreadConfig<DownloadTaskEntity> downloadInfo) {
@ -59,17 +59,29 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
+ "】");
client = createClient();
if (client == null) return;
client.setRestartOffset(mConfig.START_LOCATION);
if (mConfig.START_LOCATION > 0) {
client.setRestartOffset(mConfig.START_LOCATION);
}
//发送第二次指令时,还需要再做一次判断
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.COMMAND_OK) {
fail(mChildCurrentLocation, "获取文件信息错误,错误码为:" + reply + ",msg:" + client.getReplyString(),
null);
client.disconnect();
return;
}
String remotePath =
new String(mTaskEntity.urlEntity.remotePath.getBytes(charSet), SERVER_CHARSET);
ALog.i(TAG, "remotePath【" + remotePath + "】");
is = client.retrieveFileStream(remotePath);
//发送第二次指令时,还需要再做一次判断
int reply = client.getReplyCode();
reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply)) {
fail(mChildCurrentLocation, "获取流失败,错误码为:" + reply + ",msg:" + client.getReplyString(),
null);
client.disconnect();
fail(mChildCurrentLocation, "获取文件信息错误,错误码为:" + reply, null);
return;
}
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
file.seek(mConfig.START_LOCATION);
byte[] buffer = new byte[mBufSize];

@ -16,12 +16,12 @@
package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.io.IOException;
import java.net.HttpURLConnection;
@ -130,12 +130,14 @@ class HttpFileInfoThread implements Runnable {
private void handle302Turn(HttpURLConnection conn) throws IOException {
String newUrl = conn.getHeaderField(mTaskEntity.redirectUrlKey);
ALog.d(TAG, "30x跳转,location【 " + mTaskEntity.redirectUrlKey + "】" + "新url为【" + newUrl + "】");
if (TextUtils.isEmpty(newUrl) || newUrl.equalsIgnoreCase("null")) {
if (TextUtils.isEmpty(newUrl) || newUrl.equalsIgnoreCase("null") || !newUrl.startsWith(
"http")) {
if (onFileInfoListener != null) {
onFileInfoListener.onFail(mEntity.getUrl(), "获取重定向链接失败", false);
}
return;
}
newUrl = CheckUtil.checkUrl(newUrl);
String cookies = conn.getHeaderField("Set-Cookie");
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);

@ -35,7 +35,7 @@ public abstract class AbsUploadTarget<TARGET extends AbsUploadTarget, ENTITY ext
* @param uploadUrl 上传路径
*/
public TARGET setUploadUrl(@NonNull String uploadUrl) {
CheckUtil.checkUrl(uploadUrl);
uploadUrl = CheckUtil.checkUrl(uploadUrl);
if (mEntity.getUrl().equals(uploadUrl)) return (TARGET) this;
mEntity.setUrl(uploadUrl);
mEntity.update();

@ -53,12 +53,15 @@ public class FtpUploadTarget
}
/**
* 设置上传路径
* 设置上传路径FTP上传路径必须是从"/"开始的完整路径
*
* @param uploadUrl 上传路径
*/
public FtpUploadTarget setUploadUrl(@NonNull String uploadUrl) {
CheckUtil.checkUrl(uploadUrl);
uploadUrl = CheckUtil.checkUrl(uploadUrl);
if (!uploadUrl.endsWith("/")) {
uploadUrl += "/";
}
mTaskEntity.urlEntity = CommonUtil.getFtpUrlInfo(uploadUrl);
if (mEntity.getUrl().equals(uploadUrl)) return this;
mEntity.setUrl(uploadUrl);
@ -66,6 +69,15 @@ public class FtpUploadTarget
return this;
}
/**
* 设置字符编码
*/
public FtpUploadTarget charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) return this;
mTaskEntity.charSet = charSet;
return this;
}
/**
* ftp 用户登录信
* 设置登录信息需要在设置上传链接之后{@link #setUploadUrl(String)}

@ -18,8 +18,8 @@ package com.arialyy.aria.core.upload;
import android.os.Parcel;
import android.os.Parcelable;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.orm.Foreign;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.orm.Foreign;
import com.arialyy.aria.orm.Primary;
/**
@ -29,6 +29,19 @@ import com.arialyy.aria.orm.Primary;
public class UploadEntity extends AbsNormalEntity implements Parcelable {
@Primary @Foreign(table = UploadTaskEntity.class, column = "key") private String filePath; //文件路径
/**
* 上传完成后服务器返回的数据
*/
private String responseStr = "";
public String getResponseStr() {
return responseStr;
}
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
public String getFilePath() {
return filePath;
}

@ -19,6 +19,7 @@ import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.util.Properties;
@ -29,6 +30,7 @@ import org.apache.commons.net.ftp.FTPFile;
* 单任务远程服务器文件信息
*/
class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity> {
private static final String TAG = "FtpUploadFtpFileInfoThread";
static final int CODE_COMPLETE = 0xab1;
private boolean isComplete = false;
@ -56,12 +58,21 @@ class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity>
if (ftpFile.getSize() == mEntity.getFileSize()) {
isComplete = true;
} else {
ALog.w(TAG, "FTP服务器已存在未完成的文件【"
+ ftpFile.getName()
+ ",size: "
+ ftpFile.getSize()
+ "】"
+ "尝试从位置:"
+ ftpFile.getSize()
+ "开始上传");
File configFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName()));
Properties pro = CommonUtil.loadConfig(configFile);
String key = mEntity.getFileName() + "_record_" + 0;
mTaskEntity.isNewTask = false;
long oldRecord = Long.parseLong(pro.getProperty(key, "0"));
if (oldRecord != 0) {
//修改本地保存的停止地址为服务器上的真实地址
if (oldRecord == 0) {
//修改本地保存的停止地址为服务器上对应文件的大小
pro.setProperty(key, ftpFile.getSize() + "");
CommonUtil.saveConfig(configFile, pro);
}

@ -35,7 +35,7 @@ import org.apache.commons.net.ftp.OnFtpInputStreamListener;
* FTP 单线程上传任务需要FTP 服务器给用户打开删除和读入IO的权限
*/
class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
private final String TAG = "FtpThreadTask";
private final String TAG = "FtpUploadThreadTask";
private String dir, remotePath;
FtpThreadTask(StateConstance constance, IEventListener listener,
@ -64,6 +64,13 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
client.makeDirectory(dir);
client.changeWorkingDirectory(dir);
client.setRestartOffset(mConfig.START_LOCATION);
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.FILE_ACTION_OK) {
fail(mChildCurrentLocation, "上传失败,错误码为:" + reply + ",msg:" + client.getReplyString(), null);
client.disconnect();
return;
}
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
if (mConfig.START_LOCATION != 0) {
//file.skipBytes((int) mConfig.START_LOCATION);
@ -82,7 +89,7 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
STATE.isRunning = false;
mListener.onComplete();
}
if (STATE.isFail()){
if (STATE.isFail()) {
STATE.isRunning = false;
mListener.onFail(false);
}
@ -107,7 +114,7 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
private void initPath() throws UnsupportedEncodingException {
dir = new String(mTaskEntity.urlEntity.remotePath.getBytes(charSet), SERVER_CHARSET);
remotePath = new String(
(mTaskEntity.urlEntity.remotePath + "/" + mEntity.getFileName()).getBytes(charSet),
("/" + mTaskEntity.urlEntity.remotePath + mEntity.getFileName()).getBytes(charSet),
SERVER_CHARSET);
}
@ -115,6 +122,7 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
throws IOException {
try {
ALog.d(TAG, "remotePath【" + remotePath + "】");
client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() {
boolean isStoped = false;
@ -141,11 +149,13 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
if (reply != FTPReply.TRANSFER_ABORTED) {
fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply + ",msg:" + client.getReplyString(),
null);
}
if (client.isConnected()) {
client.disconnect();
}
if (reply == FTPReply.TRANSFER_ABORTED) return;
fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply, null);
}
}

@ -89,7 +89,8 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
addFormField(writer, key, mTaskEntity.formFields.get(key));
}
uploadFile(writer, mTaskEntity.attachment, uploadFile);
finish(writer);
mTaskEntity.getEntity().setResponseStr(finish(writer));
mListener.onComplete();
} catch (Exception e) {
e.printStackTrace();
fail();
@ -167,7 +168,6 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
STATE.isRunning = false;
return;
}
mListener.onComplete();
STATE.isRunning = false;
}
@ -184,6 +184,7 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
writer.close();
int status = mHttpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(mHttpConn.getInputStream()));
String line;
@ -193,10 +194,9 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
reader.close();
mHttpConn.disconnect();
} else {
ALog.w(TAG, "state_code = " + status);
fail();
ALog.e(TAG, "response msg: " + mHttpConn.getResponseMessage() + ",code: " + status);
// fail();
}
writer.flush();
writer.close();
mOutputStream.close();

@ -34,7 +34,7 @@ import java.util.Map;
class DBConfig {
static Map<String, Class> mapping = new HashMap<>();
static String DB_NAME;
static int VERSION = 22;
static int VERSION = 23;
static {
if (TextUtils.isEmpty(DB_NAME)) {

@ -23,20 +23,19 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull;
import android.support.v4.util.LruCache;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by lyy on 2015/11/2.
@ -204,7 +203,7 @@ final class SqlHelper extends SQLiteOpenHelper {
sql = sql.replace("?", "%s");
Object[] params = new String[expression.length - 1];
for (int i = 0, len = params.length; i < len; i++) {
params[i] = "\"" + expression[i + 1] + "\"";
params[i] = "'" + expression[i + 1] + "'";
}
sql = String.format(sql, params);
print(FIND_DATA, sql);
@ -227,7 +226,7 @@ final class SqlHelper extends SQLiteOpenHelper {
sql = sql.replace("?", "%s");
Object[] params = new String[expression.length - 1];
for (int i = 0, len = params.length; i < len; i++) {
params[i] = "\"" + expression[i + 1] + "\"";
params[i] = "'" + checkValue(expression[i + 1]) + "'";
}
sql = String.format(sql, params);
print(FIND_DATA, sql);
@ -269,7 +268,7 @@ final class SqlHelper extends SQLiteOpenHelper {
sb.append("SELECT rowid, * FROM ").append(CommonUtil.getClassName(clazz)).append(" where ");
int i = 0;
for (Object where : wheres) {
sb.append(where).append("=").append("\"").append(values[i]).append("\"");
sb.append(where).append("=").append("'").append(checkValue(values[i])).append("'");
sb.append(i >= wheres.length - 1 ? "" : " AND ");
i++;
}
@ -281,6 +280,13 @@ final class SqlHelper extends SQLiteOpenHelper {
return data;
}
private static String checkValue(String value) {
if (value.contains("'")) {
return URLEncoder.encode(value);
}
return value;
}
/**
* 查找表的所有数据
*/
@ -319,7 +325,7 @@ final class SqlHelper extends SQLiteOpenHelper {
sql = sql.replace("?", "%s");
Object[] params = new String[expression.length - 1];
for (int i = 0, len = params.length; i < len; i++) {
params[i] = "\"" + expression[i + 1] + "\"";
params[i] = "'" + expression[i + 1] + "'";
}
sql = String.format(sql, params);
SqlHelper.print(DEL_DATA, sql);
@ -362,7 +368,7 @@ final class SqlHelper extends SQLiteOpenHelper {
//sb.append(field.getName()).append("='");
String value;
prams.append(i > 0 ? ", " : "");
prams.append(field.getName()).append("=\"");
prams.append(field.getName()).append("='");
Type type = field.getType();
if (type == Map.class) {
value = SqlUtil.map2Str((Map<String, String>) field.get(dbEntity));
@ -376,13 +382,13 @@ final class SqlHelper extends SQLiteOpenHelper {
value = SqlUtil.getOneToOneParams(field);
} else {
Object obj = field.get(dbEntity);
value = obj == null ? "" : obj.toString();
value = obj == null ? "" : checkValue(obj.toString());
}
//sb.append(value == null ? "" : value);
//sb.append("'");
prams.append(TextUtils.isEmpty(value) ? "" : value);
prams.append("\"");
prams.append("'");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
@ -432,7 +438,7 @@ final class SqlHelper extends SQLiteOpenHelper {
continue;
}
sb.append(i > 0 ? ", " : "");
sb.append("\"");
sb.append("'");
Type type = field.getType();
if (type == Map.class) {
sb.append(SqlUtil.map2Str((Map<String, String>) field.get(dbEntity)));
@ -445,9 +451,9 @@ final class SqlHelper extends SQLiteOpenHelper {
} else if (SqlUtil.isOneToOne(field)) {
sb.append(SqlUtil.getOneToOneParams(field));
} else {
sb.append(field.get(dbEntity));
sb.append(checkValue(field.get(dbEntity).toString()));
}
sb.append("\"");
sb.append("'");
i++;
}
} catch (IllegalAccessException e) {
@ -639,7 +645,7 @@ final class SqlHelper extends SQLiteOpenHelper {
int column = cursor.getColumnIndex(field.getName());
if (column == -1) continue;
if (type == String.class) {
field.set(entity, cursor.getString(column));
field.set(entity, URLDecoder.decode(cursor.getString(column)));
} else if (type == int.class || type == Integer.class) {
field.setInt(entity, cursor.getInt(column));
} else if (type == float.class || type == Float.class) {

@ -74,7 +74,7 @@ public class CheckUtil {
* 检查下载实体
*/
public static void checkDownloadEntity(DownloadEntity entity) {
checkUrl(entity.getUrl());
entity.setUrl(checkUrl(entity.getUrl()));
checkPath(entity.getDownloadPath());
}
@ -88,14 +88,25 @@ public class CheckUtil {
}
/**
* 检测下载链接是否为null
* 检测下载链接是否合法如果地址中path是"//"而不是"/"将会改为"/"
*/
public static void checkUrl(String url) {
public static String checkUrl(String url) {
if (TextUtils.isEmpty(url)) {
throw new IllegalArgumentException("下载链接不能为null");
throw new IllegalArgumentException("url不能为null");
} else if (!url.startsWith("http") && !url.startsWith("ftp")) {
throw new IllegalArgumentException("url错误");
}
int index = url.indexOf("://");
if (index == -1) {
throw new IllegalArgumentException("url不合法");
}
String temp = url.substring(index + 3, url.length());
if (temp.contains("//")) {
temp = url.substring(0, index + 3) + temp.replaceAll("//", "/");
ALog.w(TAG, "url中含有//,//将转换为/,转换后的url为:" + temp);
return temp;
}
return url;
}
/**

@ -103,7 +103,8 @@ public class CommonUtil {
entity.hostName = str;
}
entity.port = m.group(3);
entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : "/" + m.group(4);
//entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : "/" + m.group(4);
entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : m.group(4);
}
return entity;
}

@ -1,5 +1,11 @@
## 开发日志
+ v_3.3.12
+ v_3.3.14
- 修复ftp上传和下载的兼容性问题
- 如果url中的path有"//"将替换为"/"
- 修复http上传成功后,如果服务器没有设置返回码导致上传失败的问题
- 上传实体UploadEntity增加responseStr字段,http上传完成后,在被`@Upload.onComplete`注解的方法中,可通过`task.getEntity().getResponseStr())`获取服务器返回的数据
- 如果服务器存在已上传了一部分的文件,用户执行删除该FTP上传任务,再次重新上传,会出现550,权限错误;本版本已修复该问题
+ v_3.3.13
- 添加`@Download.onWait、@Upload.onWait、@DownloadGroup.onWait`三个新注解,队列已经满了,继续创建新任务,任务处于等待中,将会执行被这三个注解标志的方法
- app被kill,但是还存在等待中的任务A;第二次重新启动,先创建一个新的任务B,Aria会自动把B放进等待队列中,这时再次创建任务A,会导致重复下载,进度错乱的问题;本版本已修复这个问题
+ v_3.3.11

@ -28,8 +28,14 @@ Aria有以下特点:
[![Download](https://api.bintray.com/packages/arialyy/maven/AriaApi/images/download.svg)](https://bintray.com/arialyy/maven/AriaApi/_latestVersion)
[![Download](https://api.bintray.com/packages/arialyy/maven/AriaCompiler/images/download.svg)](https://bintray.com/arialyy/maven/AriaCompiler/_latestVersion)
```java
compile 'com.arialyy.aria:aria-core:3.3.13'
annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.13'
compile 'com.arialyy.aria:aria-core:3.3.14'
annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.14'
```
如果出现android support,请将 `compile 'com.arialyy.aria:aria-core:3.3.13'`替换为
```
compile('com.arialyy.aria:aria-core:<last-version>'){
exclude group: 'com.android.support'
}
```
如果你使用的是kotlin,请使用kotlin官方提供的方法配置apt,[kotlin kapt官方配置传送门](https://www.kotlincn.net/docs/reference/kapt.html)
@ -97,12 +103,11 @@ protected void onCreate(Bundle savedInstanceState) {
### [更多说明,见WIKI](https://github.com/AriaLyy/Aria/wiki)
### 版本日志
+ v_3.3.11
- 添加进度更新间隔api,在`aria_config.xml`配置`<updateInterval value="1000"/>`或在代码中调用
`AriaManager.getInstance(AriaManager.APP).getDownloadConfig().setUpdateInterval(3000)`便可以改变进度刷新间隔
- 修复下载过程中kill进程可能出现的文件错误的问题 https://github.com/AriaLyy/Aria/issues/192
- 修复http上传的空指针问题 https://github.com/AriaLyy/Aria/issues/193
- 修复下载地址中含有`'`导致的崩溃问题 https://github.com/AriaLyy/Aria/issues/194
+ v_3.3.14
- 修复ftp上传和下载的兼容性问题
- 如果url中的path有"//"将替换为"/"
- 修复http上传成功后,如果服务器没有设置返回码导致上传失败的问题
- 上传实体UploadEntity增加responseStr字段,http上传完成后,在被`@Upload.onComplete`注解的方法中,可通过`task.getEntity().getResponseStr())`获取服务器返回的数据
[更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md)

@ -36,10 +36,9 @@ import java.io.File;
*/
public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding> {
//private final String URL = "ftp://192.168.1.9:21/下载/AriaPrj.zip";
//private final String URL = "ftp://192.168.1.9:21/下载/[电影天堂www.dy2018.com]赛车总动员3BD中英双字.mp4";
//private final String URL = "ftp://h:h@tv.dl1234.com:2199/付岩洞复仇者们05.mkv";
private final String URL = "ftp://z:z@dygod18.com:21211/[破晓电影www.poxiao.com]情遇曼哈顿HD国语中字.mkv";
//private final String URL = "ftp://172.18.104.71:21/upload/AS.zip";
//private final String URL = "ftp://182.92.180.213:21/video/572fed5c2ad48_1024.jpg";
private final String URL = "ftp://192.168.1.6:21/download/AriaPrj.zip";
//private final String URL = "ftp://d:d@dygodj8.com:12311/咖啡风暴HD大陆公映意语中字[飘花www.piaohua.com].mp4";
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
@ -61,7 +60,8 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
switch (view.getId()) {
case R.id.start:
Aria.download(this).loadFtp(URL, true).charSet("gbk")
//.login("lao", "123456")
//.login("sxf", "B34VdGsJ")
.login("lao", "123456")
.setDownloadPath("/mnt/sdcard/").start();
break;
case R.id.stop:

@ -27,15 +27,10 @@ import android.widget.RadioGroup;
import android.widget.Toast;
import butterknife.Bind;
import com.arialyy.annotations.Download;
import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTask;
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.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T;
@ -53,17 +48,18 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe";
//"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk";
//"http://sitcac.daxincf.cn/wp-content/uploads/swift_vido/01/element.mp4_1";
//"http://120.25.196.56:8000/filereq?id=15692406294&ipncid=105635&client=android&filename=20170819185541.avi";
//"http://down2.xiaoshuofuwuqi.com/d/file/filetxt/20170608/14/%BA%DA%CE%D7%CA%A6%E1%C8%C6%F0.txt";
//"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815";
//"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";
//"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt";
//"http://down8.androidgame-store.com/201706122321/97967927DD4E53D9905ECAA7874C8128/new/game1/19/45319/com.neuralprisma-2.5.2.174-2000174_1494784835.apk?f=web_1";
//不支持断点的链接
//"http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-";
//"http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/QQ_718.apk";
//"http://qudao.5535.cn/one/game.html?game=531&cpsuser=xiaoeryu2";
"https://bogoe-res.mytbz.com/tbzengsong/If You're Happy.mp3";
//"http://120.25.196.56:8000/filereq?id=15692406294&ipncid=105635&client=android&filename=20170819185541.avi";
//"http://down2.xiaoshuofuwuqi.com/d/file/filetxt/20170608/14/%BA%DA%CE%D7%CA%A6%E1%C8%C6%F0.txt";
//"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815";
//"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";
//"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt";
//"http://down8.androidgame-store.com/201706122321/97967927DD4E53D9905ECAA7874C8128/new/game1/19/45319/com.neuralprisma-2.5.2.174-2000174_1494784835.apk?f=web_1";
//不支持断点的链接
//"http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-";
//"http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/QQ_718.apk";
//"http://qudao.5535.cn/one/game.html?game=531&cpsuser=xiaoeryu2";
"https://bogoe-res.mytbz.com/tbzengsong/If You're Happy.mp3";
//"http://ozr0ucjs5.bkt.clouddn.com/51_box-104_20180131202610.apk";
@Bind(R.id.start) Button mStart;
@Bind(R.id.stop) Button mStop;
@Bind(R.id.cancel) Button mCancel;
@ -122,7 +118,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
return true;
}
@Download.onWait void onWait(DownloadTask task){
@Download.onWait void onWait(DownloadTask task) {
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
}
@ -177,12 +173,12 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
mCancel.setEnabled(false);
setBtState(true);
getBinding().setSpeed("");
L.d(TAG, "path ==> " + task.getDownloadEntity().getDownloadPath());
L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
L.d(TAG, "data ==> " + Aria.download(this).getDownloadEntity(DOWNLOAD_URL));
}
@Download.onNoSupportBreakPoint
public void onNoSupportBreakPoint(DownloadTask task) {
@Download.onNoSupportBreakPoint public void onNoSupportBreakPoint(DownloadTask task) {
T.showShort(SingleTaskActivity.this, "该下载链接不支持断点");
}
@ -221,12 +217,14 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
}
private void startD(){
private void startD() {
//Aria.get(this).setLogLevel(ALog.LOG_CLOSE);
//Aria.download(this).load("aaaa.apk");
Map<String, String> map = new HashMap<>();
map.put("User-Agent", "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 Mobile MQQBrowser/6.2 TBS/043722 Safari/537.36");
map.put("Cookie", "BAIDUID=DFC7EF42C60AD1ACF0BA94389AA67F13:FG=1; H_WISE_SIDS=121192_104493_114745_121434_119046_100098_120212_121140_118882_118858_118850_118820_118792_121254_121534_121214_117588_117242_117431_119974_120597_121043_121422_120943_121175_121272_117552_120482_121013_119962_119145_120851_120841_120034_121325_116407_121109_120654_110085_120708; PSINO=7; BDORZ=AE84CDB3A529C0F8A2B9DCDD1D18B695");
map.put("User-Agent",
"Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 Mobile MQQBrowser/6.2 TBS/043722 Safari/537.36");
map.put("Cookie",
"BAIDUID=DFC7EF42C60AD1ACF0BA94389AA67F13:FG=1; H_WISE_SIDS=121192_104493_114745_121434_119046_100098_120212_121140_118882_118858_118850_118820_118792_121254_121534_121214_117588_117242_117431_119974_120597_121043_121422_120943_121175_121272_117552_120482_121013_119962_119145_120851_120841_120034_121325_116407_121109_120654_110085_120708; PSINO=7; BDORZ=AE84CDB3A529C0F8A2B9DCDD1D18B695");
Aria.download(SingleTaskActivity.this)
.load(DOWNLOAD_URL)
//.addHeader("groupName", "value")
@ -234,12 +232,12 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//.setRequestMode(RequestEnum.POST)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1.apk")
.resetState()
//.start();
.add();
.start();
//.add();
}
@Override protected void onDestroy() {
super.onDestroy();
Aria.download(this).unRegister();
//Aria.download(this).unRegister();
}
}

@ -23,19 +23,20 @@ import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
import java.io.File;
/**
* Created by Aria.Lao on 2017/7/28.
* Ftp 文件上传demo
*/
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private final String FILE_PATH = "/mnt/sdcard/gg.zip";
private final String URL = "ftp://192.168.1.2:21/upload/测试";
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.zip";
private final String URL = "ftp://192.168.1.6:21/aa/你好";
@Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传");
@ -56,7 +57,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.upload(this).loadFtp(FILE_PATH).setUploadUrl(URL).login("lao", "123456").add();
Aria.upload(this).loadFtp(FILE_PATH).setUploadUrl(URL).login("lao", "123456").start();
break;
case R.id.stop:
Aria.upload(this).loadFtp(FILE_PATH).stop();
@ -67,7 +68,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
}
}
@Upload.onWait void onWait(UploadTask task){
@Upload.onWait void onWait(UploadTask task) {
Log.d(TAG, task.getTaskName() + "_wait");
}
@ -76,7 +77,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
Log.d(TAG, "开始上传");
Log.d(TAG, "开始上传,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
}
@Upload.onTaskResume public void taskResume(UploadTask task) {

@ -17,17 +17,18 @@
package com.arialyy.simple.upload;
import android.os.Bundle;
import android.util.Log;
import butterknife.Bind;
import butterknife.OnClick;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
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.widget.HorizontalProgressBarWithNumber;
import java.io.File;
/**
* Created by Aria.Lao on 2017/2/9.
@ -36,7 +37,7 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
private static final String TAG = "HttpUploadActivity";
@Bind(R.id.pb) HorizontalProgressBarWithNumber mPb;
private static final String FILE_PATH = "/mnt/sdcard/gg.zip";
private static final String FILE_PATH = "/mnt/sdcard/test.txt";
@Override protected int setLayoutId() {
return R.layout.activity_upload;
@ -49,10 +50,11 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
}
@OnClick(R.id.upload) void upload() {
Aria.upload(HttpUploadActivity.this)
.load(FILE_PATH)
.setUploadUrl("http://192.168.1.9:8080/upload/")
.setAttachment("serveFile")
Aria.upload(HttpUploadActivity.this).load(FILE_PATH)
//.setUploadUrl(
// "http://lib-test.xzxyun.com:8042/Api/upload?data={\"type\":\"1\",\"fileType\":\".txt\"}")
.setUploadUrl("http://192.168.1.6:8080/upload/sign_file/").setAttachment("file")
//.addHeader("iplanetdirectorypro", "11a09102fb934ad0bc206f9c611d7933")
.start();
}
@ -64,12 +66,11 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
Aria.upload(this).load(FILE_PATH).cancel();
}
@Upload.onPre public void onPre(UploadTask task) {
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
L.d(TAG, "upload start");
L.d(TAG, "upload start,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
getBinding().setFileSize(task.getConvertFileSize());
}
@ -88,10 +89,12 @@ public class HttpUploadActivity extends BaseActivity<ActivityUploadBinding> {
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
getBinding().setSpeed(task.getConvertSpeed());
getBinding().setProgress(task.getPercent());
L.d(TAG, "P => " + task.getPercent());
}
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
L.d(TAG, "上传完成");
L.d(TAG, "上传成功返回数据(如果有的话):" + task.getEntity().getResponseStr());
getBinding().setSpeed("");
getBinding().setProgress(100);
}

@ -39,7 +39,7 @@ task clean(type: Delete) {
ext {
userOrg = 'arialyy'
groupId = 'com.arialyy.aria'
publishVersion = '3.3.13'
publishVersion = '3.3.14'
// publishVersion = '1.0.3' //FTP插件
repoName='maven'
desc = 'android 下载框架'

Loading…
Cancel
Save