重构线程任务模块
This commit is contained in:
@@ -44,9 +44,10 @@
|
||||
<activity android:name=".core.download.KotlinDownloadActivity"/>
|
||||
<activity
|
||||
android:name=".core.FullScreenCodeActivity"
|
||||
android:theme="@style/FullScreen"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/FullScreen"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize"/>
|
||||
<activity android:name=".core.download.m3u8.M3U8DownloadActivity"/>
|
||||
|
||||
<service android:name=".core.download.service_download.DownloadService"/>
|
||||
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
package com.arialyy.simple;
|
||||
|
||||
import android.Manifest;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import com.arialyy.frame.permission.OnPermissionCallback;
|
||||
@@ -35,6 +36,7 @@ import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8DownloadActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMainBinding;
|
||||
import com.arialyy.simple.core.download.DownloadActivity;
|
||||
import com.arialyy.simple.core.download.FtpDownloadActivity;
|
||||
@@ -44,6 +46,7 @@ import com.arialyy.simple.core.upload.FtpUploadActivity;
|
||||
import com.arialyy.simple.core.upload.HttpUploadActivity;
|
||||
import com.arialyy.simple.modlue.CommonModule;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -60,33 +63,53 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
|
||||
getBinding().list.setLayoutManager(new LinearLayoutManager(this));
|
||||
final List<NormalTo> data = getModule(CommonModule.class).getMainData();
|
||||
getBinding().list.setAdapter(
|
||||
new Adapter(this, data));
|
||||
final List<NormalTo> data = new ArrayList<>();
|
||||
final Adapter adapter = new Adapter(this, data);
|
||||
getBinding().list.setAdapter(adapter);
|
||||
getBinding().list.addItemDecoration(
|
||||
new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
|
||||
|
||||
final CommonModule module = ViewModelProviders.of(this).get(CommonModule.class);
|
||||
module.getMainData(this).observe(this, new Observer<List<NormalTo>>() {
|
||||
@Override public void onChanged(@Nullable List<NormalTo> normalTos) {
|
||||
if (normalTos != null) {
|
||||
data.addAll(normalTos);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
|
||||
new RvItemClickSupport.OnItemClickListener() {
|
||||
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
CommonModule module = getModule(CommonModule.class);
|
||||
switch (position) {
|
||||
case 0:
|
||||
module.startNextActivity(data.get(position), DownloadActivity.class);
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
DownloadActivity.class);
|
||||
break;
|
||||
case 1:
|
||||
module.startNextActivity(data.get(position), HttpUploadActivity.class);
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
HttpUploadActivity.class);
|
||||
break;
|
||||
case 2:
|
||||
module.startNextActivity(data.get(position), DownloadGroupActivity.class);
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
DownloadGroupActivity.class);
|
||||
break;
|
||||
case 3:
|
||||
module.startNextActivity(data.get(position), FtpDownloadActivity.class);
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
FtpDownloadActivity.class);
|
||||
break;
|
||||
case 4:
|
||||
module.startNextActivity(data.get(position), FTPDirDownloadActivity.class);
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
FTPDirDownloadActivity.class);
|
||||
break;
|
||||
case 5:
|
||||
module.startNextActivity(data.get(position), FtpUploadActivity.class);
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
FtpUploadActivity.class);
|
||||
break;
|
||||
case 6:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
M3U8DownloadActivity.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package com.arialyy.simple.core.download;
|
||||
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import com.arialyy.simple.MainActivity;
|
||||
@@ -33,11 +33,10 @@ import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.databinding.ActivityDownloadMeanBinding;
|
||||
import com.arialyy.simple.core.download.fragment_download.FragmentActivity;
|
||||
import com.arialyy.simple.core.download.multi_download.MultiTaskActivity;
|
||||
import com.arialyy.simple.core.download.service_download.DownloadService;
|
||||
import com.arialyy.simple.modlue.CommonModule;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -54,25 +53,42 @@ public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding>
|
||||
super.init(savedInstanceState);
|
||||
mTo = getIntent().getParcelableExtra(MainActivity.KEY_MAIN_DATA);
|
||||
setTitle(mTo.title);
|
||||
final List<NormalTo> data = getModule(CommonModule.class).getDownloadData();
|
||||
|
||||
final List<NormalTo> data = new ArrayList<>();
|
||||
getBinding().list.setLayoutManager(new GridLayoutManager(this, 2));
|
||||
getBinding().list.setAdapter(new Adapter(this, data));
|
||||
final Adapter adapter = new Adapter(this, data);
|
||||
getBinding().list.setAdapter(adapter);
|
||||
final CommonModule module = ViewModelProviders.of(this).get(CommonModule.class);
|
||||
|
||||
module.getDownloadData(this).observe(this,
|
||||
new Observer<List<NormalTo>>() {
|
||||
@Override public void onChanged(@Nullable List<NormalTo> normalTos) {
|
||||
if (normalTos != null) {
|
||||
data.addAll(normalTos);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
|
||||
new RvItemClickSupport.OnItemClickListener() {
|
||||
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
CommonModule module = getModule(CommonModule.class);
|
||||
switch (position) {
|
||||
case 0:
|
||||
module.startNextActivity(data.get(position), SingleTaskActivity.class);
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
SingleTaskActivity.class);
|
||||
break;
|
||||
case 1:
|
||||
module.startNextActivity(data.get(position), MultiTaskActivity.class);
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
MultiTaskActivity.class);
|
||||
break;
|
||||
case 2:
|
||||
module.startNextActivity(data.get(position), HighestPriorityActivity.class);
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
HighestPriorityActivity.class);
|
||||
break;
|
||||
case 3:
|
||||
module.startNextActivity(data.get(position), KotlinDownloadActivity.class);
|
||||
module.startNextActivity(DownloadActivity.this, data.get(position),
|
||||
KotlinDownloadActivity.class);
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
@@ -81,41 +97,6 @@ public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding>
|
||||
});
|
||||
}
|
||||
|
||||
//public void onClick(View view) {
|
||||
// switch (view.getId()) {
|
||||
// case R.id.highest_priority:
|
||||
// startActivity(new Intent(this, HighestPriorityActivity.class));
|
||||
// break;
|
||||
// case R.id.service:
|
||||
// startService(new Intent(this, DownloadService.class));
|
||||
// break;
|
||||
// case R.id.single_task:
|
||||
// startActivity(new Intent(this, SingleTaskActivity.class));
|
||||
// break;
|
||||
// case R.id.multi_task:
|
||||
// startActivity(new Intent(this, MultiTaskActivity.class));
|
||||
// break;
|
||||
// case R.id.dialog_task:
|
||||
// DownloadDialog dialog = new DownloadDialog(this);
|
||||
//
|
||||
// dialog.show();
|
||||
// //DownloadDialogFragment dialog = new DownloadDialogFragment(this);
|
||||
// //dialog.show(getSupportFragmentManager(), "dialog");
|
||||
// break;
|
||||
// case R.id.pop_task:
|
||||
// DownloadPopupWindow pop = new DownloadPopupWindow(this);
|
||||
// pop.showAtLocation(mRootView, Gravity.CENTER_VERTICAL, 0, 0);
|
||||
// break;
|
||||
// case R.id.fragment_task:
|
||||
// startActivity(new Intent(this, FragmentActivity.class));
|
||||
// break;
|
||||
// case R.id.notification:
|
||||
// //SimpleNotification notification = new SimpleNotification(this);
|
||||
// //notification.start();
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
private static class Adapter extends AbsRVAdapter<NormalTo, Adapter.Holder> {
|
||||
|
||||
Adapter(Context context, List<NormalTo> data) {
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -201,6 +202,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning");
|
||||
//Log.d(TAG, task.getKey());
|
||||
long len = task.getFileSize();
|
||||
if (len == 0) {
|
||||
@@ -248,13 +250,13 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setProgress(100);
|
||||
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
getBinding().setStateStr(getString(R.string.re_start));
|
||||
getBinding().setSpeed("");
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadTarget;
|
||||
import com.arialyy.aria.core.download.DownloadTask;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.common.ModifyPathDialog;
|
||||
import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivityM3u8Binding;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
|
||||
private String mUrl;
|
||||
private String mFilePath;
|
||||
private M3U8Module mModule;
|
||||
private DownloadTarget mTarget;
|
||||
|
||||
@Override
|
||||
protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle("单任务下载");
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(M3U8Module.class);
|
||||
mModule.getHttpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTarget = Aria.download(M3U8DownloadActivity.this).load(entity.getUrl());
|
||||
if (mTarget.getTaskState() == IEntity.STATE_STOP) {
|
||||
getBinding().setStateStr(getString(R.string.resume));
|
||||
} else if (mTarget.isRunning()) {
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
}
|
||||
|
||||
if (entity.getFileSize() != 0) {
|
||||
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
|
||||
getBinding().setProgress(entity.isComplete() ? 100
|
||||
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
|
||||
}
|
||||
getBinding().setUrl(entity.getUrl());
|
||||
getBinding().setFilePath(entity.getFilePath());
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
}
|
||||
});
|
||||
getBinding().setViewModel(this);
|
||||
}
|
||||
|
||||
public void chooseUrl() {
|
||||
ModifyUrlDialog dialog =
|
||||
new ModifyUrlDialog(this, getString(R.string.modify_url_dialog_title), mUrl);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyUrlDialog");
|
||||
}
|
||||
|
||||
public void chooseFilePath() {
|
||||
ModifyPathDialog dialog =
|
||||
new ModifyPathDialog(this, getString(R.string.modify_file_path), mFilePath);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyPathDialog");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int speed = -1;
|
||||
String msg = "";
|
||||
switch (item.getItemId()) {
|
||||
case R.id.help:
|
||||
msg = "一些小知识点:\n"
|
||||
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
|
||||
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
|
||||
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据";
|
||||
showMsgDialog("tip", msg);
|
||||
break;
|
||||
case R.id.speed_0:
|
||||
speed = 0;
|
||||
break;
|
||||
case R.id.speed_128:
|
||||
speed = 128;
|
||||
break;
|
||||
case R.id.speed_256:
|
||||
speed = 256;
|
||||
break;
|
||||
case R.id.speed_512:
|
||||
speed = 512;
|
||||
break;
|
||||
case R.id.speed_1m:
|
||||
speed = 1024;
|
||||
break;
|
||||
}
|
||||
if (speed > -1) {
|
||||
msg = item.getTitle().toString();
|
||||
Aria.download(this).setMaxSpeed(speed);
|
||||
T.showShort(this, msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
void taskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setFileSize(task.getConvertFileSize());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning");
|
||||
//Log.d(TAG, task.getKey());
|
||||
long len = task.getFileSize();
|
||||
if (len == 0) {
|
||||
getBinding().setProgress(0);
|
||||
} else {
|
||||
getBinding().setProgress(task.getPercent());
|
||||
}
|
||||
getBinding().setSpeed(task.getConvertSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setStateStr(getString(R.string.resume));
|
||||
getBinding().setSpeed("");
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
void taskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setProgress(0);
|
||||
getBinding().setStateStr(getString(R.string.start));
|
||||
getBinding().setSpeed("");
|
||||
Log.d(TAG, "cancel");
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(M3U8DownloadActivity.this, getString(R.string.download_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
getBinding().setStateStr(getString(R.string.start));
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setProgress(100);
|
||||
Toast.makeText(M3U8DownloadActivity.this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
getBinding().setStateStr(getString(R.string.re_start));
|
||||
getBinding().setSpeed("");
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_m3u8;
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
if (mTarget.isRunning()) {
|
||||
Aria.download(this).load(mUrl).stop();
|
||||
} else {
|
||||
startD();
|
||||
}
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.download(this).load(mUrl).cancel(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void startD() {
|
||||
Aria.download(M3U8DownloadActivity.this)
|
||||
.load(mUrl)
|
||||
.useServerFileName(true)
|
||||
.setFilePath(mFilePath, true)
|
||||
.asM3U8()
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
//Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
mModule.uploadUrl(this, String.valueOf(data));
|
||||
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
|
||||
mModule.updateFilePath(this, String.valueOf(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8Module extends BaseViewModule {
|
||||
private final String M3U8_URL_KEY = "M3U8_URL_KEY";
|
||||
private final String M3U8_PATH_KEY = "M3U8_PATH_KEY";
|
||||
|
||||
private final String defUrl = "https://www.gaoya123.cn/2019/1557993797897.m3u8";
|
||||
private final String filePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
+ "/1557993797897.m3u8";
|
||||
|
||||
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
|
||||
private DownloadEntity singDownloadInfo;
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getHttpDownloadInfo(Context context) {
|
||||
String url = AppUtil.getConfigValue(context, M3U8_URL_KEY, defUrl);
|
||||
String filePath = AppUtil.getConfigValue(context, M3U8_PATH_KEY, this.filePath);
|
||||
|
||||
singDownloadInfo = Aria.download(context).getDownloadEntity(url);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
File temp = new File(this.filePath);
|
||||
singDownloadInfo.setDownloadPath(filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, singDownloadInfo.getDownloadPath());
|
||||
AppUtil.setConfigValue(context, M3U8_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件保存路径
|
||||
*
|
||||
* @param filePath 文件保存路径
|
||||
*/
|
||||
void updateFilePath(Context context, String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
ALog.e(TAG, "文件保存路径为空");
|
||||
return;
|
||||
}
|
||||
File temp = new File(filePath);
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
singDownloadInfo.setDownloadPath(filePath);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新url
|
||||
*/
|
||||
void uploadUrl(Context context, String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ALog.e(TAG, "下载地址为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, M3U8_URL_KEY, url);
|
||||
singDownloadInfo.setUrl(url);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
}
|
||||
@@ -15,52 +15,37 @@
|
||||
*/
|
||||
package com.arialyy.simple.modlue;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.frame.module.AbsModule;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.MainActivity;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.to.NormalTo;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用Modle块
|
||||
*/
|
||||
public class CommonModule extends AbsModule {
|
||||
public class CommonModule extends BaseViewModule {
|
||||
|
||||
private int mPosition;
|
||||
private MutableLiveData<List<NormalTo>> mLiveData = new MutableLiveData<>();
|
||||
|
||||
public CommonModule(Context context) {
|
||||
super(context);
|
||||
public CommonModule() {
|
||||
}
|
||||
|
||||
public void startNextActivity(NormalTo to, Class clazz) {
|
||||
Intent intent = new Intent(getContext(), clazz);
|
||||
public void startNextActivity(Context context, NormalTo to, Class clazz) {
|
||||
Intent intent = new Intent(context, clazz);
|
||||
intent.putExtra(MainActivity.KEY_MAIN_DATA, to);
|
||||
getContext().startActivity(intent);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建图表实体
|
||||
*/
|
||||
public Entry createNewEntry(DownloadEntity entity) {
|
||||
long speed = entity.getSpeed() / 1024;
|
||||
boolean isKb = true;
|
||||
if (speed > 1024) {
|
||||
isKb = false;
|
||||
speed /= 1024;
|
||||
}
|
||||
Entry entry = new Entry(mPosition, speed, isKb);
|
||||
mPosition++;
|
||||
return entry;
|
||||
}
|
||||
|
||||
public List<NormalTo> getDownloadData() {
|
||||
public LiveData<List<NormalTo>> getDownloadData(Context context) {
|
||||
List<NormalTo> list = new ArrayList<>();
|
||||
String[] titles = getContext().getResources().getStringArray(R.array.download_items);
|
||||
String[] titles = context.getResources().getStringArray(R.array.download_items);
|
||||
int[] icons = new int[] {
|
||||
R.drawable.ic_http,
|
||||
R.drawable.ic_http_group,
|
||||
@@ -77,20 +62,22 @@ public class CommonModule extends AbsModule {
|
||||
i++;
|
||||
list.add(to);
|
||||
}
|
||||
return list;
|
||||
mLiveData.postValue(list);
|
||||
return mLiveData;
|
||||
}
|
||||
|
||||
public List<NormalTo> getMainData() {
|
||||
public LiveData<List<NormalTo>> getMainData(Context context) {
|
||||
List<NormalTo> list = new ArrayList<>();
|
||||
String[] titles = getContext().getResources().getStringArray(R.array.main_items);
|
||||
String[] descs = getContext().getResources().getStringArray(R.array.main_items_desc);
|
||||
String[] titles = context.getResources().getStringArray(R.array.main_items);
|
||||
String[] descs = context.getResources().getStringArray(R.array.main_items_desc);
|
||||
int[] icons = new int[] {
|
||||
R.drawable.ic_http,
|
||||
R.drawable.ic_http,
|
||||
R.drawable.ic_http_group,
|
||||
R.drawable.ic_ftp,
|
||||
R.drawable.ic_ftp_dir,
|
||||
R.drawable.ic_ftp
|
||||
R.drawable.ic_ftp,
|
||||
R.drawable.ic_ts
|
||||
};
|
||||
int i = 0;
|
||||
for (String title : titles) {
|
||||
@@ -101,6 +88,7 @@ public class CommonModule extends AbsModule {
|
||||
i++;
|
||||
list.add(to);
|
||||
}
|
||||
return list;
|
||||
mLiveData.postValue(list);
|
||||
return mLiveData;
|
||||
}
|
||||
}
|
||||
|
||||
33
app/src/main/res/drawable/ic_ts.xml
Normal file
33
app/src/main/res/drawable/ic_ts.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="1024"
|
||||
android:viewportWidth="1024"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="#F4F4F4"
|
||||
android:pathData="M891.9,307.2v634.88c0,15.87 -12.8,28.16 -28.16,28.67H206.34c-11.78,0 -21.5,-9.22 -22.02,-21.5V90.62c0,-8.7 7.17,-15.87 15.87,-15.87h442.88c0.51,0 1.02,0.51 1.02,1.02s0,0.51 -0.51,0.51c-0.51,0.51 -0.51,1.02 0,1.54l247.81,228.86c0.51,0 0.51,0.51 0.51,0.51z"/>
|
||||
<path
|
||||
android:fillColor="#6200AF"
|
||||
android:pathData="M643.58,291.84L643.58,74.75l248.32,231.94h-233.98c-7.68,0 -14.34,-6.66 -14.34,-14.85zM420.35,366.08L202.24,366.08c-58.37,0 -105.47,-47.1 -105.47,-105.47S143.36,154.62 202.24,154.62h218.11c58.37,0 105.47,47.1 105.47,105.47s-47.1,105.98 -105.47,105.98zM658.43,771.58h-235.52c-21.5,0 -38.4,-17.41 -38.91,-38.4v-178.69c0,-21.5 17.41,-38.4 38.4,-38.4h235.52c21.5,0 38.4,17.41 38.4,38.4v178.69c0,20.99 -16.9,38.4 -37.89,38.4zM422.91,529.41c-13.82,0 -24.58,11.26 -24.58,24.58v178.69c0,13.82 11.26,24.58 24.58,24.58h235.52c13.82,0 24.58,-11.26 24.58,-24.58v-178.69c0,-13.82 -11.26,-24.58 -24.58,-24.58h-235.52z"/>
|
||||
<path
|
||||
android:fillColor="#6200AF"
|
||||
android:pathData="M437.76,771.58c-4.1,0 -7.17,-3.07 -7.17,-7.17L430.59,522.24c0,-4.1 3.07,-7.17 7.17,-7.17s7.17,3.07 7.17,7.17v242.18c0,4.1 -3.07,7.17 -7.17,7.17zM643.07,771.58c-4.1,0 -7.17,-3.07 -7.17,-7.17L635.9,522.24c0,-4.1 3.07,-7.17 7.17,-7.17s7.17,3.07 7.17,7.17v242.18c0,4.1 -3.07,7.17 -7.17,7.17z"/>
|
||||
<path
|
||||
android:fillColor="#6200AF"
|
||||
android:pathData="M437.76,595.97h-46.59c-4.1,0 -7.17,-3.07 -7.17,-7.17s3.07,-7.17 7.17,-7.17h46.59c4.1,0 7.17,3.07 7.17,7.17s-3.58,7.17 -7.17,7.17zM437.76,650.75h-46.59c-4.1,0 -7.17,-3.07 -7.17,-7.17s3.07,-7.17 7.17,-7.17h46.59c4.1,0 7.17,3.07 7.17,7.17s-3.58,7.17 -7.17,7.17zM437.76,712.19h-46.59c-4.1,0 -7.17,-3.07 -7.17,-7.17s3.07,-7.17 7.17,-7.17h46.59c4.1,0 7.17,3.07 7.17,7.17s-3.58,7.17 -7.17,7.17zM689.66,595.97h-46.59c-4.1,0 -7.17,-3.07 -7.17,-7.17s3.07,-7.17 7.17,-7.17h46.59c4.1,0 7.17,3.07 7.17,7.17s-3.07,7.17 -7.17,7.17zM689.66,650.75h-46.59c-4.1,0 -7.17,-3.07 -7.17,-7.17s3.07,-7.17 7.17,-7.17h46.59c4.1,0 7.17,3.07 7.17,7.17s-3.07,7.17 -7.17,7.17zM689.66,712.19h-46.59c-4.1,0 -7.17,-3.07 -7.17,-7.17s3.07,-7.17 7.17,-7.17h46.59c4.1,0 7.17,3.07 7.17,7.17s-3.07,7.17 -7.17,7.17zM509.44,693.25c-1.02,0 -2.56,-0.51 -3.58,-1.02 -2.05,-1.02 -3.58,-3.58 -3.58,-6.14v-86.02c0,-2.56 1.54,-4.61 3.58,-6.14 2.05,-1.02 4.61,-1.02 7.17,0l74.24,43.01c3.58,2.05 4.61,6.14 2.56,9.73 -0.51,1.02 -1.54,2.05 -2.56,2.56l-74.24,43.01c-1.02,1.02 -2.05,1.02 -3.58,1.02zM516.61,612.86v61.44l53.25,-30.72 -53.25,-30.72z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M284.16,301.57h-15.36L261.12,279.55h-33.79L220.16,301.57h-15.36l31.74,-84.99h15.87l31.74,84.99zM257.54,268.29L245.76,233.98c-0.51,-1.54 -1.02,-3.58 -1.02,-5.12 -0.51,1.54 -0.51,3.58 -1.02,5.12l-11.78,33.79h25.6zM360.96,216.06l-30.72,85.5h-15.87l-30.21,-85.5h15.36l20.99,64.51c0.51,2.56 1.02,4.61 1.54,7.17 0.51,-2.56 1.02,-5.12 1.54,-7.17l21.5,-64.51h15.87zM391.68,301.57h-14.34L377.34,216.06h14.34v85.5z"/>
|
||||
<path
|
||||
android:fillColor="#F4F4F4"
|
||||
android:pathData="M891.9,307.2v634.88c0,15.87 -12.8,28.16 -28.16,28.67H206.34c-11.78,0 -21.5,-9.22 -22.02,-21.5V90.62c0,-8.7 7.17,-15.87 15.87,-15.87h442.88c0.51,0 1.02,0.51 1.02,1.02s0,0.51 -0.51,0.51c-0.51,0.51 -0.51,1.02 0,1.54l247.81,228.86c0.51,0 0.51,0.51 0.51,0.51z"/>
|
||||
<path
|
||||
android:fillColor="@color/icon_color"
|
||||
android:pathData="M643.58,291.84V74.75l248.32,231.94h-233.98c-7.68,0 -14.34,-6.66 -14.34,-14.85zM420.35,366.08H202.24c-58.37,0 -105.47,-47.1 -105.47,-105.47S143.36,154.62 202.24,154.62h218.11c58.37,0 105.47,47.1 105.47,105.47s-47.1,105.98 -105.47,105.98z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M308.22,231.94h-24.06v69.63h-19.46V231.94H240.64v-15.87h67.58v15.87zM321.02,297.98v-18.94c3.58,3.07 7.17,5.12 11.26,6.66 4.1,1.54 8.19,2.05 12.29,2.05 2.56,0 4.61,0 6.14,-0.51s3.07,-1.02 4.61,-2.05c1.02,-1.02 2.05,-1.54 2.56,-2.56 0.51,-1.02 1.02,-2.05 1.02,-3.58 0,-1.54 -0.51,-3.07 -1.54,-4.61 -1.02,-1.54 -2.05,-2.56 -4.1,-3.58 -1.54,-1.02 -3.58,-2.05 -5.63,-3.07 -2.05,-1.02 -4.61,-2.05 -7.17,-3.07 -6.66,-2.56 -11.78,-6.14 -14.85,-10.24 -3.07,-4.1 -5.12,-8.7 -5.12,-14.34 0,-4.61 1.02,-8.19 2.56,-11.26 1.54,-3.07 4.1,-5.63 7.17,-7.68s6.66,-3.58 10.75,-4.61 8.19,-1.54 12.8,-1.54c4.61,0 8.19,0.51 11.78,1.02 3.58,0.51 6.66,1.54 9.73,2.56v17.92c-1.54,-1.02 -3.07,-2.05 -4.61,-2.56 -1.54,-0.51 -3.58,-1.54 -5.12,-2.05s-3.58,-1.02 -5.12,-1.02c-1.54,0 -3.58,-0.51 -5.12,-0.51 -2.05,0 -4.1,0 -6.14,0.51l-4.61,1.54c-1.02,0.51 -2.05,1.54 -3.07,2.56 -0.51,1.02 -1.02,2.05 -1.02,3.58 0,1.54 0.51,2.56 1.02,3.58 0.51,1.02 2.05,2.05 3.07,3.07 1.54,1.02 3.07,2.05 5.12,3.07 2.05,1.02 4.1,2.05 6.66,3.07 3.58,1.54 6.66,3.07 9.22,4.61 2.56,1.54 5.12,3.58 7.17,5.63 2.05,2.05 3.58,4.1 4.61,7.17s1.54,5.63 1.54,9.22c0,4.61 -1.02,8.7 -2.56,11.78s-4.1,5.63 -7.17,7.68 -6.66,3.58 -10.75,4.1c-4.1,1.02 -8.19,1.54 -12.8,1.54 -4.61,0 -9.22,-0.51 -13.31,-1.02 -4.61,-1.02 -8.19,-2.56 -11.26,-4.1z"/>
|
||||
<path
|
||||
android:fillColor="@color/icon_color"
|
||||
android:pathData="M504.83,708.61l75.26,-43.01c5.12,-3.58 6.66,-10.75 3.58,-15.87 -1.02,-1.54 -2.05,-2.56 -3.58,-3.58l-75.26,-43.01c-4.61,-2.05 -10.24,0 -12.8,4.61 -0.51,1.54 -1.02,3.07 -1.02,5.12v85.5c-0.51,5.12 3.58,9.73 8.7,10.24 2.05,1.02 3.58,0.51 5.12,0zM660.48,527.36L416.26,527.36c-15.36,0 -28.16,14.34 -28.16,32.26v192.51c0,17.92 12.29,32.26 28.16,32.26L660.48,784.38c15.36,0 28.16,-14.34 28.16,-32.26v-192c0,-17.92 -12.8,-32.77 -28.16,-32.77zM444.42,752.13c0,5.63 -4.1,10.24 -9.22,10.75h-18.43c-5.63,-0.51 -9.73,-5.12 -9.22,-10.75v-20.99c-0.51,-5.63 4.1,-10.24 9.22,-10.75L435.2,720.38c5.63,0.51 9.73,5.12 9.22,10.75v20.99zM444.42,666.62c0.51,5.63 -4.1,10.24 -9.22,10.75h-18.43c-5.63,-0.51 -9.73,-5.12 -9.22,-10.75v-20.99c0,-5.63 4.1,-10.24 9.22,-10.75L435.2,634.88c5.63,0.51 9.73,5.12 9.22,10.75v20.99zM444.42,581.12c0.51,5.63 -4.1,10.24 -9.22,10.75h-18.43c-5.63,-0.51 -9.73,-5.12 -9.22,-10.75v-20.99c-0.51,-5.63 4.1,-10.24 9.22,-10.75L435.2,549.38c5.63,0.51 9.73,5.12 9.22,10.75v20.99zM613.38,762.88L463.36,762.88v-214.02h150.02L613.38,762.88zM669.7,752.13c0,5.63 -3.58,10.24 -9.22,10.75h-18.43c-5.63,-0.51 -9.73,-5.12 -9.22,-10.75v-20.99c-0.51,-5.63 4.1,-10.24 9.22,-10.75h18.43c5.63,0.51 9.73,5.12 9.73,10.75l-0.51,20.99zM669.7,666.62c0.51,5.63 -4.1,10.24 -9.73,10.75h-18.43c-5.63,-0.51 -9.73,-5.12 -9.22,-10.75v-20.99c-0.51,-5.63 4.1,-10.24 9.22,-10.75h18.94c5.63,0.51 9.73,5.12 9.73,10.75l-0.51,20.99zM669.7,581.12c0.51,5.63 -4.1,10.24 -9.73,10.75h-18.43c-5.63,-0.51 -9.73,-5.12 -9.22,-10.75v-20.99c-0.51,-5.63 4.1,-10.24 9.22,-10.75h18.94c5.63,0.51 9.73,5.12 9.73,10.75l-0.51,20.99z"/>
|
||||
</vector>
|
||||
80
app/src/main/res/layout/activity_m3u8.xml
Normal file
80
app/src/main/res/layout/activity_m3u8.xml
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto"
|
||||
>
|
||||
|
||||
<data>
|
||||
<variable
|
||||
name="fileSize"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="speed"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="progress"
|
||||
type="int"
|
||||
/>
|
||||
<variable
|
||||
name="stateStr"
|
||||
type="String"
|
||||
/>
|
||||
|
||||
<variable
|
||||
name="url"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="filePath"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.arialyy.simple.core.download.m3u8.M3U8DownloadActivity"
|
||||
/>
|
||||
</data>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".core.download.SingleTaskActivity"
|
||||
>
|
||||
|
||||
<include layout="@layout/layout_bar"/>
|
||||
|
||||
<com.arialyy.simple.widget.SvgTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
bind:iconClickListener="@{() -> viewModel.chooseUrl()}"
|
||||
bind:svg_text_view_icon="@drawable/ic_modify"
|
||||
bind:text="@{@string/url(url)}"
|
||||
/>
|
||||
|
||||
<com.arialyy.simple.widget.SvgTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
bind:iconClickListener="@{() -> viewModel.chooseFilePath()}"
|
||||
bind:svg_text_view_icon="@drawable/ic_choose_file"
|
||||
bind:text="@{@string/file_path(filePath)}"
|
||||
/>
|
||||
|
||||
<include
|
||||
layout="@layout/layout_content_single"
|
||||
bind:fileSize="@{fileSize}"
|
||||
bind:progress="@{progress}"
|
||||
bind:speed="@{speed}"
|
||||
bind:stateStr="@{stateStr}"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
@@ -35,6 +35,7 @@
|
||||
<item>FTP 下载</item>
|
||||
<item>FTP 文件夹下载</item>
|
||||
<item>FTP 文件上传</item>
|
||||
<item>M3U8 点播文件下载</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="main_items_desc">
|
||||
@@ -44,6 +45,7 @@
|
||||
<item>单文件下载、多文件队列下载</item>
|
||||
<item>下载服务器上的某个FTP文件夹</item>
|
||||
<item>上传单个文件到服务器</item>
|
||||
<item>下载M3U8点播文件</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="download_items">
|
||||
|
||||
Reference in New Issue
Block a user