Merge branch 'v_2.0'
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -37,7 +37,7 @@
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -7,8 +7,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 23
|
||||
versionCode 84
|
||||
versionName "2.3.6"
|
||||
versionCode 85
|
||||
versionName "2.3.7"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
@ -27,17 +27,15 @@ import com.arialyy.aria.util.CheckUtil;
|
||||
* AM 接收器
|
||||
*/
|
||||
public class AMReceiver {
|
||||
String targetName;
|
||||
String targetName;
|
||||
OnSchedulerListener listener;
|
||||
DownloadEntity entity;
|
||||
Object obj;
|
||||
Object obj;
|
||||
|
||||
/**
|
||||
* {@link #load(String)},请使用该方法
|
||||
*/
|
||||
@Deprecated public AMTarget load(DownloadEntity entity) {
|
||||
this.entity = entity;
|
||||
return new AMTarget(this);
|
||||
return new AMTarget(entity, targetName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,14 +43,13 @@ public class AMReceiver {
|
||||
*/
|
||||
public AMTarget load(@NonNull String downloadUrl) {
|
||||
CheckUtil.checkDownloadUrl(downloadUrl);
|
||||
if (entity == null) {
|
||||
entity = DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
|
||||
}
|
||||
DownloadEntity entity =
|
||||
DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
|
||||
if (entity == null) {
|
||||
entity = new DownloadEntity();
|
||||
}
|
||||
entity.setDownloadUrl(downloadUrl);
|
||||
return new AMTarget(this);
|
||||
return new AMTarget(entity, targetName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,10 +29,13 @@ import java.util.List;
|
||||
* https://github.com/AriaLyy/Aria
|
||||
*/
|
||||
public class AMTarget {
|
||||
private AMReceiver mReceiver;
|
||||
//private AMReceiver mReceiver;
|
||||
DownloadEntity entity;
|
||||
String targetName;
|
||||
|
||||
AMTarget(AMReceiver receiver) {
|
||||
this.mReceiver = receiver;
|
||||
AMTarget(DownloadEntity entity, String targetName) {
|
||||
this.entity = entity;
|
||||
this.targetName = targetName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +45,7 @@ public class AMTarget {
|
||||
if (TextUtils.isEmpty(downloadPath)) {
|
||||
throw new IllegalArgumentException("文件保持路径不能为null");
|
||||
}
|
||||
mReceiver.entity.setDownloadPath(downloadPath);
|
||||
entity.setDownloadPath(downloadPath);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -53,7 +56,7 @@ public class AMTarget {
|
||||
if (TextUtils.isEmpty(downloadName)) {
|
||||
throw new IllegalArgumentException("文件名不能为null");
|
||||
}
|
||||
mReceiver.entity.setFileName(downloadName);
|
||||
entity.setFileName(downloadName);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -61,7 +64,7 @@ public class AMTarget {
|
||||
* 获取下载文件大小
|
||||
*/
|
||||
public long getFileSize() {
|
||||
DownloadEntity entity = getDownloadEntity(mReceiver.entity.getDownloadUrl());
|
||||
DownloadEntity entity = getDownloadEntity(this.entity.getDownloadUrl());
|
||||
if (entity == null) {
|
||||
throw new NullPointerException("下载管理器中没有改任务");
|
||||
}
|
||||
@ -72,7 +75,7 @@ public class AMTarget {
|
||||
* 获取当前下载进度,如果下載实体存在,则返回当前进度
|
||||
*/
|
||||
public long getCurrentProgress() {
|
||||
DownloadEntity entity = getDownloadEntity(mReceiver.entity.getDownloadUrl());
|
||||
DownloadEntity entity = getDownloadEntity(this.entity.getDownloadUrl());
|
||||
if (entity == null) {
|
||||
throw new NullPointerException("下载管理器中没有改任务");
|
||||
}
|
||||
@ -89,8 +92,7 @@ public class AMTarget {
|
||||
*/
|
||||
public void add() {
|
||||
DownloadManager.getInstance()
|
||||
.setCmd(
|
||||
CommonUtil.createCmd(mReceiver.targetName, mReceiver.entity, CmdFactory.TASK_CREATE))
|
||||
.setCmd(CommonUtil.createCmd(targetName, entity, CmdFactory.TASK_CREATE))
|
||||
.exe();
|
||||
}
|
||||
|
||||
@ -99,8 +101,8 @@ public class AMTarget {
|
||||
*/
|
||||
public void start() {
|
||||
List<IDownloadCmd> cmds = new ArrayList<>();
|
||||
cmds.add(CommonUtil.createCmd(mReceiver.targetName, mReceiver.entity, CmdFactory.TASK_CREATE));
|
||||
cmds.add(CommonUtil.createCmd(mReceiver.targetName, mReceiver.entity, CmdFactory.TASK_START));
|
||||
cmds.add(CommonUtil.createCmd(targetName, entity, CmdFactory.TASK_CREATE));
|
||||
cmds.add(CommonUtil.createCmd(targetName, entity, CmdFactory.TASK_START));
|
||||
DownloadManager.getInstance().setCmds(cmds).exe();
|
||||
cmds.clear();
|
||||
}
|
||||
@ -110,7 +112,7 @@ public class AMTarget {
|
||||
*/
|
||||
public void stop() {
|
||||
DownloadManager.getInstance()
|
||||
.setCmd(CommonUtil.createCmd(mReceiver.targetName, mReceiver.entity, CmdFactory.TASK_STOP))
|
||||
.setCmd(CommonUtil.createCmd(targetName, entity, CmdFactory.TASK_STOP))
|
||||
.exe();
|
||||
}
|
||||
|
||||
@ -119,7 +121,7 @@ public class AMTarget {
|
||||
*/
|
||||
public void resume() {
|
||||
DownloadManager.getInstance()
|
||||
.setCmd(CommonUtil.createCmd(mReceiver.targetName, mReceiver.entity, CmdFactory.TASK_START))
|
||||
.setCmd(CommonUtil.createCmd(targetName, entity, CmdFactory.TASK_START))
|
||||
.exe();
|
||||
}
|
||||
|
||||
@ -128,8 +130,7 @@ public class AMTarget {
|
||||
*/
|
||||
public void cancel() {
|
||||
DownloadManager.getInstance()
|
||||
.setCmd(
|
||||
CommonUtil.createCmd(mReceiver.targetName, mReceiver.entity, CmdFactory.TASK_CANCEL))
|
||||
.setCmd(CommonUtil.createCmd(targetName, entity, CmdFactory.TASK_CANCEL))
|
||||
.exe();
|
||||
}
|
||||
|
||||
@ -137,7 +138,7 @@ public class AMTarget {
|
||||
* 是否在下载
|
||||
*/
|
||||
public boolean isDownloading() {
|
||||
return DownloadManager.getInstance().getTaskQueue().getTask(mReceiver.entity).isDownloading();
|
||||
return DownloadManager.getInstance().getTaskQueue().getTask(entity).isDownloading();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,9 +24,7 @@ import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.os.Build;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.widget.PopupWindow;
|
||||
import com.arialyy.aria.core.scheduler.OnSchedulerListener;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
@ -51,43 +49,43 @@ import com.arialyy.aria.core.task.Task;
|
||||
/**
|
||||
* 预处理完成
|
||||
*/
|
||||
public static final String ACTION_PRE = "ACTION_PRE";
|
||||
public static final String ACTION_PRE = "ACTION_PRE";
|
||||
/**
|
||||
* 下载开始前事件
|
||||
*/
|
||||
public static final String ACTION_POST_PRE = "ACTION_POST_PRE";
|
||||
public static final String ACTION_POST_PRE = "ACTION_POST_PRE";
|
||||
/**
|
||||
* 开始下载事件
|
||||
*/
|
||||
public static final String ACTION_START = "ACTION_START";
|
||||
public static final String ACTION_START = "ACTION_START";
|
||||
/**
|
||||
* 恢复下载事件
|
||||
*/
|
||||
public static final String ACTION_RESUME = "ACTION_RESUME";
|
||||
public static final String ACTION_RESUME = "ACTION_RESUME";
|
||||
/**
|
||||
* 正在下载事件
|
||||
*/
|
||||
public static final String ACTION_RUNNING = "ACTION_RUNNING";
|
||||
public static final String ACTION_RUNNING = "ACTION_RUNNING";
|
||||
/**
|
||||
* 停止下载事件
|
||||
*/
|
||||
public static final String ACTION_STOP = "ACTION_STOP";
|
||||
public static final String ACTION_STOP = "ACTION_STOP";
|
||||
/**
|
||||
* 取消下载事件
|
||||
*/
|
||||
public static final String ACTION_CANCEL = "ACTION_CANCEL";
|
||||
public static final String ACTION_CANCEL = "ACTION_CANCEL";
|
||||
/**
|
||||
* 下载完成事件
|
||||
*/
|
||||
public static final String ACTION_COMPLETE = "ACTION_COMPLETE";
|
||||
public static final String ACTION_COMPLETE = "ACTION_COMPLETE";
|
||||
/**
|
||||
* 下载失败事件
|
||||
*/
|
||||
public static final String ACTION_FAIL = "ACTION_FAIL";
|
||||
public static final String ACTION_FAIL = "ACTION_FAIL";
|
||||
/**
|
||||
* 下载实体
|
||||
*/
|
||||
public static final String ENTITY = "DOWNLOAD_ENTITY";
|
||||
public static final String ENTITY = "DOWNLOAD_ENTITY";
|
||||
/**
|
||||
* 位置
|
||||
*/
|
||||
@ -95,7 +93,7 @@ import com.arialyy.aria.core.task.Task;
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
public static final String CURRENT_SPEED = "CURRENT_SPEED";
|
||||
public static final String CURRENT_SPEED = "CURRENT_SPEED";
|
||||
|
||||
private Aria() {
|
||||
}
|
||||
@ -118,7 +116,17 @@ import com.arialyy.aria.core.task.Task;
|
||||
/**
|
||||
* 处理Fragment
|
||||
*/
|
||||
private static AMReceiver whit(Fragment fragment) {
|
||||
public static AMReceiver whit(Fragment fragment) {
|
||||
checkNull(fragment);
|
||||
return AriaManager.getInstance(
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? fragment.getContext()
|
||||
: fragment.getActivity()).get(fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Fragment
|
||||
*/
|
||||
public static AMReceiver whit(android.support.v4.app.Fragment fragment) {
|
||||
checkNull(fragment);
|
||||
return AriaManager.getInstance(
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? fragment.getContext()
|
||||
@ -151,10 +159,6 @@ import com.arialyy.aria.core.task.Task;
|
||||
return AriaManager.getInstance(dialog.getContext()).get(dialog);
|
||||
}
|
||||
|
||||
private static void checkNull(Object obj) {
|
||||
if (obj == null) throw new IllegalArgumentException("不能传入空对象");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理通用事件
|
||||
*/
|
||||
@ -185,6 +189,30 @@ import com.arialyy.aria.core.task.Task;
|
||||
return AriaManager.getInstance(popupWindow.getContentView().getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Fragment的通用任务
|
||||
*/
|
||||
public static AriaManager get(Fragment fragment) {
|
||||
checkNull(fragment);
|
||||
return AriaManager.getInstance(
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? fragment.getContext()
|
||||
: fragment.getActivity());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Fragment的通用任务
|
||||
*/
|
||||
public static AriaManager get(android.support.v4.app.Fragment fragment) {
|
||||
checkNull(fragment);
|
||||
return AriaManager.getInstance(
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? fragment.getContext()
|
||||
: fragment.getActivity());
|
||||
}
|
||||
|
||||
private static void checkNull(Object obj) {
|
||||
if (obj == null) throw new IllegalArgumentException("不能传入空对象");
|
||||
}
|
||||
|
||||
public static class SimpleSchedulerListener implements OnSchedulerListener {
|
||||
|
||||
@Override public void onTaskPre(Task task) {
|
||||
|
@ -67,17 +67,24 @@ public class Task {
|
||||
/**
|
||||
* 获取文件大小
|
||||
*/
|
||||
public long getFileSize(){
|
||||
public long getFileSize() {
|
||||
return mEntity.getFileSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前下载进度
|
||||
*/
|
||||
public long getCurrentProgress(){
|
||||
public long getCurrentProgress() {
|
||||
return mEntity.getCurrentProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前下载任务的下载地址
|
||||
*/
|
||||
public String getDownloadUrl() {
|
||||
return mEntity.getDownloadUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始下载
|
||||
*/
|
||||
@ -202,6 +209,7 @@ public class Task {
|
||||
public Task build() {
|
||||
Task task = new Task(context, downloadEntity, outHandler);
|
||||
task.setTargetName(targetName);
|
||||
//Log.w(TAG, "downloadEntity hashcode ==> " + downloadEntity.hashCode());
|
||||
downloadEntity.save();
|
||||
return task;
|
||||
}
|
||||
|
17
README.md
17
README.md
@ -16,7 +16,7 @@
|
||||
## 下载
|
||||
[](https://bintray.com/arialyy/maven/Aria/_latestVersion)</br>
|
||||
```java
|
||||
compile 'com.arialyy.aria:Aria:2.3.6'
|
||||
compile 'com.arialyy.aria:Aria:2.3.8'
|
||||
```
|
||||
|
||||
|
||||
@ -30,7 +30,13 @@ compile 'com.arialyy.aria:Aria:2.3.6'
|
||||
|
||||
***
|
||||
## 使用
|
||||
### 一、只需要以下参数,你便能很简单的使用Aria下载文件了
|
||||
### 一、添加权限
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
```
|
||||
### 二、只需要以下参数,你便能很简单的使用Aria下载文件了
|
||||
```java
|
||||
Aria.whit(this)
|
||||
.load(DOWNLOAD_URL) //下载地址,必填
|
||||
@ -38,14 +44,14 @@ compile 'com.arialyy.aria:Aria:2.3.6'
|
||||
.setDownloadName("test.apk") //文件名,必填
|
||||
.start();
|
||||
```
|
||||
### 二、为了能接收到Aria传递的数据,你需要把你的Activity或fragment注册到Aria管理器中,注册的方式很简单,在onResume
|
||||
### 三、为了能接收到Aria传递的数据,你需要把你的Activity或fragment注册到Aria管理器中,注册的方式很简单,在onResume
|
||||
```java
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
Aria.whit(this).addSchedulerListener(new MySchedulerListener());
|
||||
}
|
||||
```
|
||||
### 三、通过下载链接,你还能使用Aria执行很多操作,如:
|
||||
### 四、通过下载链接,你还能使用Aria执行很多操作,如:
|
||||
- 添加任务(不进行下载)
|
||||
|
||||
```java
|
||||
@ -85,7 +91,7 @@ compile 'com.arialyy.aria:Aria:2.3.6'
|
||||
Aria.whit(this).load(DOWNLOAD_URL).getFileSize();
|
||||
```
|
||||
|
||||
### 四、关于Aria,你还需要知道的一些东西
|
||||
### 五、关于Aria,你还需要知道的一些东西
|
||||
- 设置下载任务数,Aria默认下载任务为**2**
|
||||
|
||||
```java
|
||||
@ -114,6 +120,7 @@ compile 'com.arialyy.aria:Aria:2.3.6'
|
||||
|
||||
***
|
||||
## 开发日志
|
||||
+ v_2.3.8 修复数据错乱的bug、添加fragment支持
|
||||
+ v_2.3.6 添加dialog、popupWindow支持
|
||||
+ v_2.3.3
|
||||
- 添加断点支持
|
||||
|
@ -15,7 +15,7 @@
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<!--android:name=".activity.SingleTaskActivity"-->
|
||||
<activity
|
||||
android:name=".activity.MainActivity"
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
@ -24,8 +24,10 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".activity.SingleTaskActivity"/>
|
||||
<activity android:name=".activity.MultiTaskActivity"/>
|
||||
<activity android:name=".single_task.SingleTaskActivity"/>
|
||||
<activity android:name=".multi_task.MultiTaskActivity"/>
|
||||
<activity android:name=".fragment_task.FragmentActivity"/>
|
||||
<activity android:name=".multi_task.DownloadActivity"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.activity;
|
||||
package com.arialyy.simple;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
@ -28,21 +28,23 @@ import butterknife.Bind;
|
||||
import com.arialyy.frame.permission.OnPermissionCallback;
|
||||
import com.arialyy.frame.permission.PermissionManager;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMainBinding;
|
||||
import com.arialyy.simple.dialog.DownloadDialog;
|
||||
import com.arialyy.simple.pop.DownloadPopupWindow;
|
||||
import com.arialyy.simple.dialog_task.DownloadDialog;
|
||||
import com.arialyy.simple.fragment_task.FragmentActivity;
|
||||
import com.arialyy.simple.multi_task.MultiTaskActivity;
|
||||
import com.arialyy.simple.pop_task.DownloadPopupWindow;
|
||||
import com.arialyy.simple.single_task.SingleTaskActivity;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/10/13.
|
||||
*/
|
||||
public class MainActivity extends BaseActivity<ActivityMainBinding> {
|
||||
@Bind(R.id.toolbar) Toolbar mBar;
|
||||
@Bind(R.id.single_task) Button mSigleBt;
|
||||
@Bind(R.id.multi_task) Button mMultiBt;
|
||||
@Bind(R.id.dialog_task) Button mDialogBt;
|
||||
@Bind(R.id.pop_task) Button mPopBt;
|
||||
@Bind(R.id.toolbar) Toolbar mBar;
|
||||
@Bind(R.id.single_task) Button mSigleBt;
|
||||
@Bind(R.id.multi_task) Button mMultiBt;
|
||||
@Bind(R.id.dialog_task) Button mDialogBt;
|
||||
@Bind(R.id.pop_task) Button mPopBt;
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_main;
|
||||
@ -99,6 +101,9 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
|
||||
//pop.showAsDropDown(mRootView);
|
||||
pop.showAtLocation(mRootView, Gravity.CENTER_VERTICAL, 0, 0);
|
||||
break;
|
||||
case R.id.fragment_task:
|
||||
startActivity(new Intent(this, FragmentActivity.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,179 +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.simple.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import butterknife.Bind;
|
||||
import com.arialyy.aria.core.AMTarget;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.adapter.DownloadAdapter;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMultiBinding;
|
||||
import com.arialyy.simple.dialog.DownloadNumDialog;
|
||||
import com.arialyy.simple.module.DownloadModule;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class MultiTaskActivity extends BaseActivity<ActivityMultiBinding> {
|
||||
@Bind(R.id.list) RecyclerView mList;
|
||||
@Bind(R.id.toolbar) Toolbar mBar;
|
||||
DownloadAdapter mAdapter;
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_multi;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setSupportActionBar(mBar);
|
||||
mBar.setTitle("多任务下载");
|
||||
mAdapter = new DownloadAdapter(this, getModule(DownloadModule.class).getDownloadData());
|
||||
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
//private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
// long len = 0;
|
||||
//
|
||||
// @Override public void onReceive(Context context, Intent intent) {
|
||||
// String action = intent.getAction();
|
||||
// DownloadEntity entity = intent.getParcelableExtra(DownloadManager.ENTITY);
|
||||
// switch (action) {
|
||||
// case DownloadManager.ACTION_PRE:
|
||||
// L.d(TAG, "download pre");
|
||||
// mAdapter.updateState(entity);
|
||||
// break;
|
||||
// case DownloadManager.ACTION_POST_PRE:
|
||||
// len = entity.getFileSize();
|
||||
// L.d(TAG, "download post pre");
|
||||
// break;
|
||||
// case DownloadManager.ACTION_START:
|
||||
// L.d(TAG, "download start");
|
||||
// break;
|
||||
// case DownloadManager.ACTION_RESUME:
|
||||
// L.d(TAG, "download resume");
|
||||
// long location = intent.getLongExtra(DownloadManager.CURRENT_LOCATION, 1);
|
||||
// mAdapter.updateState(entity);
|
||||
// break;
|
||||
// case DownloadManager.ACTION_RUNNING:
|
||||
// long current = intent.getLongExtra(DownloadManager.CURRENT_LOCATION, 0);
|
||||
// long speed = intent.getLongExtra(DownloadManager.CURRENT_SPEED, 0);
|
||||
// //mAdapter.setProgress(entity.getDownloadUrl(), current, speed);
|
||||
// mAdapter.setProgress(entity);
|
||||
// break;
|
||||
// case DownloadManager.ACTION_STOP:
|
||||
// L.d(TAG, "download stop");
|
||||
// mAdapter.updateState(entity);
|
||||
// break;
|
||||
// case DownloadManager.ACTION_COMPLETE:
|
||||
// L.d(TAG, "download complete");
|
||||
// mAdapter.updateState(entity);
|
||||
// break;
|
||||
// case DownloadManager.ACTION_CANCEL:
|
||||
// L.d(TAG, "download cancel");
|
||||
// mAdapter.updateState(entity);
|
||||
// break;
|
||||
// case DownloadManager.ACTION_FAIL:
|
||||
// L.d(TAG, "download fail");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
|
||||
public void onClick(View view){
|
||||
switch (view.getId()){
|
||||
case R.id.num:
|
||||
DownloadNumDialog dialog = new DownloadNumDialog(this);
|
||||
dialog.show(getSupportFragmentManager(), "download_num");
|
||||
break;
|
||||
case R.id.stop_all:
|
||||
Aria.get(this).stopAllTask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
Aria.whit(this).addSchedulerListener(new MySchedulerListener());
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
//unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == DownloadNumDialog.RESULT_CODE){
|
||||
mAdapter.setDownloadNum(Integer.parseInt(data + ""));
|
||||
}
|
||||
}
|
||||
|
||||
private class MySchedulerListener extends Aria.SimpleSchedulerListener{
|
||||
@Override public void onTaskPre(Task task) {
|
||||
super.onTaskPre(task);
|
||||
L.d(TAG, "download pre");
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskStart(Task task) {
|
||||
super.onTaskStart(task);
|
||||
L.d(TAG, "download start");
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskResume(Task task) {
|
||||
super.onTaskResume(task);
|
||||
L.d(TAG, "download resume");
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskRunning(Task task) {
|
||||
super.onTaskRunning(task);
|
||||
mAdapter.setProgress(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskStop(Task task) {
|
||||
super.onTaskStop(task);
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskCancel(Task task) {
|
||||
super.onTaskCancel(task);
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskComplete(Task task) {
|
||||
super.onTaskComplete(task);
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskFail(Task task) {
|
||||
super.onTaskFail(task);
|
||||
L.d(TAG, "download fail");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.arialyy.simple.dialog;
|
||||
package com.arialyy.simple.dialog_task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
@ -0,0 +1,124 @@
|
||||
package com.arialyy.simple.fragment_task;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import butterknife.Bind;
|
||||
import butterknife.OnClick;
|
||||
import com.arialyy.aria.core.AMTarget;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
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.widget.HorizontalProgressBarWithNumber;
|
||||
|
||||
/**
|
||||
* Created by Aria.Lao on 2017/1/4.
|
||||
*/
|
||||
public class DownloadFragment extends AbsFragment<FragmentDownloadBinding> {
|
||||
@Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb;
|
||||
@Bind(R.id.start) Button mStart;
|
||||
@Bind(R.id.stop) Button mStop;
|
||||
@Bind(R.id.cancel) Button mCancel;
|
||||
@Bind(R.id.size) TextView mSize;
|
||||
@Bind(R.id.speed) TextView mSpeed;
|
||||
|
||||
private static final String DOWNLOAD_URL =
|
||||
"http://static.gaoshouyou.com/d/3a/93/573ae1db9493a801c24bf66128b11e39.apk";
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
if (Aria.get(this).taskExists(DOWNLOAD_URL)) {
|
||||
AMTarget target = Aria.whit(this).load(DOWNLOAD_URL);
|
||||
int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize());
|
||||
mPb.setProgress(p);
|
||||
}
|
||||
DownloadEntity entity = Aria.get(this).getDownloadEntity(DOWNLOAD_URL);
|
||||
if (entity != null) {
|
||||
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
|
||||
int state = entity.getState();
|
||||
setBtState(state != DownloadEntity.STATE_DOWNLOAD_ING);
|
||||
} else {
|
||||
setBtState(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onResume() {
|
||||
super.onResume();
|
||||
Aria.whit(this).addSchedulerListener(new DownloadFragment.MyDialogDownloadCallback());
|
||||
}
|
||||
|
||||
@OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
Aria.whit(this)
|
||||
.load(DOWNLOAD_URL)
|
||||
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/daialog.apk")
|
||||
.setDownloadName("daialog.apk")
|
||||
.start();
|
||||
break;
|
||||
case R.id.stop:
|
||||
Aria.whit(this).load(DOWNLOAD_URL).stop();
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.whit(this).load(DOWNLOAD_URL).cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onDelayLoad() {
|
||||
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.fragment_download;
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object obj) {
|
||||
|
||||
}
|
||||
|
||||
private void setBtState(boolean startEnable) {
|
||||
mStart.setEnabled(startEnable);
|
||||
mCancel.setEnabled(!startEnable);
|
||||
mStop.setEnabled(!startEnable);
|
||||
}
|
||||
|
||||
private class MyDialogDownloadCallback extends Aria.SimpleSchedulerListener {
|
||||
|
||||
@Override public void onTaskPre(Task task) {
|
||||
super.onTaskPre(task);
|
||||
mSize.setText(CommonUtil.formatFileSize(task.getFileSize()));
|
||||
setBtState(false);
|
||||
}
|
||||
|
||||
@Override public void onTaskStop(Task task) {
|
||||
super.onTaskStop(task);
|
||||
setBtState(true);
|
||||
mSpeed.setText("0.0kb/s");
|
||||
}
|
||||
|
||||
@Override public void onTaskCancel(Task task) {
|
||||
super.onTaskCancel(task);
|
||||
setBtState(true);
|
||||
mPb.setProgress(0);
|
||||
mSpeed.setText("0.0kb/s");
|
||||
}
|
||||
|
||||
@Override public void onTaskRunning(Task task) {
|
||||
super.onTaskRunning(task);
|
||||
long current = task.getCurrentProgress();
|
||||
long len = task.getFileSize();
|
||||
if (len == 0) {
|
||||
mPb.setProgress(0);
|
||||
} else {
|
||||
mPb.setProgress((int) ((current * 100) / len));
|
||||
}
|
||||
mSpeed.setText(CommonUtil.formatFileSize(task.getSpeed()) + "/s");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.arialyy.simple.fragment_task;
|
||||
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.FragmentDownloadBinding;
|
||||
|
||||
/**
|
||||
* Created by Aria.Lao on 2017/1/4.
|
||||
*/
|
||||
|
||||
public class FragmentActivity extends BaseActivity<FragmentDownloadBinding> {
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_fragment;
|
||||
}
|
||||
}
|
@ -24,24 +24,59 @@ import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.DownloadEntity;
|
||||
import com.arialyy.aria.core.DownloadManager;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.AndroidUtils;
|
||||
import com.arialyy.frame.util.StringUtil;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.activity.SingleTaskActivity;
|
||||
import com.arialyy.simple.multi_task.FileListEntity;
|
||||
import com.arialyy.simple.single_task.SingleTaskActivity;
|
||||
import com.arialyy.simple.base.BaseModule;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class DownloadModule extends BaseModule {
|
||||
private List<String> mTestDownloadUrl = new ArrayList<>();
|
||||
|
||||
public DownloadModule(Context context) {
|
||||
super(context);
|
||||
mTestDownloadUrl.add("http://static.gaoshouyou.com/d/e6/f5/4de6329f9cf5dc3a1d1e6bbcca0d003c.apk");
|
||||
mTestDownloadUrl.add("http://static.gaoshouyou.com/d/6e/e5/ff6ecaaf45e532e6d07747af82357472.apk");
|
||||
mTestDownloadUrl.add("http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk");
|
||||
}
|
||||
|
||||
public String getRadomUrl() {
|
||||
Random random = new Random();
|
||||
int i = random.nextInt(2);
|
||||
return mTestDownloadUrl.get(i);
|
||||
}
|
||||
|
||||
public DownloadEntity createRandomDownloadEntity(){
|
||||
return createDownloadEntity(getRadomUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载地址
|
||||
*/
|
||||
public List<FileListEntity> createFileList() {
|
||||
String[] names = getContext().getResources().getStringArray(R.array.file_nams);
|
||||
String[] downloadUrl = getContext().getResources().getStringArray(R.array.download_url);
|
||||
List<FileListEntity> list = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (String name : names) {
|
||||
FileListEntity entity = new FileListEntity();
|
||||
entity.name = name;
|
||||
entity.downloadUrl = downloadUrl[i];
|
||||
entity.downloadPath = Environment.getExternalStorageDirectory() + "/Download/" + name;
|
||||
list.add(entity);
|
||||
i++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,8 +121,8 @@ public class DownloadModule extends BaseModule {
|
||||
}
|
||||
|
||||
private DownloadEntity createDownloadEntity(String url) {
|
||||
String fileName = CommonUtil.keyToHashCode(url) + ".apk";
|
||||
DownloadEntity entity = new DownloadEntity();
|
||||
String fileName = CommonUtil.keyToHashCode(url) + ".apk";
|
||||
DownloadEntity entity = new DownloadEntity();
|
||||
entity.setDownloadUrl(url);
|
||||
entity.setDownloadPath(getDownloadPath(url));
|
||||
entity.setFileName(fileName);
|
||||
|
@ -0,0 +1,86 @@
|
||||
package com.arialyy.simple.multi_task;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import butterknife.Bind;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityDownloadBinding;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/6.
|
||||
*/
|
||||
|
||||
public class DownloadActivity extends BaseActivity<ActivityDownloadBinding> {
|
||||
@Bind(R.id.list) RecyclerView mList;
|
||||
private DownloadAdapter mAdapter;
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_download;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
mAdapter = new DownloadAdapter(this, Aria.get(this).getDownloadList());
|
||||
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
Aria.whit(this).addSchedulerListener(new MySchedulerListener());
|
||||
}
|
||||
|
||||
private class MySchedulerListener extends Aria.SimpleSchedulerListener {
|
||||
@Override public void onTaskPre(Task task) {
|
||||
super.onTaskPre(task);
|
||||
L.d(TAG, "download pre");
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskStart(Task task) {
|
||||
super.onTaskStart(task);
|
||||
L.d(TAG, "download start");
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskResume(Task task) {
|
||||
super.onTaskResume(task);
|
||||
L.d(TAG, "download resume");
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskRunning(Task task) {
|
||||
super.onTaskRunning(task);
|
||||
mAdapter.setProgress(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskStop(Task task) {
|
||||
super.onTaskStop(task);
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskCancel(Task task) {
|
||||
super.onTaskCancel(task);
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskComplete(Task task) {
|
||||
super.onTaskComplete(task);
|
||||
mAdapter.updateState(task.getDownloadEntity());
|
||||
}
|
||||
|
||||
@Override public void onTaskFail(Task task) {
|
||||
super.onTaskFail(task);
|
||||
L.d(TAG, "download fail");
|
||||
}
|
||||
}
|
||||
}
|
@ -14,12 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package com.arialyy.simple.adapter;
|
||||
package com.arialyy.simple.multi_task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
@ -40,16 +38,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* Created by Lyy on 2016/9/27.
|
||||
* 下载列表适配器
|
||||
*/
|
||||
public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapter.MyHolder> {
|
||||
private static final String TAG = "DownloadAdapter";
|
||||
private Map<String, Integer> mPositions = new ConcurrentHashMap<>();
|
||||
final class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapter.MyHolder> {
|
||||
private static final String TAG = "DownloadAdapter";
|
||||
private Map<String, Integer> mPositions = new ConcurrentHashMap<>();
|
||||
|
||||
public DownloadAdapter(Context context, List<DownloadEntity> data) {
|
||||
DownloadAdapter(Context context, List<DownloadEntity> data) {
|
||||
super(context, data);
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
for (DownloadEntity entity : data) {
|
||||
mPositions.put(entity.getDownloadUrl(), i);
|
||||
Aria.whit(getContext()).load(entity).add();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -73,7 +70,7 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
|
||||
notifyDataSetChanged();
|
||||
} else {
|
||||
int position = indexItem(entity.getDownloadUrl());
|
||||
if (position == -1){
|
||||
if (position == -1) {
|
||||
return;
|
||||
}
|
||||
mData.set(position, entity);
|
||||
@ -82,9 +79,9 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
|
||||
}
|
||||
|
||||
public synchronized void setProgress(DownloadEntity entity) {
|
||||
String url = entity.getDownloadUrl();
|
||||
int position = indexItem(url);
|
||||
if (position == -1){
|
||||
String url = entity.getDownloadUrl();
|
||||
int position = indexItem(url);
|
||||
if (position == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -94,8 +91,8 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
|
||||
|
||||
private synchronized int indexItem(String url) {
|
||||
Set<String> keys = mPositions.keySet();
|
||||
for (String key : keys){
|
||||
if (key.equals(url)){
|
||||
for (String key : keys) {
|
||||
if (key.equals(url)) {
|
||||
return mPositions.get(key);
|
||||
}
|
||||
}
|
||||
@ -103,16 +100,19 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
|
||||
}
|
||||
|
||||
@Override protected void bindData(MyHolder holder, int position, final DownloadEntity item) {
|
||||
long size = item.getFileSize();
|
||||
int current = 0;
|
||||
long size = item.getFileSize();
|
||||
int current = 0;
|
||||
long progress = item.getCurrentProgress();
|
||||
long speed = item.getSpeed();
|
||||
long speed = item.getSpeed();
|
||||
current = size == 0 ? 0 : (int) (progress * 100 / size);
|
||||
holder.progress.setProgress(current);
|
||||
BtClickListener listener = new BtClickListener(item);
|
||||
holder.bt.setOnClickListener(listener);
|
||||
String str = "";
|
||||
int color = android.R.color.holo_green_light;
|
||||
holder.name.setText("文件名:" + item.getFileName());
|
||||
holder.url.setText("下载地址:" + item.getDownloadUrl());
|
||||
holder.path.setText("保持路径:" + item.getDownloadPath());
|
||||
String str = "";
|
||||
int color = android.R.color.holo_green_light;
|
||||
switch (item.getState()) {
|
||||
case DownloadEntity.STATE_WAIT:
|
||||
case DownloadEntity.STATE_OTHER:
|
||||
@ -192,11 +192,14 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
|
||||
}
|
||||
|
||||
class MyHolder extends AbsHolder {
|
||||
@Bind(R.id.progressBar) HorizontalProgressBarWithNumber progress;
|
||||
@Bind(R.id.bt) Button bt;
|
||||
@Bind(R.id.speed) TextView speed;
|
||||
@Bind(R.id.fileSize) TextView fileSize;
|
||||
@Bind(R.id.del) TextView cancel;
|
||||
@Bind(R.id.progressBar) HorizontalProgressBarWithNumber progress;
|
||||
@Bind(R.id.bt) Button bt;
|
||||
@Bind(R.id.speed) TextView speed;
|
||||
@Bind(R.id.fileSize) TextView fileSize;
|
||||
@Bind(R.id.del) TextView cancel;
|
||||
@Bind(R.id.name) TextView name;
|
||||
@Bind(R.id.download_url) TextView url;
|
||||
@Bind(R.id.download_path) TextView path;
|
||||
|
||||
MyHolder(View itemView) {
|
||||
super(itemView);
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.arialyy.simple.dialog;
|
||||
package com.arialyy.simple.multi_task;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
@ -0,0 +1,100 @@
|
||||
package com.arialyy.simple.multi_task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import butterknife.Bind;
|
||||
import com.arialyy.absadapter.common.AbsHolder;
|
||||
import com.arialyy.absadapter.recycler_view.AbsRVAdapter;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.simple.R;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/6.
|
||||
*/
|
||||
final class FileListAdapter extends AbsRVAdapter<FileListEntity, FileListAdapter.FileListHolder> {
|
||||
|
||||
//SparseBooleanArray mBtStates = new SparseBooleanArray();
|
||||
Map<String, Boolean> mBtStates = new ConcurrentHashMap<>();
|
||||
private Map<String, Integer> mPositions = new ConcurrentHashMap<>();
|
||||
|
||||
public FileListAdapter(Context context, List<FileListEntity> data) {
|
||||
super(context, data);
|
||||
for (int i = 0, len = data.size(); i < len; i++) {
|
||||
mBtStates.put(data.get(i).downloadUrl, true);
|
||||
mPositions.put(data.get(i).downloadUrl, i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected FileListHolder getViewHolder(View convertView, int viewType) {
|
||||
return new FileListHolder(convertView);
|
||||
}
|
||||
|
||||
@Override protected int setLayoutId(int type) {
|
||||
return R.layout.item_file_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindData(FileListHolder holder, int position, final FileListEntity item) {
|
||||
holder.name.setText("文件名:" + item.name);
|
||||
holder.url.setText("下载地址:" + item.downloadUrl);
|
||||
holder.path.setText("保存路径:" + item.downloadPath);
|
||||
if (mBtStates.get(item.downloadUrl)) {
|
||||
holder.bt.setEnabled(true);
|
||||
holder.bt.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
Toast.makeText(getContext(), "开始下载:" + item.name, Toast.LENGTH_SHORT).show();
|
||||
Aria.whit(getContext())
|
||||
.load(item.downloadUrl)
|
||||
.setDownloadName(item.name)
|
||||
.setDownloadPath(item.downloadPath)
|
||||
.start();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
holder.bt.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBtState(String downloadUrl, boolean able) {
|
||||
Set<String> keys = mBtStates.keySet();
|
||||
for (String key : keys) {
|
||||
if (key.equals(downloadUrl)) {
|
||||
Log.d(TAG, "able ==> " + able);
|
||||
mBtStates.put(downloadUrl, able);
|
||||
notifyItemChanged(indexItem(downloadUrl));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized int indexItem(String url) {
|
||||
Set<String> keys = mPositions.keySet();
|
||||
for (String key : keys) {
|
||||
if (key.equals(url)) {
|
||||
int index = mPositions.get(key);
|
||||
Log.d(TAG, "index ==> " + index);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
class FileListHolder extends AbsHolder {
|
||||
@Bind(R.id.name) TextView name;
|
||||
@Bind(R.id.download_url) TextView url;
|
||||
@Bind(R.id.download_path) TextView path;
|
||||
@Bind(R.id.bt) Button bt;
|
||||
|
||||
FileListHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.arialyy.simple.multi_task;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/1/6.
|
||||
*/
|
||||
|
||||
public class FileListEntity {
|
||||
public String name, downloadUrl, downloadPath;
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.multi_task;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import butterknife.Bind;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMultiBinding;
|
||||
import com.arialyy.simple.module.DownloadModule;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Lyy on 2016/9/27.
|
||||
*/
|
||||
public class MultiTaskActivity extends BaseActivity<ActivityMultiBinding> {
|
||||
@Bind(R.id.list) RecyclerView mList;
|
||||
@Bind(R.id.toolbar) Toolbar mBar;
|
||||
private FileListAdapter mAdapter;
|
||||
List<FileListEntity> mData = new ArrayList<>();
|
||||
|
||||
@Override protected int setLayoutId() {
|
||||
return R.layout.activity_multi;
|
||||
}
|
||||
|
||||
@Override protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setSupportActionBar(mBar);
|
||||
mBar.setTitle("多任务下载");
|
||||
mData.addAll(getModule(DownloadModule.class).createFileList());
|
||||
mAdapter = new FileListAdapter(this, mData);
|
||||
mList.setLayoutManager(new LinearLayoutManager(this));
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.num:
|
||||
DownloadNumDialog dialog = new DownloadNumDialog(this);
|
||||
dialog.show(getSupportFragmentManager(), "download_num");
|
||||
break;
|
||||
case R.id.stop_all:
|
||||
Aria.get(this).stopAllTask();
|
||||
break;
|
||||
case R.id.turn:
|
||||
startActivity(new Intent(this, DownloadActivity.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
Aria.whit(this).addSchedulerListener(new DownloadListener());
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
//unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == DownloadNumDialog.RESULT_CODE) {
|
||||
Aria.get(this).setMaxDownloadNum(Integer.parseInt(data + ""));
|
||||
}
|
||||
}
|
||||
|
||||
private class DownloadListener extends Aria.SimpleSchedulerListener {
|
||||
|
||||
@Override public void onTaskStart(Task task) {
|
||||
super.onTaskStart(task);
|
||||
mAdapter.updateBtState(task.getDownloadUrl(), false);
|
||||
}
|
||||
|
||||
@Override public void onTaskRunning(Task task) {
|
||||
super.onTaskRunning(task);
|
||||
}
|
||||
|
||||
@Override public void onTaskResume(Task task) {
|
||||
super.onTaskResume(task);
|
||||
mAdapter.updateBtState(task.getDownloadUrl(), false);
|
||||
}
|
||||
|
||||
@Override public void onTaskStop(Task task) {
|
||||
super.onTaskStop(task);
|
||||
mAdapter.updateBtState(task.getDownloadUrl(), true);
|
||||
}
|
||||
|
||||
@Override public void onTaskComplete(Task task) {
|
||||
super.onTaskComplete(task);
|
||||
mAdapter.updateBtState(task.getDownloadUrl(), true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
package com.arialyy.simple.pop;
|
||||
package com.arialyy.simple.pop_task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
@ -15,7 +14,6 @@ import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.DownloadEntity;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.core.AbsDialog;
|
||||
import com.arialyy.frame.core.AbsPopupWindow;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
@ -14,13 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.activity;
|
||||
package com.arialyy.simple.single_task;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
@ -35,15 +33,12 @@ import butterknife.Bind;
|
||||
import com.arialyy.aria.core.AMTarget;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.DownloadEntity;
|
||||
import com.arialyy.aria.core.DownloadManager;
|
||||
import com.arialyy.aria.core.task.Task;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.L;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
import com.arialyy.simple.module.DownloadModule;
|
||||
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
|
||||
|
||||
public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
19
app/src/main/res/layout/activity_download.xml
Normal file
19
app/src/main/res/layout/activity_download.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.example.arial.test.MainActivity"
|
||||
>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
</layout>
|
17
app/src/main/res/layout/activity_fragment.xml
Normal file
17
app/src/main/res/layout/activity_fragment.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<fragment
|
||||
android:id="@+id/fragment1"
|
||||
android:name="com.arialyy.simple.fragment_task.DownloadFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
@ -47,5 +47,14 @@
|
||||
style="?buttonBarButtonStyle"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/fragment_task"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="在Fragment中使用"
|
||||
style="?buttonBarButtonStyle"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
|
@ -15,6 +15,7 @@
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/num"
|
||||
android:layout_below="@+id/toolbar"
|
||||
/>
|
||||
|
||||
@ -40,5 +41,17 @@
|
||||
android:text="停止所有"
|
||||
/>
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/turn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_margin="16dp"
|
||||
android:onClick="onClick"
|
||||
android:text="下载列表"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
</layout>
|
||||
|
@ -6,7 +6,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="com.arialyy.simple.activity.SingleTaskActivity"
|
||||
tools:context="com.arialyy.simple.single_task.SingleTaskActivity"
|
||||
>
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
|
@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:context="com.arialyy.simple.activity.SingleTaskActivity"
|
||||
tools:context="com.arialyy.simple.single_task.SingleTaskActivity"
|
||||
tools:showIn="@layout/activity_single"
|
||||
>
|
||||
|
||||
|
12
app/src/main/res/layout/fragment_download.xml
Normal file
12
app/src/main/res/layout/fragment_download.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<include layout="@layout/dialog_download"/>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
@ -5,54 +5,86 @@
|
||||
android:padding="16dp"
|
||||
>
|
||||
|
||||
<com.arialyy.simple.widget.HorizontalProgressBarWithNumber
|
||||
android:id="@+id/progressBar"
|
||||
<RelativeLayout
|
||||
android:id="@+id/bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_toLeftOf="@+id/bt"
|
||||
android:max="100"
|
||||
>
|
||||
|
||||
<com.arialyy.simple.widget.HorizontalProgressBarWithNumber
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_toLeftOf="@+id/bt"
|
||||
android:max="100"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fileSize"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/progressBar"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="0mb/0mb"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="开始"
|
||||
style="?buttonBarButtonStyle"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/speed"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/fileSize"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:text="0kb/s"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/del"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignRight="@+id/progressBar"
|
||||
android:layout_alignTop="@+id/fileSize"
|
||||
android:text="删除"
|
||||
android:textColor="@color/bt_selector_cancel"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/bar"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="name"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fileSize"
|
||||
android:id="@+id/download_url"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/progressBar"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="0mb/0mb"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="开始"
|
||||
style="?buttonBarButtonStyle"
|
||||
android:layout_below="@+id/name"
|
||||
android:layout_marginTop="10dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/speed"
|
||||
android:id="@+id/download_path"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/fileSize"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:text="0kb/s"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/del"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignRight="@+id/progressBar"
|
||||
android:layout_alignTop="@+id/fileSize"
|
||||
android:text="删除"
|
||||
android:textColor="@color/bt_selector_cancel"
|
||||
android:layout_below="@+id/download_url"
|
||||
android:layout_marginTop="10dp"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
40
app/src/main/res/layout/item_file_list.xml
Normal file
40
app/src/main/res/layout/item_file_list.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="name"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/download_url"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/name"
|
||||
android:layout_marginTop="10dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/download_path"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/download_url"
|
||||
android:layout_marginTop="10dp"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/download_path"
|
||||
android:text="点击下载"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
@ -15,4 +15,21 @@
|
||||
<!--<item>http://static.gaoshouyou.com/d/6e/e5/ff6ecaaf45e532e6d07747af82357472.apk</item>-->
|
||||
<!--<item>http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk</item>-->
|
||||
</string-array>
|
||||
|
||||
<string-array name="file_nams">
|
||||
<item>阴阳师</item>
|
||||
<item>奇迹暖暖</item>
|
||||
<item>幻影纹章</item>
|
||||
<item>史上最坑爹的游戏10</item>
|
||||
<item>鲜果消消乐</item>
|
||||
|
||||
</string-array>
|
||||
<string-array name="download_url">
|
||||
<item>http://g37.gdl.netease.com/onmyoji_netease.apk</item>
|
||||
<item>http://static.gaoshouyou.com/d/eb/f2/dfeba30541f209ab8a50d847fc1661ce.apk</item>
|
||||
<item>http://rs.0.gaoshouyou.com/d/51/46/58514d126c46b8a3f27fc8c7db3b09ec.apk</item>
|
||||
<item>http://rs.0.gaoshouyou.com/d/23/69/07238f952669727878d7a0e180534c8b.apk</item>
|
||||
<item>http://rs.0.gaoshouyou.com/d/e7/3d/73e716d3353de5b479fcf7da8d36a5ef.apk</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 3.4 MiB |
Reference in New Issue
Block a user