优化demo代码,demo添加代码使用示例

v3.6.6
laoyuyu 6 years ago
parent ce43e48097
commit 7b15d4c052
  1. 39
      AppFrame/build.gradle
  2. 8
      AppFrame/proguard-rules.pro
  3. 13
      AppFrame/src/androidTest/java/com/lyy/frame/ApplicationTest.java
  4. 12
      AppFrame/src/main/AndroidManifest.xml
  5. 13
      AppFrame/src/main/java/com/arialyy/frame/base/BaseApp.java
  6. 108
      AppFrame/src/main/java/com/arialyy/frame/base/BaseDialog.java
  7. 19
      AppFrame/src/main/java/com/arialyy/frame/base/BaseFragment.java
  8. 20
      AppFrame/src/main/java/com/arialyy/frame/base/BaseViewModule.java
  9. 52
      AppFrame/src/main/java/com/arialyy/frame/base/StatusBarCompat.java
  10. 28
      AppFrame/src/main/java/com/arialyy/frame/base/net/BasicDeserializer.java
  11. 39
      AppFrame/src/main/java/com/arialyy/frame/base/net/HttpCallback.java
  12. 20
      AppFrame/src/main/java/com/arialyy/frame/base/net/INetResponse.java
  13. 23
      AppFrame/src/main/java/com/arialyy/frame/base/net/JsonCodeAnalysisUtil.java
  14. 112
      AppFrame/src/main/java/com/arialyy/frame/base/net/NetManager.java
  15. 65
      AppFrame/src/main/java/com/arialyy/frame/base/net/OkHttpLogger.java
  16. 219
      AppFrame/src/main/java/com/arialyy/frame/cache/AbsCache.java
  17. 6
      AppFrame/src/main/java/com/arialyy/frame/cache/CacheParam.java
  18. 96
      AppFrame/src/main/java/com/arialyy/frame/cache/CacheUtil.java
  19. 968
      AppFrame/src/main/java/com/arialyy/frame/cache/DiskLruCache.java
  20. 21
      AppFrame/src/main/java/com/arialyy/frame/cache/PathConstaant.java
  21. 9
      AppFrame/src/main/java/com/arialyy/frame/config/CommonConstant.java
  22. 9
      AppFrame/src/main/java/com/arialyy/frame/config/NetConstant.java
  23. 38
      AppFrame/src/main/java/com/arialyy/frame/core/AbsActivity.java
  24. 15
      AppFrame/src/main/java/com/arialyy/frame/core/AbsAlertDialog.java
  25. 3
      AppFrame/src/main/java/com/arialyy/frame/core/AbsDialog.java
  26. 9
      AppFrame/src/main/java/com/arialyy/frame/core/AbsDialogFragment.java
  27. 1
      AppFrame/src/main/java/com/arialyy/frame/core/AbsFragment.java
  28. 55
      AppFrame/src/main/java/com/arialyy/frame/core/AbsFrame.java
  29. 10
      AppFrame/src/main/java/com/arialyy/frame/core/AbsPopupWindow.java
  30. 6
      AppFrame/src/main/java/com/arialyy/frame/core/BindingFactory.java
  31. 12
      AppFrame/src/main/java/com/arialyy/frame/core/CrashHandler.java
  32. 6
      AppFrame/src/main/java/com/arialyy/frame/core/DialogSimpleModule.java
  33. 4
      AppFrame/src/main/java/com/arialyy/frame/core/ModuleFactory.java
  34. 62
      AppFrame/src/main/java/com/arialyy/frame/http/HttpUtil.java
  35. 21
      AppFrame/src/main/java/com/arialyy/frame/module/AbsModule.java
  36. 11
      AppFrame/src/main/java/com/arialyy/frame/module/IOCProxy.java
  37. 3
      AppFrame/src/main/java/com/arialyy/frame/module/ModuleFactory.java
  38. 10
      AppFrame/src/main/java/com/arialyy/frame/permission/PermissionManager.java
  39. 8
      AppFrame/src/main/java/com/arialyy/frame/permission/PermissionUtil.java
  40. 4
      AppFrame/src/main/java/com/arialyy/frame/temp/AbsTempView.java
  41. 18
      AppFrame/src/main/java/com/arialyy/frame/temp/TempView.java
  42. 4
      AppFrame/src/main/java/com/arialyy/frame/util/AESEncryption.java
  43. 86
      AppFrame/src/main/java/com/arialyy/frame/util/AndroidUtils.java
  44. 6
      AppFrame/src/main/java/com/arialyy/frame/util/AppUtils.java
  45. 10
      AppFrame/src/main/java/com/arialyy/frame/util/DensityUtils.java
  46. 9
      AppFrame/src/main/java/com/arialyy/frame/util/DrawableUtil.java
  47. 29
      AppFrame/src/main/java/com/arialyy/frame/util/FileUtil.java
  48. 11
      AppFrame/src/main/java/com/arialyy/frame/util/KeyBoardUtils.java
  49. 83
      AppFrame/src/main/java/com/arialyy/frame/util/MediaUtil.java
  50. 7
      AppFrame/src/main/java/com/arialyy/frame/util/NetUtils.java
  51. 5
      AppFrame/src/main/java/com/arialyy/frame/util/RegularExpression.java
  52. 36
      AppFrame/src/main/java/com/arialyy/frame/util/ScreenUtil.java
  53. 3
      AppFrame/src/main/java/com/arialyy/frame/util/ShellUtils.java
  54. 2
      AppFrame/src/main/java/com/arialyy/frame/util/StringUtil.java
  55. 26
      AppFrame/src/main/java/com/arialyy/frame/util/show/FL.java
  56. 68
      AppFrame/src/main/java/com/arialyy/frame/util/show/L.java
  57. 24
      AppFrame/src/main/java/com/arialyy/frame/util/show/T.java
  58. 24
      AppFrame/src/main/res/drawable/selector_green_bt.xml
  59. 4
      AppFrame/src/main/res/layout/layout_error_temp.xml
  60. 6
      AppFrame/src/main/res/values/color.xml
  61. 2
      AppFrame/src/main/res/values/strings.xml
  62. 22
      AppFrame/src/main/res/values/style.xml
  63. 8
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
  64. 8
      AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
  65. 2
      README.md
  66. 5
      app/build.gradle
  67. 5
      app/src/main/AndroidManifest.xml
  68. 90
      app/src/main/assets/help_code/FtpDownload.java
  69. 127
      app/src/main/assets/help_code/FtpUpload.java
  70. 119
      app/src/main/assets/help_code/HttpDownload.java
  71. 170
      app/src/main/assets/help_code/KotlinHttpDownload.kt
  72. 8
      app/src/main/java/com/arialyy/simple/base/BaseActivity.java
  73. 13
      app/src/main/java/com/arialyy/simple/base/BaseApplication.java
  74. 58
      app/src/main/java/com/arialyy/simple/common/DialogModule.java
  75. 177
      app/src/main/java/com/arialyy/simple/common/DirChooseDialog.java
  76. 93
      app/src/main/java/com/arialyy/simple/common/ModifyPathDialog.java
  77. 4
      app/src/main/java/com/arialyy/simple/common/ModifyUrlDialog.java
  78. 68
      app/src/main/java/com/arialyy/simple/core/FullScreenCodeActivity.java
  79. 95
      app/src/main/java/com/arialyy/simple/core/download/DownloadModule1.java
  80. 311
      app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt
  81. 220
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  82. 55
      app/src/main/java/com/arialyy/simple/core/test/TestFTPActivity.java
  83. 80
      app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
  84. 74
      app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java
  85. 106
      app/src/main/java/com/arialyy/simple/util/AppUtil.java
  86. 76
      app/src/main/java/com/arialyy/simple/widget/CodeView.java
  87. 5
      app/src/main/java/com/arialyy/simple/widget/SvgTextView.java
  88. 19
      app/src/main/res/drawable/ic_choose_file.xml
  89. 6
      app/src/main/res/drawable/ic_dir.xml
  90. 4
      app/src/main/res/drawable/ic_full_screen.xml
  91. 2
      app/src/main/res/drawable/ic_modify.xml
  92. 8
      app/src/main/res/layout/activity_ftp_upload.xml
  93. 17
      app/src/main/res/layout/activity_full_screen_code.xml
  94. 61
      app/src/main/res/layout/activity_single.xml
  95. 86
      app/src/main/res/layout/activity_single_kotlin.xml
  96. 81
      app/src/main/res/layout/dialog_choose_dir.xml
  97. 120
      app/src/main/res/layout/dialog_modify_path.xml
  98. 3
      app/src/main/res/layout/dialog_modify_url.xml
  99. 31
      app/src/main/res/layout/item_choose_dir.xml
  100. 44
      app/src/main/res/layout/layout_code_demo.xml
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,5 +1,5 @@
apply plugin: 'com.android.library'
//apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
@ -7,8 +7,10 @@ android {
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 61
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
@ -22,18 +24,25 @@ android {
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
testImplementation 'junit:junit:4.12'
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation 'com.google.code.gson:gson:2.7'
// compile 'com.squareup.retrofit2:retrofit:2.1.0'
// compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
// compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
api "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
api 'com.google.code.gson:gson:2.8.2'
api 'io.reactivex:rxandroid:1.2.0'
api 'io.reactivex:rxjava:1.1.5'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'
// compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
// compile 'com.google.dagger:dagger:2.5'
// apt 'com.google.dagger:dagger-compiler:2.5'
// provided 'javax.annotation:jsr250-api:1.0'
}
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.2.0'
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
implementation 'com.android.support:multidex:1.0.3'
//apply from: 'jcenter.gradle'
api "android.arch.lifecycle:runtime:${rootProject.ext.lifecycleVersion}"
api "android.arch.lifecycle:extensions:${rootProject.ext.lifecycleVersion}"
annotationProcessor "android.arch.lifecycle:compiler:${rootProject.ext.lifecycleVersion}"
}

@ -15,3 +15,11 @@
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,13 @@
package com.lyy.frame;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

@ -1,14 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lyy.frame">
package="com.lyy.frame">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
</application>
</application>
</manifest>

@ -0,0 +1,13 @@
package com.arialyy.frame.base;
import android.app.Application;
import android.content.Context;
/**
* Created by AriaL on 2017/11/26.
*/
public class BaseApp {
public static Context context;
public static Application app;
}

@ -0,0 +1,108 @@
package com.arialyy.frame.base;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.IntEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Dialog;
import android.databinding.ViewDataBinding;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.BounceInterpolator;
import com.arialyy.frame.core.AbsDialogFragment;
import com.arialyy.frame.util.AndroidUtils;
/**
* Created by Aria.Lao on 2017/12/4.
*/
public abstract class BaseDialog<VB extends ViewDataBinding> extends AbsDialogFragment<VB> {
private WindowManager.LayoutParams mWpm;
private Window mWindow;
protected boolean useDefaultAnim = true;
@Override protected void init(Bundle savedInstanceState) {
mWindow = getDialog().getWindow();
if (mWindow != null) {
mWpm = mWindow.getAttributes();
}
if (mWpm != null && mWindow != null) {
//mView = mWindow.getDecorView();
mRootView.setBackgroundColor(Color.WHITE);
mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//in();
if (useDefaultAnim) {
in1();
}
}
}
@Override public void dismiss() {
if (mWpm != null && mWindow != null) {
if (useDefaultAnim) {
out();
}
} else {
super.dismiss();
}
}
@Override protected void dataCallback(int result, Object data) {
}
/**
* 进场动画
*/
private void in() {
int height = AndroidUtils.getScreenParams(getContext())[1];
ValueAnimator animator = ValueAnimator.ofObject(new IntEvaluator(), -height / 2, 0);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
mWpm.y = (int) animation.getAnimatedValue();
mWindow.setAttributes(mWpm);
}
});
animator.setInterpolator(new BounceInterpolator()); //弹跳
Animator alpha = ObjectAnimator.ofFloat(mRootView, "alpha", 0f, 1f);
AnimatorSet set = new AnimatorSet();
set.play(animator).with(alpha);
set.setDuration(2000).start();
}
private void in1() {
Animator alpha = ObjectAnimator.ofFloat(mRootView, "alpha", 0f, 1f);
alpha.setDuration(800);
alpha.start();
}
/**
* 重力动画
*/
private void out() {
int height = AndroidUtils.getScreenParams(getContext())[1];
ValueAnimator animator = ValueAnimator.ofObject(new IntEvaluator(), 0, height / 3);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
mWpm.y = (int) animation.getAnimatedValue();
mWindow.setAttributes(mWpm);
}
});
Animator alpha = ObjectAnimator.ofFloat(mRootView, "alpha", 1f, 0f);
AnimatorSet set = new AnimatorSet();
set.play(animator).with(alpha);
set.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
BaseDialog.super.dismiss();
}
});
set.setDuration(600).start();
}
}

@ -0,0 +1,19 @@
package com.arialyy.frame.base;
import android.databinding.ViewDataBinding;
import com.arialyy.frame.core.AbsFragment;
/**
* Created by Aria.Lao on 2017/12/1.
*/
public abstract class BaseFragment<VB extends ViewDataBinding> extends AbsFragment<VB> {
public int color;
@Override protected void dataCallback(int result, Object obj) {
}
@Override protected void onDelayLoad() {
}
}

@ -0,0 +1,20 @@
package com.arialyy.frame.base;
import android.arch.lifecycle.ViewModel;
import com.arialyy.frame.base.net.NetManager;
import com.arialyy.frame.util.StringUtil;
/**
* Created by AriaL on 2017/11/26.
* ViewModule只能是public
*/
public class BaseViewModule extends ViewModel {
protected NetManager mNetManager;
protected String TAG = "";
public BaseViewModule() {
mNetManager = NetManager.getInstance();
TAG = StringUtil.getClassName(this);
}
}

@ -0,0 +1,52 @@
package com.arialyy.frame.base;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
public class StatusBarCompat {
private static final int INVALID_VAL = -1;
private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void compat(Activity activity, int statusColor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (statusColor != INVALID_VAL) {
activity.getWindow().setStatusBarColor(statusColor);
}
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
int color = COLOR_DEFAULT;
ViewGroup contentView = activity.findViewById(android.R.id.content);
if (statusColor != INVALID_VAL) {
color = statusColor;
}
View statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(activity));
statusBarView.setBackgroundColor(color);
contentView.addView(statusBarView, lp);
}
}
public static void compat(Activity activity) {
compat(activity, INVALID_VAL);
}
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}

@ -0,0 +1,28 @@
package com.arialyy.frame.base.net;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
/**
* 自定义Gson描述
* Created by Aria.Lao on 2016/10/26.
*
* @param <T> 服务器数据实体
*/
public class BasicDeserializer<T> implements JsonDeserializer<T> {
@Override
public T deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject root = element.getAsJsonObject();
if (JsonCodeAnalysisUtil.isSuccess(root)) {
return new Gson().fromJson(root.get("object"), typeOfT);
} else {
throw new IllegalStateException(root.get("rltmsg").getAsString());
}
}
}

@ -0,0 +1,39 @@
package com.arialyy.frame.base.net;
import com.arialyy.frame.util.show.FL;
import com.arialyy.frame.util.show.L;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
/**
* Created by Aria.Lao on 2016/10/26.
* HTTP数据回调
*/
public abstract class HttpCallback<T> implements INetResponse<T>, Observable.Transformer<T, T> {
@Override public void onFailure(Throwable e) {
L.e("HttpCallback", FL.getExceptionString(e));
}
@Override public Observable<T> call(Observable<T> observable) {
Observable<T> tObservable = observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Func1<T, T>() {
@Override public T call(T t) {
onResponse(t);
return t;
}
})
.onErrorReturn(new Func1<Throwable, T>() {
@Override public T call(Throwable throwable) {
onFailure(throwable);
return null;
}
});
tObservable.subscribe();
return tObservable;
}
}

@ -0,0 +1,20 @@
package com.arialyy.frame.base.net;
/**
* Created by Aria.Lao on 2016/10/25.
* 网络响应接口所有的网络回调都要继承该接口
*
* @param <T> 数据实体结构
*/
public interface INetResponse<T> {
/**
* 网络请求成功
*/
public void onResponse(T response);
/**
* 请求失败
*/
public void onFailure(Throwable e);
}

@ -0,0 +1,23 @@
package com.arialyy.frame.base.net;
import com.google.gson.JsonObject;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by AriaL on 2017/11/26.
*/
public class JsonCodeAnalysisUtil {
public static boolean isSuccess(JsonObject obj) {
JSONObject object = null;
try {
object = new JSONObject(obj.toString());
return object.optBoolean("success");
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
}

@ -0,0 +1,112 @@
package com.arialyy.frame.base.net;
import android.util.SparseArray;
import com.arialyy.frame.base.BaseApp;
import com.arialyy.frame.config.CommonConstant;
import com.arialyy.frame.config.NetConstant;
import com.franmontiel.persistentcookiejar.ClearableCookieJar;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.google.gson.Gson;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Aria.Lao on 2016/10/25.
* 网络管理器
*/
public class NetManager {
private static final Object LOCK = new Object();
private static volatile NetManager INSTANCE = null;
private static final long TIME_OUT = 8 * 1000;
private Retrofit mRetrofit;
private Retrofit.Builder mBuilder;
private SparseArray<GsonConverterFactory> mConverterFactorys = new SparseArray<>();
private ClearableCookieJar mCookieJar;
private NetManager() {
init();
}
public static NetManager getInstance() {
if (INSTANCE == null) {
synchronized (LOCK) {
INSTANCE = new NetManager();
}
}
return INSTANCE;
}
OkHttpClient okHttpClient;
private void init() {
mCookieJar = new PersistentCookieJar(new SetCookieCache(),
new SharedPrefsCookiePersistor(BaseApp.context));
//OkHttpClient okHttpClient = provideOkHttpClient();
okHttpClient = provideOkHttpClient();
}
public ClearableCookieJar getCookieJar() {
return mCookieJar;
}
/**
* 执行网络请求
*
* @param service 服务器返回的实体类型
* @param gson gson 为传入的数据解析器ENTITY 网络实体
* <pre><code>
* Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken<ENTITY>() {
* }.getType(), new BasicDeserializer<ENTITY>()).create();
*
* //如启动图,需要将‘ENTITY’替换为启动图实体‘LauncherImgEntity’
* Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken<LauncherImgEntity>() {
* }.getType(), new BasicDeserializer<LauncherImgEntity>()).create();
*
* </code></pre>
*/
public <SERVICE> SERVICE request(Class<SERVICE> service, Gson gson) {
GsonConverterFactory f = null;
if (gson == null) {
f = GsonConverterFactory.create();
} else {
f = GsonConverterFactory.create(gson);
}
;
final Retrofit.Builder builder = new Retrofit.Builder().client(okHttpClient)
.baseUrl(NetConstant.BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create());
builder.addConverterFactory(f);
return builder.build().create(service);
}
/**
* 创建OKHTTP
*/
private OkHttpClient provideOkHttpClient() {
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (CommonConstant.DEBUG) {
//HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
//logging.setLevel(HttpLoggingInterceptor.Level.BODY);
//builder.addInterceptor(logging);
builder.addInterceptor(new OkHttpLogger());
}
builder.connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
.readTimeout(TIME_OUT, TimeUnit.MILLISECONDS);
builder.cookieJar(mCookieJar);
//builder.addInterceptor(chain -> {
// //String cookies = CookieUtil.getCookies();
// Request request = chain.request().newBuilder()
// //.addHeader("Content-Type", "application/x-www-form-urlencoded")
// //.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
// //.addHeader("Cookie", cookies)
// .build();
// return chain.proceed(request);
//});
return builder.build();
}
}

@ -0,0 +1,65 @@
package com.arialyy.frame.base.net;
import com.arialyy.frame.util.show.FL;
import com.arialyy.frame.util.show.L;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
/**
* Created by Lyy on 2016/9/19.
* 自定义的 OKHTTP 日志
*/
public class OkHttpLogger implements Interceptor {
final static String TAG = "OKHTTP";
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long startNs = System.nanoTime();
Response response = chain.proceed(request);
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
ResponseBody responseBody = response.body();
long contentLength = responseBody.contentLength();
String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
L.d(TAG, "<-- "
+ response.code()
+ ' '
+ response.message()
+ ' '
+ response.request().url()
+ " ("
+ tookMs
+ "ms"
+ (", " + bodySize + " body")
+ ')');
//Headers headers = response.headers();
//for (int i = 0, count = headers.size(); i < count; i++) {
// FL.d(TAG, headers.name(i) + ": " + headers.value(i));
//}
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset UTF8 = Charset.forName("UTF-8");
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
if (contentLength != 0) {
//FL.j(TAG, buffer.clone().readString(charset));
L.j(buffer.clone().readString(charset));
}
L.d(TAG, "<-- END HTTP (" + buffer.size() + "-byte body)");
return response;
}
}

@ -4,25 +4,26 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.util.LruCache;
import android.text.TextUtils;
import com.arialyy.frame.cache.diskcache.DiskLruCache;
import com.arialyy.frame.util.AndroidUtils;
import com.arialyy.frame.util.AppUtils;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.StreamUtil;
import com.arialyy.frame.util.StringUtil;
import com.arialyy.frame.util.show.FL;
import com.arialyy.frame.util.show.L;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by AriaLyy@outlook.com on 2015/4/9.
* Created by Lyy on 2015/4/9.
* 缓存抽象类封装了缓存的读写操作
*/
abstract class AbsCache implements CacheParam {
public abstract class AbsCache implements CacheParam {
private static final String TAG = "AbsCache";
private static final Object LOCK = new Object();
/**
* 磁盘缓存工具
*/
@ -35,34 +36,30 @@ abstract class AbsCache implements CacheParam {
* 是否使用内存缓存
*/
private boolean useMemory = false;
/**
* 是否使用磁盘缓存
*/
private boolean useDisk = false;
/**
* 最大的内存
*/
private int mMaxMemoryCacheSize;
/**
* 最大的磁盘大小
*/
private long mMaxDiskCacheSize;
private int mMaxMemory;
private Context mContext;
private static final Object mDiskCacheLock = new Object();
/**
* 默认使用默认路径
*
* @param useMemory 是否使用内存缓存
*/
protected AbsCache(Context context) {
this(context, DEFAULT_DIR);
protected AbsCache(Context context, boolean useMemory) {
this.mContext = context;
this.useMemory = useMemory;
init(DEFAULT_DIR, 1, SMALL_DISK_CACHE_CAPACITY);
}
/**
* 指定缓存文件夹
*
* @param useMemory 是否使用内存缓存
* @param cacheDir 缓存文件夹
*/
AbsCache(Context context, @NonNull String cacheDir) {
protected AbsCache(Context context, boolean useMemory, @NonNull String cacheDir) {
this.mContext = context;
this.useMemory = useMemory;
init(cacheDir, 1, SMALL_DISK_CACHE_CAPACITY);
}
@ -74,7 +71,7 @@ abstract class AbsCache implements CacheParam {
/**
* 初始化磁盘缓存
*/
private void initDiskCache(String cacheDir, int valueCount, long cacheSize) {
protected void initDiskCache(String cacheDir, int valueCount, long cacheSize) {
try {
File dir = getDiskCacheDir(mContext, cacheDir);
if (!dir.exists()) {
@ -90,35 +87,29 @@ abstract class AbsCache implements CacheParam {
/**
* 初始化内存缓存
*/
private void initMemoryCache() {
if (!useMemory) return;
protected void initMemoryCache() {
if (!useMemory) {
return;
}
// 获取应用程序最大可用内存
mMaxMemoryCacheSize = (int) Runtime.getRuntime().maxMemory();
mMaxMemory = (int) Runtime.getRuntime().maxMemory();
// 设置图片缓存大小为程序最大可用内存的1/8
mMemoryCache = new LruCache<>(mMaxMemoryCacheSize / 8);
mMemoryCache = new LruCache<>(mMaxMemory / 8);
}
/**
* 是否使用内存缓存
*/
void setUseMemory(boolean useMemory) {
protected void setUseMemory(boolean useMemory) {
this.useMemory = useMemory;
}
/**
* 是否使用磁盘缓存
*/
void setUseDisk(boolean useDisk) {
this.useDisk = useDisk;
initMemoryCache();
}
/**
* 设置内存缓存大小
*/
void setMemoryCacheSize(int size) {
if (useMemory && mMemoryCache != null) {
mMemoryCache.resize(size);
}
protected void setMemoryCache(int size) {
mMemoryCache.resize(size);
}
/**
@ -129,8 +120,8 @@ abstract class AbsCache implements CacheParam {
* @param cacheSize 缓存大小
* @see CacheParam
*/
void openDiskCache(@NonNull String cacheDir, int valueCount, long cacheSize) {
synchronized (LOCK) {
protected void openDiskCache(@NonNull String cacheDir, int valueCount, long cacheSize) {
synchronized (mDiskCacheLock) {
if (mDiskLruCache != null && mDiskLruCache.isClosed()) {
try {
File dir = getDiskCacheDir(mContext, cacheDir);
@ -152,41 +143,35 @@ abstract class AbsCache implements CacheParam {
* @param key 缓存的key,通过该key来读写缓存一般是URL
* @param data 缓存的数据
*/
void writeDiskCache(@NonNull String key, @NonNull byte[] data) {
protected void writeDiskCache(@NonNull String key, @NonNull byte[] data) {
if (TextUtils.isEmpty(key)) {
L.e(TAG, "key 不能为null");
return;
}
String hashKey = StringUtil.keyToHashKey(key);
if (useMemory && mMemoryCache != null) {
mMemoryCache.put(hashKey, data);
}
if (useDisk) {
synchronized (LOCK) {
if (mDiskLruCache != null) {
L.i(TAG, "缓存数据到磁盘[key:" + key + ",hashKey:" + hashKey + "]");
OutputStream out = null;
try {
DiskLruCache.Editor editor = mDiskLruCache.edit(hashKey);
out = editor.newOutputStream(DISK_CACHE_INDEX);
out.write(data, 0, data.length);
editor.commit();
out.flush();
out.close();
} catch (IOException e) {
FL.e(this, "writeDiskFailed[key:"
+ key
+ ",hashKey:"
+ hashKey
+ "]\n"
+ FL.getExceptionString(e));
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
synchronized (mDiskCacheLock) {
if (mDiskLruCache != null) {
L.i(TAG, "缓存数据到磁盘[key:" + key + ",hashKey:" + hashKey + "]");
OutputStream out = null;
try {
DiskLruCache.Editor editor = mDiskLruCache.edit(hashKey);
out = editor.newOutputStream(DISK_CACHE_INDEX);
out.write(data, 0, data.length);
editor.commit();
out.flush();
out.close();
} catch (IOException e) {
FL.e(this,
"writeDiskFailed[key:" + key + ",hashKey:" + hashKey + "]\n" + FL.getExceptionString(
e));
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@ -200,7 +185,7 @@ abstract class AbsCache implements CacheParam {
* @param key 缓存的key一般是原来的url
* @return 缓存数据
*/
byte[] readDiskCache(@NonNull String key) {
protected byte[] readDiskCache(@NonNull String key) {
if (TextUtils.isEmpty(key)) {
return null;
}
@ -211,32 +196,37 @@ abstract class AbsCache implements CacheParam {
return data;
}
}
if (useDisk) {
synchronized (LOCK) {
byte[] data = null;
L.i(TAG, "读取磁盘缓存数据[key:" + key + ",hashKey:" + hashKey + "]");
InputStream inputStream = null;
try {
DiskLruCache.Snapshot snapshot = mDiskLruCache.get(hashKey);
if (snapshot != null) {
inputStream = snapshot.getInputStream(DISK_CACHE_INDEX);
data = StreamUtil.readStream(inputStream);
return data;
}
} catch (Exception e) {
FL.e(this, "readDiskCacheFailed[key:"
+ key
+ ",hashKey:"
+ hashKey
+ "]\n"
+ FL.getExceptionString(e));
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
synchronized (mDiskCacheLock) {
byte[] data = null;
L.i(TAG, "读取磁盘缓存数据[key:" + key + ",hashKey:" + hashKey + "]");
InputStream inputStream = null;
try {
DiskLruCache.Snapshot snapshot = mDiskLruCache.get(hashKey);
if (snapshot != null) {
inputStream = snapshot.getInputStream(DISK_CACHE_INDEX);
data = StreamUtil.readStream(inputStream);
return data;
}
} catch (IOException e) {
FL.e(this, "readDiskCacheFailed[key:"
+ key
+ ",hashKey:"
+ hashKey
+ "]\n"
+ FL.getExceptionString(e));
} catch (Exception e) {
FL.e(this, "readDiskCacheFailed[key:"
+ key
+ ",hashKey:"
+ hashKey
+ "]\n"
+ FL.getExceptionString(e));
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@ -254,7 +244,7 @@ abstract class AbsCache implements CacheParam {
if (mMemoryCache != null) {
mMemoryCache.remove(hashKey);
}
synchronized (LOCK) {
synchronized (mDiskCacheLock) {
if (mDiskLruCache != null) {
try {
mDiskLruCache.remove(hashKey);
@ -270,23 +260,14 @@ abstract class AbsCache implements CacheParam {
}
}
/**
* 关闭内存缓存
*/
void closeMemoryCache() {
if (mMemoryCache != null) {
mMemoryCache.evictAll();
}
}
/**
* 清除所有缓存
*/
void clearCache() {
protected void clearCache() {
if (mMemoryCache != null) {
mMemoryCache.evictAll();
}
synchronized (LOCK) {
synchronized (mDiskCacheLock) {
if (mDiskLruCache != null) {
try {
mDiskLruCache.delete();
@ -303,8 +284,8 @@ abstract class AbsCache implements CacheParam {
* 关闭掉了之后就不能再调用DiskLruCache中任何操作缓存数据的方法
* 通常只应该在Activity的onDestroy()方法中去调用close()方法
*/
void closeDiskCache() {
synchronized (LOCK) {
protected void closeDiskCache() {
synchronized (mDiskCacheLock) {
if (mDiskLruCache != null) {
try {
mDiskLruCache.close();
@ -320,8 +301,8 @@ abstract class AbsCache implements CacheParam {
* 注意在写入缓存时需要flush同步一次并不是每次写入缓存都要调用一次flush()方法的频繁地调用并不会带来任何好处
* 只会额外增加同步journal文件的时间比较标准的做法就是在Activity的onPause()方法中去调用一次flush()方法就可以了
*/
void flushDiskCache() {
synchronized (LOCK) {
protected void flushDiskCache() {
synchronized (mDiskCacheLock) {
if (mDiskLruCache != null) {
try {
mDiskLruCache.flush();
@ -339,16 +320,6 @@ abstract class AbsCache implements CacheParam {
return mDiskLruCache.size();
}
/**
* 生成缓存文件夹
*
* @param uniqueName 缓存文件夹名
* @return 缓存文件夹
*/
public static File getDiskCacheDir(Context context, String uniqueName) {
return new File(AndroidUtils.getDiskCacheDir(context) + File.separator + uniqueName);
}
/**
* 转换byte数组为String
*/
@ -364,4 +335,14 @@ abstract class AbsCache implements CacheParam {
}
return sb.toString();
}
/**
* 生成缓存文件夹
*
* @param uniqueName 缓存文件夹名
* @return 缓存文件夹
*/
public static File getDiskCacheDir(Context context, String uniqueName) {
return new File(AndroidUtils.getDiskCacheDir(context) + File.separator + uniqueName);
}
}

@ -1,10 +1,10 @@
package com.arialyy.frame.cache;
/**
* Created by AriaLyy@outlook.com on 2015/4/9.
* Created by Lyy on 2015/4/9.
* 缓存参数
*/
interface CacheParam {
public interface CacheParam {
/**
* 磁盘缓存
@ -17,7 +17,7 @@ interface CacheParam {
/**
* 内存缓存
*/
public static final int MEMORY_CACHE_SIZE = 4 * 1024 * 1024;
public static final int MEMORY_CACHE_SIZE = 1;
/**
* 小容量磁盘缓存
*/

@ -3,13 +3,15 @@ package com.arialyy.frame.cache;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import com.arialyy.frame.util.DrawableUtil;
import com.arialyy.frame.util.show.L;
import com.google.gson.Gson;
import java.io.UnsupportedEncodingException;
/**
* Created by AriaLyy@outlook.com on 2015/4/9.
* Created by AriaLyy on 2015/4/9.
* 缓存工具
*/
public class CacheUtil extends AbsCache {
@ -17,32 +19,28 @@ public class CacheUtil extends AbsCache {
/**
* 默认使用默认路径
*
* @param useMemory 是否使用内存缓存
*/
private CacheUtil(Context context) {
this(context, DEFAULT_DIR);
public CacheUtil(Context context, boolean useMemory) {
super(context, useMemory);
}
/**
* 指定缓存文件夹
*
* @param cacheDir 缓存文件夹名
*/
private CacheUtil(Context context, @NonNull String cacheDir) {
super(context, cacheDir);
}
/**
* 是否使用内存缓存
* @param useMemory 是否使用内存缓存
* @param cacheDir 缓存文件夹
*/
private void setUseMemoryCache(boolean openMemoryCache) {
setUseMemory(openMemoryCache);
public CacheUtil(Context context, boolean useMemory, @NonNull String cacheDir) {
super(context, useMemory, cacheDir);
}
/**
* 是否使用磁场缓存
* 设置是否使用内存缓存
*/
private void setUseDiskCache(boolean openDiskCache) {
setUseMemory(openDiskCache);
public void setUseMemoryCache(boolean useMemoryCache) {
setUseMemory(useMemoryCache);
}
/**
@ -180,15 +178,14 @@ public class CacheUtil extends AbsCache {
/**
* 删除所有缓存
*/
public void clearCache() {
super.clearCache();
public void removeAll() {
clearCache();
}
/**
* 关闭磁盘缓存
*/
public void close() {
closeMemoryCache();
closeDiskCache();
}
@ -198,65 +195,4 @@ public class CacheUtil extends AbsCache {
public long getCacheSize() {
return super.getCacheSize();
}
public static class Builder {
boolean openDiskCache = false;
boolean openMemoryCache = false;
String cacheDirName = DEFAULT_DIR;
long diskCacheSize = NORMAL_DISK_CACHE_CAPACITY;
int memoryCacheSize = MEMORY_CACHE_SIZE;
Context context;
public Builder(Context context) {
this.context = context;
}
/**
* 打开磁盘缓存
*/
public Builder openDiskCache() {
openDiskCache = true;
return this;
}
/**
* 打开内存缓存
*/
public Builder openMemoryCache() {
openMemoryCache = true;
return this;
}
/**
* 缓存文件夹名只需要写文件夹名
*/
public Builder setCacheDirName(String cacheDirName) {
this.cacheDirName = cacheDirName;
return this;
}
/**
* 设置磁盘缓存大小
*/
public Builder setDiskCacheSize(long cacheSize) {
this.diskCacheSize = cacheSize;
return this;
}
/**
* 设置内存缓存大小
*/
public Builder setMemoryCacheSize(int cacheSize) {
this.memoryCacheSize = cacheSize;
return this;
}
public CacheUtil build() {
CacheUtil util = new CacheUtil(context);
util.setUseMemoryCache(openMemoryCache);
util.setUseDiskCache(openDiskCache);
util.setMemoryCacheSize(memoryCacheSize);
return new CacheUtil(context, cacheDirName);
}
}
}

@ -0,0 +1,968 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.frame.cache;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* *****************************************************************************
* Taken from the JB source code, can be found in:
* libcore/luni/src/main/java/libcore/io/DiskLruCache.java
* or direct link:
* https://android.googlesource.com/platform/libcore/+/android-4.1.1_r1/luni/src/main/java/libcore/io/DiskLruCache.java
* *****************************************************************************
*
* A cache that uses a bounded amount of space on a filesystem. Each cache
* entry has a string key and a fixed number of values. Values are byte
* sequences, accessible as streams or files. Each value must be between {@code
* 0} and {@code Integer.MAX_VALUE} bytes in length.
*
* The cache stores its data in a directory on the filesystem. This
* directory must be exclusive to the cache; the cache may delete or overwrite
* files from its directory. It is an error for multiple processes to use the
* same cache directory at the same time.
*
* This cache limits the number of bytes that it will store on the
* filesystem. When the number of stored bytes exceeds the limit, the cache will
* remove entries in the background until the limit is satisfied. The limit is
* not strict: the cache may temporarily exceed it while waiting for files to be
* deleted. The limit does not include filesystem overhead or the cache
* journal so space-sensitive applications should set a conservative limit.
*
* Clients call {@link #edit} to create or update the values of an entry. An
* entry may have only one editor at one time; if a value is not available to be
* edited then {@link #edit} will return null.
*
* When an entry is being <strong>created</strong> it is necessary to
* supply a full set of values; the empty value should be used as a
* placeholder if necessary.
* When an entry is being <strong>edited</strong>, it is not necessary
* to supply data for every value; values default to their previous
* value.
*
* Clients call {@link #get} to read a snapshot of an entry. The read will
* observe the value at the time that {@link #get} was called. Updates and
* removals after the call do not impact ongoing reads.
*
* This class is tolerant of some I/O errors. If files are missing from the
* filesystem, the corresponding entries will be dropped from the cache. If
* an error occurs while writing a cache value, the edit will fail silently.
* Callers should handle other problems by catching {@code IOException} and
* responding appropriately.
*/
public final class DiskLruCache implements Closeable {
static final String JOURNAL_FILE = "journal";
static final String JOURNAL_FILE_TMP = "journal.tmp";
static final String MAGIC = "libcore.io.DiskLruCache";
static final String VERSION_1 = "1";
static final long ANY_SEQUENCE_NUMBER = -1;
private static final String CLEAN = "CLEAN";
private static final String DIRTY = "DIRTY";
private static final String REMOVE = "REMOVE";
private static final String READ = "READ";
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final int IO_BUFFER_SIZE = 8 * 1024;
/*
* This cache uses a journal file named "journal". A typical journal file
* looks like this:
* libcore.io.DiskLruCache
* 1
* 100
* 2
*
* CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
* DIRTY 335c4c6028171cfddfbaae1a9c313c52
* CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
* REMOVE 335c4c6028171cfddfbaae1a9c313c52
* DIRTY 1ab96a171faeeee38496d8b330771a7a
* CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
* READ 335c4c6028171cfddfbaae1a9c313c52
* READ 3400330d1dfc7f3f7f4b8d4d803dfcf6
*
* The first five lines of the journal form its header. They are the
* constant string "libcore.io.DiskLruCache", the disk cache's version,
* the application's version, the value count, and a blank line.
*
* Each of the subsequent lines in the file is a record of the state of a
* cache entry. Each line contains space-separated values: a state, a key,
* and optional state-specific values.
* o DIRTY lines track that an entry is actively being created or updated.
* Every successful DIRTY action should be followed by a CLEAN or REMOVE
* action. DIRTY lines without a matching CLEAN or REMOVE indicate that
* temporary files may need to be deleted.
* o CLEAN lines track a cache entry that has been successfully published
* and may be read. A publish line is followed by the lengths of each of
* its values.
* o READ lines track accesses for LRU.
* o REMOVE lines track entries that have been deleted.
*
* The journal file is appended to as cache operations occur. The journal may
* occasionally be compacted by dropping redundant lines. A temporary file named
* "journal.tmp" will be used during compaction; that file should be deleted if
* it exists when the cache is opened.
*/
private final File directory;
private final File journalFile;
private final File journalFileTmp;
private final int appVersion;
private final long maxSize;
private final int valueCount;
private long size = 0;
private Writer journalWriter;
private final LinkedHashMap<String, Entry> lruEntries =
new LinkedHashMap<String, Entry>(0, 0.75f, true);
private int redundantOpCount;
/**
* To differentiate between old and current snapshots, each entry is given
* a sequence number each time an edit is committed. A snapshot is stale if
* its sequence number is not equal to its entry's sequence number.
*/
private long nextSequenceNumber = 0;
/* From java.util.Arrays */
@SuppressWarnings("unchecked")
private static <T> T[] copyOfRange(T[] original, int start, int end) {
final int originalLength = original.length; // For exception priority compatibility.
if (start > end) {
throw new IllegalArgumentException();
}
if (start < 0 || start > originalLength) {
throw new ArrayIndexOutOfBoundsException();
}
final int resultLength = end - start;
final int copyLength = Math.min(resultLength, originalLength - start);
final T[] result =
(T[]) Array.newInstance(original.getClass().getComponentType(), resultLength);
System.arraycopy(original, start, result, 0, copyLength);
return result;
}
/**
* Returns the remainder of 'reader' as a string, closing it when done.
*/
public static String readFully(Reader reader) throws IOException {
try {
StringWriter writer = new StringWriter();
char[] buffer = new char[1024];
int count;
while ((count = reader.read(buffer)) != -1) {
writer.write(buffer, 0, count);
}
return writer.toString();
} finally {
reader.close();
}
}
/**
* Returns the ASCII characters up to but not including the next "\r\n", or
* "\n".
*
* @throws EOFException if the stream is exhausted before the next newline
* character.
*/
public static String readAsciiLine(InputStream in) throws IOException {
StringBuilder result = new StringBuilder(80);
while (true) {
int c = in.read();
if (c == -1) {
throw new EOFException();
} else if (c == '\n') {
break;
}
result.append((char) c);
}
int length = result.length();
if (length > 0 && result.charAt(length - 1) == '\r') {
result.setLength(length - 1);
}
return result.toString();
}
/**
* Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
*/
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (RuntimeException rethrown) {
throw rethrown;
} catch (Exception ignored) {
}
}
}
/**
* Recursively delete everything in {@code dir}.
*/
// TODO: this should specify paths as Strings rather than as Files
public static void deleteContents(File dir) throws IOException {
File[] files = dir.listFiles();
if (files == null) {
throw new IllegalArgumentException("not a directory: " + dir);
}
for (File file : files) {
if (file.isDirectory()) {
deleteContents(file);
}
if (!file.delete()) {
throw new IOException("failed to delete file: " + file);
}
}
}
/**
* This cache uses a single background thread to evict entries.
*/
private final ExecutorService executorService =
new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
private final Callable<Void> cleanupCallable = new Callable<Void>() {
@Override
public Void call() throws Exception {
synchronized (DiskLruCache.this) {
if (journalWriter == null) {
return null; // closed
}
trimToSize();
if (journalRebuildRequired()) {
rebuildJournal();
redundantOpCount = 0;
}
}
return null;
}
};
private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) {
this.directory = directory;
this.appVersion = appVersion;
this.journalFile = new File(directory, JOURNAL_FILE);
this.journalFileTmp = new File(directory, JOURNAL_FILE_TMP);
this.valueCount = valueCount;
this.maxSize = maxSize;
}
/**
* Opens the cache in {@code directory}, creating a cache if none exists
* there.
*
* @param directory a writable directory
* @param valueCount the number of values per cache entry. Must be positive.
* @param maxSize the maximum number of bytes this cache should use to store
* @throws IOException if reading or writing the cache directory fails
*/
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
throws IOException {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
if (valueCount <= 0) {
throw new IllegalArgumentException("valueCount <= 0");
}
// prefer to pick up where we left off
DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
if (cache.journalFile.exists()) {
try {
cache.readJournal();
cache.processJournal();
cache.journalWriter =
new BufferedWriter(new FileWriter(cache.journalFile, true), IO_BUFFER_SIZE);
return cache;
} catch (IOException journalIsCorrupt) {
// System.logW("DiskLruCache " + directory + " is corrupt: "
// + journalIsCorrupt.getMessage() + ", removing");
cache.delete();
}
}
// create a new empty cache
directory.mkdirs();
cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
cache.rebuildJournal();
return cache;
}
private void readJournal() throws IOException {
InputStream in = new BufferedInputStream(new FileInputStream(journalFile), IO_BUFFER_SIZE);
try {
String magic = readAsciiLine(in);
String version = readAsciiLine(in);
String appVersionString = readAsciiLine(in);
String valueCountString = readAsciiLine(in);
String blank = readAsciiLine(in);
if (!MAGIC.equals(magic) || !VERSION_1.equals(version) || !Integer.toString(appVersion)
.equals(appVersionString) || !Integer.toString(valueCount).equals(valueCountString) || !""
.equals(blank)) {
throw new IOException("unexpected journal header: ["
+ magic
+ ", "
+ version
+ ", "
+ valueCountString
+ ", "
+ blank
+ "]");
}
while (true) {
try {
readJournalLine(readAsciiLine(in));
} catch (EOFException endOfJournal) {
break;
}
}
} finally {
closeQuietly(in);
}
}
private void readJournalLine(String line) throws IOException {
String[] parts = line.split(" ");
if (parts.length < 2) {
throw new IOException("unexpected journal line: " + line);
}
String key = parts[1];
if (parts[0].equals(REMOVE) && parts.length == 2) {
lruEntries.remove(key);
return;
}
Entry entry = lruEntries.get(key);
if (entry == null) {
entry = new Entry(key);
lruEntries.put(key, entry);
}
if (parts[0].equals(CLEAN) && parts.length == 2 + valueCount) {
entry.readable = true;
entry.currentEditor = null;
entry.setLengths(copyOfRange(parts, 2, parts.length));
} else if (parts[0].equals(DIRTY) && parts.length == 2) {
entry.currentEditor = new Editor(entry);
} else if (parts[0].equals(READ) && parts.length == 2) {
// this work was already done by calling lruEntries.get()
} else {
throw new IOException("unexpected journal line: " + line);
}
}
/**
* Computes the initial size and collects garbage as a part of opening the
* cache. Dirty entries are assumed to be inconsistent and will be deleted.
*/
private void processJournal() throws IOException {
deleteIfExists(journalFileTmp);
for (Iterator<Entry> i = lruEntries.values().iterator(); i.hasNext(); ) {
Entry entry = i.next();
if (entry.currentEditor == null) {
for (int t = 0; t < valueCount; t++) {
size += entry.lengths[t];
}
} else {
entry.currentEditor = null;
for (int t = 0; t < valueCount; t++) {
deleteIfExists(entry.getCleanFile(t));
deleteIfExists(entry.getDirtyFile(t));
}
i.remove();
}
}
}
/**
* Creates a new journal that omits redundant information. This replaces the
* current journal if it exists.
*/
private synchronized void rebuildJournal() throws IOException {
if (journalWriter != null) {
journalWriter.close();
}
Writer writer = new BufferedWriter(new FileWriter(journalFileTmp), IO_BUFFER_SIZE);
writer.write(MAGIC);
writer.write("\n");
writer.write(VERSION_1);
writer.write("\n");
writer.write(Integer.toString(appVersion));
writer.write("\n");
writer.write(Integer.toString(valueCount));
writer.write("\n");
writer.write("\n");
for (Entry entry : lruEntries.values()) {
if (entry.currentEditor != null) {
writer.write(DIRTY + ' ' + entry.key + '\n');
} else {
writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
}
}
writer.close();
journalFileTmp.renameTo(journalFile);
journalWriter = new BufferedWriter(new FileWriter(journalFile, true), IO_BUFFER_SIZE);
}
private static void deleteIfExists(File file) throws IOException {
// try {
// Libcore.os.remove(file.getPath());
// } catch (ErrnoException errnoException) {
// if (errnoException.errno != OsConstants.ENOENT) {
// throw errnoException.rethrowAsIOException();
// }
// }
if (file.exists() && !file.delete()) {
throw new IOException();
}
}
/**
* Returns a snapshot of the entry named {@code key}, or null if it doesn't
* exist is not currently readable. If a value is returned, it is moved to
* the head of the LRU queue.
*/
public synchronized Snapshot get(String key) throws IOException {
checkNotClosed();
validateKey(key);
Entry entry = lruEntries.get(key);
if (entry == null) {
return null;
}
if (!entry.readable) {
return null;
}
/*
* Open all streams eagerly to guarantee that we see a single published
* snapshot. If we opened streams lazily then the streams could come
* from different edits.
*/
InputStream[] ins = new InputStream[valueCount];
try {
for (int i = 0; i < valueCount; i++) {
ins[i] = new FileInputStream(entry.getCleanFile(i));
}
} catch (FileNotFoundException e) {
// a file must have been deleted manually!
return null;
}
redundantOpCount++;
journalWriter.append(READ + ' ' + key + '\n');
if (journalRebuildRequired()) {
executorService.submit(cleanupCallable);
}
return new Snapshot(key, entry.sequenceNumber, ins);
}
/**
* Returns an editor for the entry named {@code key}, or null if another
* edit is in progress.
*/
public Editor edit(String key) throws IOException {
return edit(key, ANY_SEQUENCE_NUMBER);
}
private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException {
checkNotClosed();
validateKey(key);
Entry entry = lruEntries.get(key);
if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER && (entry == null
|| entry.sequenceNumber != expectedSequenceNumber)) {
return null; // snapshot is stale
}
if (entry == null) {
entry = new Entry(key);
lruEntries.put(key, entry);
} else if (entry.currentEditor != null) {
return null; // another edit is in progress
}
Editor editor = new Editor(entry);
entry.currentEditor = editor;
// flush the journal before creating files to prevent file leaks
journalWriter.write(DIRTY + ' ' + key + '\n');
journalWriter.flush();
return editor;
}
/**
* Returns the directory where this cache stores its data.
*/
public File getDirectory() {
return directory;
}
/**
* Returns the maximum number of bytes that this cache should use to store
* its data.
*/
public long maxSize() {
return maxSize;
}
/**
* Returns the number of bytes currently being used to store the values in
* this cache. This may be greater than the max size if a background
* deletion is pending.
*/
public synchronized long size() {
return size;
}
private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
Entry entry = editor.entry;
if (entry.currentEditor != editor) {
throw new IllegalStateException();
}
// if this edit is creating the entry for the first time, every index must have a value
if (success && !entry.readable) {
for (int i = 0; i < valueCount; i++) {
if (!entry.getDirtyFile(i).exists()) {
editor.abort();
throw new IllegalStateException("edit didn't create file " + i);
}
}
}
for (int i = 0; i < valueCount; i++) {
File dirty = entry.getDirtyFile(i);
if (success) {
if (dirty.exists()) {
File clean = entry.getCleanFile(i);
dirty.renameTo(clean);
long oldLength = entry.lengths[i];
long newLength = clean.length();
entry.lengths[i] = newLength;
size = size - oldLength + newLength;
}
} else {
deleteIfExists(dirty);
}
}
redundantOpCount++;
entry.currentEditor = null;
if (entry.readable | success) {
entry.readable = true;
journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
if (success) {
entry.sequenceNumber = nextSequenceNumber++;
}
} else {
lruEntries.remove(entry.key);
journalWriter.write(REMOVE + ' ' + entry.key + '\n');
}
if (size > maxSize || journalRebuildRequired()) {
executorService.submit(cleanupCallable);
}
}
/**
* We only rebuild the journal when it will halve the size of the journal
* and eliminate at least 2000 ops.
*/
private boolean journalRebuildRequired() {
final int REDUNDANT_OP_COMPACT_THRESHOLD = 2000;
return redundantOpCount >= REDUNDANT_OP_COMPACT_THRESHOLD
&& redundantOpCount >= lruEntries.size();
}
/**
* Drops the entry for {@code key} if it exists and can be removed. Entries
* actively being edited cannot be removed.
*
* @return true if an entry was removed.
*/
public synchronized boolean remove(String key) throws IOException {
checkNotClosed();
validateKey(key);
Entry entry = lruEntries.get(key);
if (entry == null || entry.currentEditor != null) {
return false;
}
for (int i = 0; i < valueCount; i++) {
File file = entry.getCleanFile(i);
if (!file.delete()) {
throw new IOException("failed to delete " + file);
}
size -= entry.lengths[i];
entry.lengths[i] = 0;
}
redundantOpCount++;
journalWriter.append(REMOVE + ' ' + key + '\n');
lruEntries.remove(key);
if (journalRebuildRequired()) {
executorService.submit(cleanupCallable);
}
return true;
}
/**
* Returns true if this cache has been closed.
*/
public boolean isClosed() {
return journalWriter == null;
}
private void checkNotClosed() {
if (journalWriter == null) {
throw new IllegalStateException("cache is closed");
}
}
/**
* Force buffered operations to the filesystem.
*/
public synchronized void flush() throws IOException {
checkNotClosed();
trimToSize();
journalWriter.flush();
}
/**
* Closes this cache. Stored values will remain on the filesystem.
*/
public synchronized void close() throws IOException {
if (journalWriter == null) {
return; // already closed
}
for (Entry entry : new ArrayList<Entry>(lruEntries.values())) {
if (entry.currentEditor != null) {
entry.currentEditor.abort();
}
}
trimToSize();
journalWriter.close();
journalWriter = null;
}
private void trimToSize() throws IOException {
while (size > maxSize) {
// Map.Entry<String, Entry> toEvict = lruEntries.eldest();
final Map.Entry<String, Entry> toEvict = lruEntries.entrySet().iterator().next();
remove(toEvict.getKey());
}
}
/**
* Closes the cache and deletes all of its stored values. This will delete
* all files in the cache directory including files that weren't created by
* the cache.
*/
public void delete() throws IOException {
close();
deleteContents(directory);
}
private void validateKey(String key) {
if (key.contains(" ") || key.contains("\n") || key.contains("\r")) {
throw new IllegalArgumentException(
"keys must not contain spaces or newlines: \"" + key + "\"");
}
}
private static String inputStreamToString(InputStream in) throws IOException {
return readFully(new InputStreamReader(in, UTF_8));
}
/**
* A snapshot of the values for an entry.
*/
public final class Snapshot implements Closeable {
private final String key;
private final long sequenceNumber;
private final InputStream[] ins;
private Snapshot(String key, long sequenceNumber, InputStream[] ins) {
this.key = key;
this.sequenceNumber = sequenceNumber;
this.ins = ins;
}
/**
* Returns an editor for this snapshot's entry, or null if either the
* entry has changed since this snapshot was created or if another edit
* is in progress.
*/
public Editor edit() throws IOException {
return DiskLruCache.this.edit(key, sequenceNumber);
}
/**
* Returns the unbuffered stream with the value for {@code index}.
*/
public InputStream getInputStream(int index) {
return ins[index];
}
/**
* Returns the string value for {@code index}.
*/
public String getString(int index) throws IOException {
return inputStreamToString(getInputStream(index));
}
@Override
public void close() {
for (InputStream in : ins) {
closeQuietly(in);
}
}
}
/**
* Edits the values for an entry.
*/
public final class Editor {
private final Entry entry;
private boolean hasErrors;
private Editor(Entry entry) {
this.entry = entry;
}
/**
* Returns an unbuffered input stream to read the last committed value,
* or null if no value has been committed.
*/
public InputStream newInputStream(int index) throws IOException {
synchronized (DiskLruCache.this) {
if (entry.currentEditor != this) {
throw new IllegalStateException();
}
if (!entry.readable) {
return null;
}
return new FileInputStream(entry.getCleanFile(index));
}
}
/**
* Returns the last committed value as a string, or null if no value
* has been committed.
*/
public String getString(int index) throws IOException {
InputStream in = newInputStream(index);
return in != null ? inputStreamToString(in) : null;
}
/**
* Returns a new unbuffered output stream to write the value at
* {@code index}. If the underlying output stream encounters errors
* when writing to the filesystem, this edit will be aborted when
* {@link #commit} is called. The returned output stream does not throw
* IOExceptions.
*/
public OutputStream newOutputStream(int index) throws IOException {
synchronized (DiskLruCache.this) {
if (entry.currentEditor != this) {
throw new IllegalStateException();
}
return new FaultHidingOutputStream(new FileOutputStream(entry.getDirtyFile(index)));
}
}
/**
* Sets the value at {@code index} to {@code value}.
*/
public void set(int index, String value) throws IOException {
Writer writer = null;
try {
writer = new OutputStreamWriter(newOutputStream(index), UTF_8);
writer.write(value);
} finally {
closeQuietly(writer);
}
}
/**
* Commits this edit so it is visible to readers. This releases the
* edit lock so another edit may be started on the same key.
*/
public void commit() throws IOException {
if (hasErrors) {
completeEdit(this, false);
remove(entry.key); // the previous entry is stale
} else {
completeEdit(this, true);
}
}
/**
* Aborts this edit. This releases the edit lock so another edit may be
* started on the same key.
*/
public void abort() throws IOException {
completeEdit(this, false);
}
private class FaultHidingOutputStream extends FilterOutputStream {
private FaultHidingOutputStream(OutputStream out) {
super(out);
}
@Override
public void write(int oneByte) {
try {
out.write(oneByte);
} catch (IOException e) {
hasErrors = true;
}
}
@Override
public void write(byte[] buffer, int offset, int length) {
try {
out.write(buffer, offset, length);
} catch (IOException e) {
hasErrors = true;
}
}
@Override
public void close() {
try {
out.close();
} catch (IOException e) {
hasErrors = true;
}
}
@Override
public void flush() {
try {
out.flush();
} catch (IOException e) {
hasErrors = true;
}
}
}
}
private final class Entry {
private final String key;
/**
* Lengths of this entry's files.
*/
private final long[] lengths;
/**
* True if this entry has ever been published
*/
private boolean readable;
/**
* The ongoing edit or null if this entry is not being edited.
*/
private Editor currentEditor;
/**
* The sequence number of the most recently committed edit to this entry.
*/
private long sequenceNumber;
private Entry(String key) {
this.key = key;
this.lengths = new long[valueCount];
}
public String getLengths() throws IOException {
StringBuilder result = new StringBuilder();
for (long size : lengths) {
result.append(' ').append(size);
}
return result.toString();
}
/**
* Set lengths using decimal numbers like "10123".
*/
private void setLengths(String[] strings) throws IOException {
if (strings.length != valueCount) {
throw invalidLengths(strings);
}
try {
for (int i = 0; i < strings.length; i++) {
lengths[i] = Long.parseLong(strings[i]);
}
} catch (NumberFormatException e) {
throw invalidLengths(strings);
}
}
private IOException invalidLengths(String[] strings) throws IOException {
throw new IOException("unexpected journal line: " + Arrays.toString(strings));
}
public File getCleanFile(int i) {
return new File(directory, key + "." + i);
}
public File getDirtyFile(int i) {
return new File(directory, key + "." + i + ".tmp");
}
}
}

@ -0,0 +1,21 @@
package com.arialyy.frame.cache;
import android.os.Environment;
/**
* Created by AriaL on 2017/11/26.
*/
public class PathConstaant {
private static final String WP_DIR = "windPath";
/**
* 获取APK升级路径
*/
public static String getWpPath() {
return Environment.getExternalStorageDirectory().getPath()
+ "/"
+ WP_DIR
+ "/update/windPath.apk";
}
}

@ -0,0 +1,9 @@
package com.arialyy.frame.config;
/**
* Created by AriaL on 2017/11/26.
*/
public interface CommonConstant {
boolean DEBUG = true;
}

@ -0,0 +1,9 @@
package com.arialyy.frame.config;
/**
* Created by AriaL on 2017/11/26.
*/
public interface NetConstant {
String BASE_URL = "http://wwww.baidu.com/";
}

@ -8,6 +8,7 @@ import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.arialyy.frame.module.AbsModule;
import com.arialyy.frame.module.IOCProxy;
import com.arialyy.frame.temp.AbsTempView;
@ -17,25 +18,26 @@ import com.arialyy.frame.util.StringUtil;
import com.arialyy.frame.util.show.T;
/**
* Created by AriaLyy@outlook.com on 2015/11/3.
* Created by lyy on 2015/11/3.
* 所有的 Activity都应该继承这个类
*/
public abstract class AbsActivity<VB extends ViewDataBinding> extends AppCompatActivity
implements OnTempBtClickListener {
protected String TAG = "";
protected AbsFrame mAm;
protected View mRootView;
protected AbsTempView mTempView;
protected boolean useTempView = true;
private VB mBind;
private IOCProxy mProxy;
/**
* 第一次点击返回的系统时间
*/
private long mFirstClickTime = 0;
protected AbsFrame mAm;
protected View mRootView;
private ModuleFactory mModuleF;
protected AbsTempView mTempView;
protected boolean useTempView = true;
@Override protected void onCreate(Bundle savedInstanceState) {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initialization();
init(savedInstanceState);
@ -55,12 +57,6 @@ public abstract class AbsActivity<VB extends ViewDataBinding> extends AppCompatA
}
}
protected void reNewModule() {
if (mModuleF == null) {
mModuleF = ModuleFactory.newInstance();
}
}
/**
* 获取填充View
*/
@ -115,7 +111,8 @@ public abstract class AbsActivity<VB extends ViewDataBinding> extends AppCompatA
*/
protected void hintTempView(int delay) {
new Handler().postDelayed(new Runnable() {
@Override public void run() {
@Override
public void run() {
if (mTempView == null || !useTempView) {
return;
}
@ -126,11 +123,13 @@ public abstract class AbsActivity<VB extends ViewDataBinding> extends AppCompatA
}, delay);
}
@Override public void onBtTempClick(View view, int type) {
@Override
public void onBtTempClick(View view, int type) {
}
@Override protected void onDestroy() {
@Override
protected void onDestroy() {
super.onDestroy();
}
@ -138,7 +137,8 @@ public abstract class AbsActivity<VB extends ViewDataBinding> extends AppCompatA
}
@Override public void finish() {
@Override
public void finish() {
super.finish();
mAm.removeActivity(this);
}
@ -228,13 +228,15 @@ public abstract class AbsActivity<VB extends ViewDataBinding> extends AppCompatA
mAm.exitApp(false);
}
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionHelp.getInstance().handlePermissionCallback(requestCode, permissions, grantResults);
}
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
PermissionHelp.getInstance()
.handleSpecialPermissionCallback(this, requestCode, resultCode, data);

@ -3,9 +3,9 @@ package com.arialyy.frame.core;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import com.arialyy.frame.module.AbsModule;
import com.arialyy.frame.module.IOCProxy;
import com.arialyy.frame.util.StringUtil;
@ -34,12 +34,15 @@ public abstract class AbsAlertDialog extends DialogFragment {
mObj = obj;
}
@Override public void onCreate(Bundle savedInstanceState) {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDialog();
}
@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
@ -98,13 +101,15 @@ public abstract class AbsAlertDialog extends DialogFragment {
protected abstract void dataCallback(int result, Object obj);
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionHelp.getInstance().handlePermissionCallback(requestCode, permissions, grantResults);
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
PermissionHelp.getInstance()
.handleSpecialPermissionCallback(getContext(), requestCode, resultCode, data);

@ -2,16 +2,13 @@ package com.arialyy.frame.core;
import android.app.Dialog;
import android.content.Context;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.Window;
import com.arialyy.frame.module.AbsModule;
import com.arialyy.frame.module.IOCProxy;
import com.arialyy.frame.util.StringUtil;
/**
* Created by lyy on 2015/11/4.
* 继承Dialog

@ -18,6 +18,7 @@ import com.arialyy.frame.module.IOCProxy;
import com.arialyy.frame.util.StringUtil;
import com.lyy.frame.R;
/**
* Created by lyy on 2015/11/4.
* DialogFragment
@ -61,10 +62,6 @@ public abstract class AbsDialogFragment<VB extends ViewDataBinding> extends Dial
return mRootView;
}
public <V extends View> V findViewById(@IdRes int id) {
return mRootView.findViewById(id);
}
@Override public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof AbsActivity) {
@ -72,6 +69,10 @@ public abstract class AbsDialogFragment<VB extends ViewDataBinding> extends Dial
}
}
public <T extends View> T findViewById(@IdRes int id){
return mRootView.findViewById(id);
}
private void initFragment() {
TAG = StringUtil.getClassName(this);
mProxy = IOCProxy.newInstance(this);

@ -29,7 +29,6 @@ import com.arialyy.frame.util.show.L;
import java.lang.reflect.Field;
/**
* Created by lyy on 2015/11/4.
* 基础Fragment

@ -1,15 +1,16 @@
package com.arialyy.frame.core;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.os.Process;
import com.arialyy.frame.base.BaseApp;
import com.arialyy.frame.util.show.FL;
import java.io.File;
import java.util.Iterator;
import java.util.Stack;
/**
* Created by AriaLyy@outlook.com on 2015/11/4.
* Created by lyy on 2015/11/4.
* APP生命周期管理类管理
*/
public class AbsFrame {
@ -23,18 +24,20 @@ public class AbsFrame {
}
private AbsFrame(Context context) {
mContext = context;
private AbsFrame(Application application) {
mContext = application.getApplicationContext();
BaseApp.context = mContext;
BaseApp.app = application;
}
/**
* 初始化框架
*/
public static AbsFrame init(Context applicationContext) {
public static AbsFrame init(Application app) {
if (mManager == null) {
synchronized (LOCK) {
if (mManager == null) {
mManager = new AbsFrame(applicationContext);
mManager = new AbsFrame(app);
}
}
}
@ -51,18 +54,6 @@ public class AbsFrame {
return mManager;
}
/**
* activity 是否存在
*/
public boolean activityExists(Class clazz) {
for (AbsActivity activity : mActivityStack) {
if (activity.getClass().getName().equals(clazz.getName())) {
return true;
}
}
return false;
}
/**
* 获取Activity栈
*/
@ -72,7 +63,7 @@ public class AbsFrame {
/**
* 开启异常捕获
* 日志文件位于/data/data/Package Name/cache//crash/2016.10.26_AbsExceptionFile.crash
* 日志文件位于/data/data/Package Name/cache//crash/AbsExceptionFile.crash
*/
public void openCrashHandler() {
openCrashHandler("", "");
@ -137,6 +128,7 @@ public class AbsFrame {
*/
public void finishActivity(AbsActivity activity) {
if (activity != null) {
mActivityStack.remove(activity);
activity.finish();
}
}
@ -146,10 +138,7 @@ public class AbsFrame {
*/
public void removeActivity(AbsActivity activity) {
if (activity != null) {
int i = mActivityStack.search(activity);
if (i != -1) {
mActivityStack.remove(activity);
}
mActivityStack.remove(activity);
}
}
@ -157,12 +146,9 @@ public class AbsFrame {
* 结束指定类名的Activity
*/
public void finishActivity(Class<?> cls) {
Iterator<AbsActivity> iter = mActivityStack.iterator();
while (iter.hasNext()) {
AbsActivity activity = iter.next();
if (activity.getClass().getName().equals(cls.getName())) {
iter.remove();
activity.finish();
for (AbsActivity activity : mActivityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
}
}
}
@ -187,16 +173,15 @@ public class AbsFrame {
public void exitApp(Boolean isBackground) {
try {
finishAllActivity();
//ActivityManager activityMgr =
// (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
//activityMgr.restartPackage(mContext.getPackageName());
ActivityManager activityMgr =
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
activityMgr.restartPackage(mContext.getPackageName());
} catch (Exception e) {
FL.e(TAG, FL.getExceptionString(e));
} finally {
// 注意,如果您有后台程序运行,请不要支持此句子
if (!isBackground) {
System.exit(0);
//Process.killProcess(Process.myPid());
}
}
}

@ -9,12 +9,10 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import com.arialyy.frame.module.AbsModule;
import com.arialyy.frame.module.IOCProxy;
import com.arialyy.frame.util.StringUtil;
/**
* Created by lyy on 2015/12/3.
* 抽象的Popupwindow悬浮框
@ -22,7 +20,7 @@ import com.arialyy.frame.util.StringUtil;
public abstract class AbsPopupWindow extends PopupWindow {
protected String TAG;
private static Context mContext;
private Context mContext;
private Drawable mBackground;
protected View mView;
private Object mObj;
@ -62,14 +60,14 @@ public abstract class AbsPopupWindow extends PopupWindow {
TAG = StringUtil.getClassName(this);
// 设置SelectPicPopupWindow弹出窗体的宽
setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
// 设置SelectPicPopupWindow弹出窗体的高
setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
//// 设置SelectPicPopupWindow弹出窗体的高
setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
setFocusable(true);
// 设置SelectPicPopupWindow弹出窗体动画效果
// setAnimationStyle(R.style.wisdom_anim_style);
// 实例化一个ColorDrawable颜色为半透明
if (mBackground == null) {
mBackground = new ColorDrawable(Color.parseColor("#7f000000"));
mBackground = new ColorDrawable(Color.parseColor("#4f000000"));
}
// 设置SelectPicPopupWindow弹出窗体的背景
setBackgroundDrawable(mBackground);

@ -1,9 +1,9 @@
package com.arialyy.frame.core;
import android.databinding.ViewDataBinding;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by lyy on 2016/9/16.
@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class BindingFactory {
private final String TAG = "BindingFactory";
private Map<Integer, ViewDataBinding> mBindings = new ConcurrentHashMap<>();
private Map<Integer, ViewDataBinding> mBindings = new HashMap<>();
private BindingFactory() {

@ -2,11 +2,13 @@ package com.arialyy.frame.core;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Looper;
import android.text.TextUtils;
import com.arialyy.frame.http.HttpUtil;
import com.arialyy.frame.permission.PermissionManager;
import com.arialyy.frame.util.AndroidUtils;
import com.arialyy.frame.util.CalendarUtils;
import com.arialyy.frame.util.FileUtil;
@ -64,7 +66,8 @@ final class CrashHandler implements Thread.UncaughtExceptionHandler {
mPramKey = key;
}
@Override public void uncaughtException(Thread thread, Throwable ex) {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
} else {
@ -90,7 +93,8 @@ final class CrashHandler implements Thread.UncaughtExceptionHandler {
}
//在这里处理崩溃逻辑,将不再显示FC对话框
new Thread() {
@Override public void run() {
@Override
public void run() {
Looper.prepare();
T.showLong(mContext, "很抱歉,程序出现异常,即将退出");
Looper.loop();
@ -111,8 +115,8 @@ final class CrashHandler implements Thread.UncaughtExceptionHandler {
info.systemVersionCode = Build.VERSION.SDK_INT;
info.phoneModel = Build.MODEL;
info.exceptionMsg = FL.getExceptionString(ex);
if (AndroidUtils.checkPermission(mContext, Manifest.permission.INTERNET)
&& AndroidUtils.checkPermission(mContext, Manifest.permission.ACCESS_NETWORK_STATE)) {
if (AndroidUtils.checkPermission(mContext, Manifest.permission.INTERNET) &&
AndroidUtils.checkPermission(mContext, Manifest.permission.ACCESS_NETWORK_STATE)) {
if (NetUtils.isConnected(mContext) && !TextUtils.isEmpty(mServerHost) && !TextUtils.isEmpty(
mPramKey)) {
String objStr = new Gson().toJson(info);

@ -25,7 +25,8 @@ public class DialogSimpleModule extends AbsModule {
/**
* 可设置参数和回调名的回调函数
*/
@Deprecated public void onDialog(String methodName, Class<?> param, Object data) {
@Deprecated
public void onDialog(String methodName, Class<?> param, Object data) {
callback(methodName, param, data);
}
@ -34,7 +35,8 @@ public class DialogSimpleModule extends AbsModule {
*
* @param b 需要回调的数据
*/
@Deprecated public void onDialog(Bundle b) {
@Deprecated
public void onDialog(Bundle b) {
callback("onDialog", Bundle.class, b);
}
}

@ -8,7 +8,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by lyy on 2015/8/31.
@ -18,7 +17,7 @@ public class ModuleFactory {
private final String TAG = "ModuleFactory";
private Map<Integer, AbsModule> mModules = new ConcurrentHashMap<>();
private Map<Integer, AbsModule> mModules = new HashMap<>();
private ModuleFactory() {
@ -50,7 +49,6 @@ public class ModuleFactory {
Object[] params = { context };
try {
Constructor<T> con = clazz.getConstructor(paramTypes);
con.setAccessible(true);
T module = con.newInstance(params);
mModules.put(clazz.hashCode(), module);
return module;

@ -36,7 +36,7 @@ import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by AriaLyy@outlook.com on 2015/11/5.
* Created by lyy on 2015/11/5.
* 网络连接工具
*/
public class HttpUtil {
@ -56,7 +56,7 @@ public class HttpUtil {
private HttpUtil(Context context) {
mContext = context;
mCacheUtil = new CacheUtil.Builder(context).openDiskCache().build();
mCacheUtil = new CacheUtil(mContext, false);
mHandler = new Handler(Looper.getMainLooper());
}
@ -110,10 +110,12 @@ public class HttpUtil {
* @param key 上传文件键值
*/
public void uploadFile(@NonNull final String url, @NonNull final String filePath,
@NonNull final String key, final String contentType, final Map<String, String> header,
@NonNull final String key,
final String contentType, final Map<String, String> header,
@NonNull final IResponse absResponse) {
new Thread(new Runnable() {
@Override public void run() {
@Override
public void run() {
File file = new File(filePath);
String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
String PREFIX = "--", LINE_END = "\r\n";
@ -131,9 +133,10 @@ public class HttpUtil {
conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
if (header != null && header.size() > 0) {
Set<String> keys = header.keySet();
for (String key : keys) {
conn.setRequestProperty(key, header.get(key));
Set set = header.entrySet();
for (Object aSet : set) {
Map.Entry entry = (Map.Entry) aSet;
conn.setRequestProperty(entry.getKey() + "", entry.getValue() + "");
}
}
OutputStream outputSteam = conn.getOutputStream();
@ -193,12 +196,13 @@ public class HttpUtil {
L.v(TAG, "请求链接 >>>> " + url);
String requestUrl = url;
if (params != null && params.size() > 0) {
Set<String> keys = params.keySet();
Set set = params.entrySet();
int i = 0;
requestUrl += "?";
for (String key : keys) {
for (Object aSet : set) {
i++;
requestUrl += key + "=" + params.get(key) + (i < params.size() ? "&" : "");
Map.Entry entry = (Map.Entry) aSet;
requestUrl += entry.getKey() + "=" + entry.getValue() + (i < params.size() ? "&" : "");
}
L.v(TAG, "请求参数为 >>>> ");
L.m(params);
@ -213,7 +217,8 @@ public class HttpUtil {
//请求加入调度
call.enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
@Override
public void onFailure(Call call, IOException e) {
L.e(TAG, "请求链接【" + url + "】失败");
String data = null;
if (useCache) {
@ -228,7 +233,8 @@ public class HttpUtil {
}
}
@Override public void onResponse(Call call, Response response) throws IOException {
@Override
public void onResponse(Call call, Response response) throws IOException {
String data = response.body().string();
L.d(TAG, "数据获取成功,获取到的数据为 >>>> ");
L.j(data);
@ -256,18 +262,20 @@ public class HttpUtil {
//头数据
Headers.Builder hb = new Headers.Builder();
if (header != null && header.size() > 0) {
Set<String> keys = header.keySet();
for (String key : keys) {
hb.add(key, header.get(key));
Set set = header.entrySet();
for (Object aSet : set) {
Map.Entry entry = (Map.Entry) aSet;
hb.add(entry.getKey() + "", entry.getValue() + "");
}
L.v(TAG, "请求的头数据为 >>>> ");
L.m(header);
}
//请求参数
if (params != null && params.size() > 0) {
Set<String> keys = params.keySet();
for (String key : keys) {
formB.add(key, params.get(key));
Set set = params.entrySet();
for (Object aSet : set) {
Map.Entry entry = (Map.Entry) aSet;
formB.add(entry.getKey() + "", entry.getValue() + "");
}
L.v(TAG, "请求参数为 >>>> ");
L.m(params);
@ -279,7 +287,8 @@ public class HttpUtil {
new Request.Builder().url(url).post(formB.build()).headers(hb.build()).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
@Override
public void onFailure(Call call, IOException e) {
L.e(TAG, "请求链接【" + url + "】失败");
String data = null;
if (useCache) {
@ -294,7 +303,8 @@ public class HttpUtil {
}
}
@Override public void onResponse(Call call, Response response) throws IOException {
@Override
public void onResponse(Call call, Response response) throws IOException {
String data = response.body().string();
L.d(TAG, "数据获取成功,获取到的数据为 >>>>");
L.j(data);
@ -309,7 +319,8 @@ public class HttpUtil {
private void setOnError(final Object error, final IResponse response) {
mHandler.post(new Runnable() {
@Override public void run() {
@Override
public void run() {
response.onError(error);
}
});
@ -317,7 +328,8 @@ public class HttpUtil {
private void setOnResponse(final String data, final IResponse response) {
mHandler.post(new Runnable() {
@Override public void run() {
@Override
public void run() {
response.onResponse(data);
}
});
@ -328,11 +340,13 @@ public class HttpUtil {
*/
public static class AbsResponse implements IResponse {
@Override public void onResponse(String data) {
@Override
public void onResponse(String data) {
}
@Override public void onError(Object error) {
@Override
public void onError(Object error) {
}
}

@ -1,14 +1,23 @@
package com.arialyy.frame.module;
import android.content.Context;
import android.databinding.ViewDataBinding;
import android.text.TextUtils;
import android.util.SparseIntArray;
import android.view.View;
import com.arialyy.frame.core.AbsActivity;
import com.arialyy.frame.core.BindingFactory;
import com.arialyy.frame.module.inf.ModuleListener;
import com.arialyy.frame.util.ObjUtil;
import com.arialyy.frame.util.StringUtil;
import com.arialyy.frame.util.show.L;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by AriaLyy on 2015/2/3.
* 抽象的module
@ -46,7 +55,9 @@ public class AbsModule {
* @param moduleListener Module监听
*/
public void setModuleListener(ModuleListener moduleListener) {
if (moduleListener == null) throw new NullPointerException("ModuleListener不能为空");
if (moduleListener == null) {
throw new NullPointerException("ModuleListener不能为空");
}
this.mModuleListener = moduleListener;
}
@ -126,7 +137,8 @@ public class AbsModule {
*
* @param method 回调的方法名
*/
@Deprecated protected void callback(String method) {
@Deprecated
protected void callback(String method) {
mModuleListener.callback(method);
}
@ -137,7 +149,8 @@ public class AbsModule {
* @param dataClassType 回调数据类型
* @param data 回调数据
*/
@Deprecated protected void callback(String method, Class<?> dataClassType, Object data) {
@Deprecated
protected void callback(String method, Class<?> dataClassType, Object data) {
mModuleListener.callback(method, dataClassType, data);
}
}

@ -50,7 +50,8 @@ public class IOCProxy implements ModuleListener {
* @param result 返回码
* @param data 回调数据
*/
@Override public void callback(int result, Object data) {
@Override
public void callback(int result, Object data) {
synchronized (this) {
try {
Method m = ReflectionUtil.getMethod(mObj.getClass(), mMethod, int.class, Object.class);
@ -69,7 +70,9 @@ public class IOCProxy implements ModuleListener {
*
* @param method 方法名
*/
@Override @Deprecated public void callback(String method) {
@Override
@Deprecated
public void callback(String method) {
synchronized (this) {
try {
Method m = mObj.getClass().getDeclaredMethod(method);
@ -93,7 +96,9 @@ public class IOCProxy implements ModuleListener {
* @param dataClassType 参数类型, int.class
* @param data 数据
*/
@Override @Deprecated public void callback(String method, Class<?> dataClassType, Object data) {
@Override
@Deprecated
public void callback(String method, Class<?> dataClassType, Object data) {
synchronized (this) {
try {
Method m = mObj.getClass().getDeclaredMethod(method, dataClassType);

@ -54,8 +54,7 @@ public class ModuleFactory {
* @return true : key已经和value对应false : key没有和value对应
*/
private boolean checkKey(int key, AbsModule.OnCallback callback) {
return mKeyIndex.indexOfKey(key) != -1
|| mKeyIndex.indexOfValue(callback.hashCode()) != -1
return mKeyIndex.indexOfKey(key) != -1 || mKeyIndex.indexOfValue(callback.hashCode()) != -1
&& mKeyIndex.valueAt(callback.hashCode()) == key;
}
}

@ -85,8 +85,10 @@ import java.util.List;
* @param obj Activity || Fragment
* @param permission 权限
*/
public void requestPermission(Object obj, OnPermissionCallback callback, String... permission) {
requestPermission(obj, "", callback, registerCallback(obj, callback, permission));
public PermissionManager requestPermission(Object obj, OnPermissionCallback callback,
String... permission) {
requestPermissionAndHint(obj, callback, "", registerCallback(obj, callback, permission));
return this;
}
/**
@ -96,9 +98,9 @@ import java.util.List;
* @param hint 如果框对话框包含不再询问选择框的时候的提示用语
* @param permission 权限
*/
private void requestPermission(Object obj, String hint, OnPermissionCallback callback,
public void requestPermissionAndHint(Object obj, OnPermissionCallback callback, String hint,
String... permission) {
mPu.requestPermission(obj, hint, 0, registerCallback(obj, callback, permission));
mPu.requestPermission(obj, 0, hint, registerCallback(obj, callback, permission));
}
private void registerCallback(OnPermissionCallback callback, int hashCode) {

@ -45,7 +45,7 @@ import java.util.List;
if (!AndroidVersionUtil.hasM()) {
return;
}
requestPermission(obj, "", requestCode, permission);
requestPermission(obj, requestCode, "", permission);
}
/**
@ -53,7 +53,7 @@ import java.util.List;
*
* @param hint 如果框对话框包含不再询问选择框的时候的提示用语
*/
public void requestPermission(Object obj, String hint, int requestCode, String... permission) {
public void requestPermission(Object obj, int requestCode, String hint, String... permission) {
if (!AndroidVersionUtil.hasM() || permission == null || permission.length == 0) {
return;
}
@ -72,12 +72,12 @@ import java.util.List;
for (String str : permission) {
if (fragment != null) {
if (fragment.shouldShowRequestPermissionRationale(str)) {
T.showShort(fragment.getContext(), hint);
T.showLong(fragment.getContext(), hint);
break;
}
} else {
if (activity.shouldShowRequestPermissionRationale(str)) {
T.showShort(activity, hint);
T.showLong(activity, hint);
break;
}
}

@ -10,7 +10,6 @@ import android.widget.LinearLayout;
import com.arialyy.frame.util.StringUtil;
import com.arialyy.frame.util.show.L;
/**
* Created by lyy on 2016/4/27.
* 抽象的填充类
@ -57,7 +56,8 @@ public abstract class AbsTempView extends LinearLayout implements ITempView {
}
}
@Override public void setType(int type) {
@Override
public void setType(int type) {
mType = type;
if (type == LOADING) {
onLoading();

@ -23,37 +23,43 @@ public class TempView extends AbsTempView {
super(context);
}
@Override protected void init() {
@Override
protected void init() {
mPb = (ProgressBar) findViewById(R.id.pb);
mHint = (TextView) findViewById(R.id.hint);
mBt = (Button) findViewById(R.id.bt);
mErrorContent = (FrameLayout) findViewById(R.id.error);
mBt.setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
@Override
public void onClick(View v) {
onTempBtClick(v, mType);
}
});
}
@Override protected int setLayoutId() {
@Override
protected int setLayoutId() {
return R.layout.layout_error_temp;
}
@Override public void onError() {
@Override
public void onError() {
mErrorContent.setVisibility(VISIBLE);
mPb.setVisibility(GONE);
mHint.setText("网络错误");
mBt.setText("点击刷新");
}
@Override public void onNull() {
@Override
public void onNull() {
mErrorContent.setVisibility(VISIBLE);
mPb.setVisibility(GONE);
mHint.setText("数据为空");
mBt.setText("点击刷新");
}
@Override public void onLoading() {
@Override
public void onLoading() {
mErrorContent.setVisibility(GONE);
mPb.setVisibility(VISIBLE);
}

@ -140,7 +140,9 @@ public class AESEncryption {
* AES算法的秘钥要求16位
*/
public static String toHex(byte[] buf) {
if (buf == null) return "";
if (buf == null) {
return "";
}
StringBuffer result = new StringBuffer(2 * buf.length);
for (byte aBuf : buf) {
appendHex(result, aBuf);

@ -1,11 +1,8 @@
package com.arialyy.frame.util;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -21,13 +18,14 @@ import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.telephony.TelephonyManager;
import android.text.format.Formatter;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import com.arialyy.frame.util.show.FL;
import com.arialyy.frame.util.show.L;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
@ -48,35 +46,18 @@ public class AndroidUtils {
}
private static final float DENSITY = Resources.getSystem().getDisplayMetrics().density;
// 获得机身可用内存
public static String getRomAvailableSize(Context context) {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return Formatter.formatFileSize(context, blockSize * availableBlocks);
}
/**
* 重启app
* 应用市场是否存在
*
* @return {@code true}存在
*/
public static void reStartApp(Context context) {
Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(context.getPackageName());
PendingIntent restartIntent =
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
System.exit(0);
}
public static boolean hasAnyMarket(Context context) {
Intent intent = new Intent();
intent.setData(Uri.parse("market://details?id=android.browser"));
List list = context.getPackageManager()
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
/**
* 另外一种dp转PX方法
*/
public static int dp2px(int dp) {
return Math.round(dp * DENSITY);
return list != null && list.size() > 0;
}
/**
@ -148,6 +129,14 @@ public class AndroidUtils {
return "";
}
/**
* 获取未安装软件包的包名
*/
public static PackageInfo getApkPackageInfo(Context context, String apkPath) {
PackageManager pm = context.getPackageManager();
return pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
}
/**
* 判断是否安装
*/
@ -196,8 +185,6 @@ public class AndroidUtils {
public static void startOtherApp(Context context, String packageName) {
PackageManager pm = context.getPackageManager();
Intent launcherIntent = pm.getLaunchIntentForPackage(packageName);
launcherIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(launcherIntent);
}
@ -445,8 +432,8 @@ public class AndroidUtils {
* 安装APP
*/
public static void install(Context context, File file) {
L.e(TAG, "install Apk:" + file.getName());
context.startActivity(getInstallIntent(file));
FL.e(TAG, "install Apk:" + file.getName());
context.startActivity(getInstallIntent(context, file));
}
/**
@ -464,11 +451,18 @@ public class AndroidUtils {
/**
* 获取安装应用的Intent
*/
public static Intent getInstallIntent(File file) {
public static Intent getInstallIntent(Context context, File file) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri =
FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", file);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
return intent;
}
@ -518,22 +512,6 @@ public class AndroidUtils {
return context.getResources().getDisplayMetrics();
}
/**
* 获取电话号码
*/
public static String getLocalPhoneNumber(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_SMS)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_NUMBERS)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
String line1Number = getTelephonyManager(context).getLine1Number();
return line1Number == null ? "" : line1Number;
}
return null;
}
/**
* 获取设备型号(Nexus5)
*/

@ -93,7 +93,8 @@ public class AppUtils {
public static String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (NameNotFoundException e) {
@ -110,7 +111,8 @@ public class AppUtils {
public static String getVersionName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
return packageInfo.versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();

@ -9,7 +9,7 @@ import android.util.TypedValue;
*/
public class DensityUtils {
private DensityUtils() {
/* cannot be instantiated */
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
@ -26,16 +26,16 @@ public class DensityUtils {
* dp转px
*/
public static int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
context.getResources().getDisplayMetrics());
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
/**
* sp转px
*/
public static int sp2px(Context context, float spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,
context.getResources().getDisplayMetrics());
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, context.getResources().getDisplayMetrics());
}
/**

@ -40,7 +40,8 @@ public class DrawableUtil {
float scaleWidth = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidth, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,
matrix, true);
return new BitmapDrawable(null, newbmp);
}
@ -50,9 +51,9 @@ public class DrawableUtil {
public static Bitmap drawableToBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);

@ -1,17 +1,19 @@
package com.arialyy.frame.util;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.arialyy.frame.util.show.FL;
import com.arialyy.frame.util.show.L;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
@ -29,6 +31,8 @@ import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -40,11 +44,22 @@ public class FileUtil {
private static final String MB = "MB";
private static final String GB = "GB";
private FileUtil() {
}
private static final String TAG = "FileUtil";
//android获取一个用于打开HTML文件的intent
public static Intent getHtmlFileIntent(String Path) {
File file = new File(Path);
Uri uri = Uri.parse(file.toString())
.buildUpon()
.encodedAuthority("com.android.htmlfileprovider")
.scheme("content")
.encodedPath(file.toString())
.build();
Intent intent = new Intent("android.intent.action.VIEW");
intent.setDataAndType(uri, "text/html");
return intent;
}
/**
* 获取文件夹大小
*/
@ -465,8 +480,8 @@ public class FileUtil {
if (dir.isDirectory()) {
String[] children = dir.list();
// 递归删除目录中的子目录下
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
for (String aChildren : children) {
boolean success = deleteDir(new File(dir, aChildren));
if (!success) {
return false;
}

@ -17,10 +17,11 @@ public class KeyBoardUtils {
* @param mContext 上下文
*/
public static void openKeybord(EditText mEditText, Context mContext) {
InputMethodManager imm =
(InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm = (InputMethodManager) mContext
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY);
}
/**
@ -30,8 +31,8 @@ public class KeyBoardUtils {
* @param mContext 上下文
*/
public static void closeKeybord(EditText mEditText, Context mContext) {
InputMethodManager imm =
(InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm = (InputMethodManager) mContext
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
}

@ -0,0 +1,83 @@
package com.arialyy.frame.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import java.io.IOException;
import java.util.Formatter;
import java.util.Locale;
/**
* Created by Aria.Lao on 2018/1/4.
* 多媒体工具
*/
public class MediaUtil {
private MediaUtil() {
throw new AssertionError();
}
/**
* 获取音频视频播放长度
*/
public static long getDuration(String path) {
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(path);
} catch (IOException e) {
e.printStackTrace();
return -1;
}
int duration = mediaPlayer.getDuration();
mediaPlayer.release();
return duration;
}
/**
* 格式化视频时间
*/
public static String convertViewTime(long timeMs) {
int totalSeconds = (int) (timeMs / 1000);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
StringBuilder sFormatBuilder = new StringBuilder();
Formatter sFormatter = new Formatter(sFormatBuilder, Locale.getDefault());
sFormatBuilder.setLength(0);
if (hours > 0) {
return sFormatter.format("%02d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return sFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
/**
* 获取音频封面
*/
public static Bitmap getArtwork(Context context, String url) {
Uri selectedAudio = Uri.parse(url);
MediaMetadataRetriever myRetriever = new MediaMetadataRetriever();
myRetriever.setDataSource(context, selectedAudio); // the URI of audio file
byte[] artwork;
artwork = myRetriever.getEmbeddedPicture();
if (artwork != null) {
return BitmapFactory.decodeByteArray(artwork, 0, artwork.length);
}
return null;
}
public static byte[] getArtworkAsByte(Context context, String url) {
Uri selectedAudio = Uri.parse(url);
MediaMetadataRetriever myRetriever = new MediaMetadataRetriever();
myRetriever.setDataSource(context, selectedAudio); // the URI of audio file
byte[] artwork;
artwork = myRetriever.getEmbeddedPicture();
if (artwork != null) {
return artwork;
}
return null;
}
}

@ -36,7 +36,7 @@ public class NetUtils {
public static final int NETWORK_TYPE_WIFI = 4;
private NetUtils() {
/* cannot be instantiated */
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
@ -75,8 +75,9 @@ public class NetUtils {
netWorkType = NETWORK_TYPE_WIFI;
} else if (type.equalsIgnoreCase("MOBILE")) {
String proxyHost = android.net.Proxy.getDefaultHost();
netWorkType = TextUtils.isEmpty(proxyHost) ? (isFastMobileNetwork(context) ? NETWORK_TYPE_3G
: NETWORK_TYPE_2G) : NETWORK_TYPE_WAP;
netWorkType = TextUtils.isEmpty(proxyHost)
? (isFastMobileNetwork(context) ? NETWORK_TYPE_3G : NETWORK_TYPE_2G)
: NETWORK_TYPE_WAP;
}
} else {
netWorkType = NETWORK_TYPE_INVALID;

@ -13,8 +13,9 @@ public class RegularExpression {
/**
* 视频
*/
public static String VIDEO = "^(.*)\\.(mpeg-4|h.264|h.265|rmvb|xvid|vp6|h.263|mpeg-1|mpeg-2|avi|"
+ "mov|mkv|flv|3gp|3g2|asf|wmv|mp4|m4v|tp|ts|mtp|m2t)$";
public static String VIDEO =
"^(.*)\\.(mpeg-4|h.264|h.265|rmvb|xvid|vp6|h.263|mpeg-1|mpeg-2|avi|" +
"mov|mkv|flv|3gp|3g2|asf|wmv|mp4|m4v|tp|ts|mtp|m2t)$";
/**
* 音频
*/

@ -44,7 +44,8 @@ public class ScreenUtil {
*
* @param greyScale true:灰度
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB) public void setGreyScale(View v, boolean greyScale) {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setGreyScale(View v, boolean greyScale) {
if (greyScale) {
// Create a paint object with 0 saturation (black and white)
ColorMatrix cm = new ColorMatrix();
@ -63,7 +64,8 @@ public class ScreenUtil {
* 获得屏幕高度
*/
public int getScreenWidth(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
@ -73,7 +75,8 @@ public class ScreenUtil {
* 获得屏幕宽度
*/
public int getScreenHeight(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
@ -88,7 +91,8 @@ public class ScreenUtil {
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
int height = Integer.parseInt(clazz.getField("status_bar_height")
.get(object).toString());
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
@ -134,7 +138,8 @@ public class ScreenUtil {
int width = getScreenWidth(activity);
int height = getScreenHeight(activity);
Bitmap bp = null;
bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
return bp;
}
@ -145,9 +150,9 @@ public class ScreenUtil {
public boolean isAutoBrightness(ContentResolver aContentResolver) {
boolean automicBrightness = false;
try {
automicBrightness =
Settings.System.getInt(aContentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE)
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
automicBrightness = Settings.System.getInt(aContentResolver,
Settings.System.SCREEN_BRIGHTNESS_MODE)
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
@ -161,7 +166,8 @@ public class ScreenUtil {
int nowBrightnessValue = 0;
ContentResolver resolver = activity.getContentResolver();
try {
nowBrightnessValue = Settings.System.getInt(resolver, Settings.System.SCREEN_BRIGHTNESS);
nowBrightnessValue = Settings.System.getInt(
resolver, Settings.System.SCREEN_BRIGHTNESS);
} catch (Exception e) {
e.printStackTrace();
}
@ -184,7 +190,8 @@ public class ScreenUtil {
* 停止自动亮度调节
*/
public void stopAutoBrightness(Activity activity) {
Settings.System.putInt(activity.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.putInt(activity.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
@ -192,7 +199,8 @@ public class ScreenUtil {
* 开启亮度自动调节
*/
public void startAutoBrightness(Activity activity) {
Settings.System.putInt(activity.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.putInt(activity.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
}
@ -200,8 +208,10 @@ public class ScreenUtil {
* 保存亮度设置状态
*/
public void saveBrightness(ContentResolver resolver, int brightness) {
Uri uri = Settings.System.getUriFor("screen_brightness");
Settings.System.putInt(resolver, "screen_brightness", brightness);
Uri uri = Settings.System
.getUriFor("screen_brightness");
Settings.System.putInt(resolver, "screen_brightness",
brightness);
// resolver.registerContentObserver(uri, true, myContentObserver);
resolver.notifyChange(uri, null);
}

@ -170,7 +170,8 @@ public class ShellUtils {
}
}
return new CommandResult(result, successMsg == null ? null : successMsg.toString(),
errorMsg == null ? null : errorMsg.toString());
errorMsg == null ? null
: errorMsg.toString());
}
/**

@ -276,7 +276,7 @@ public class StringUtil {
public static double strToDouble(String str) {
// double d = Double.parseDouble(str);
/* 以下代码处理精度问题 */
/* 以下代码处理精度问题 */
BigDecimal bDeci = new BigDecimal(str);
// BigDecimal chushu =new BigDecimal(100000000);
// BigDecimal result =bDeci.divide(chushu,new

@ -1,23 +1,26 @@
package com.arialyy.frame.util.show;
import android.util.Log;
import com.arialyy.frame.util.CalendarUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
/**
* Created by AriaLyy@outlook.com on 2015/4/1.
* Created by Lyy on 2015/4/1.
* 写入文件的log由于使用到反射和文件流的操作建议在需要的地方才去使用
*/
public class FL {
public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化
public static String PATH = "/GameBar2/log/AriaFrameLog__"; //log路径
static String LINE_SEPARATOR = System.getProperty("line.separator"); //等价于"\n\r",唯一的作用是能装逼
static int JSON_INDENT = 4;
public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化
public static String NAME = "AriaFrame"; //log路径
private static String printLine(String tag, boolean isTop) {
String top =
@ -53,15 +56,16 @@ public class FL {
message = jsonStr;
}
writeLogToFile(tag, printLine(tag, true));
message = LINE_SEPARATOR + message;
String temp = "\n" + printLine(tag, true) + "\n";
String temp = "";
String[] lines = message.split(LINE_SEPARATOR);
for (String line : lines) {
temp += "║ " + line + "\n";
temp += "║ " + line;
Log.d(tag, "║ " + line);
}
temp += printLine(tag, false);
writeLogToFile(tag, temp);
writeLogToFile(tag, printLine(tag, false));
}
}
@ -141,8 +145,8 @@ public class FL {
* 返回日志路径
*/
public static String getLogPath() {
String path = PATH + CalendarUtils.getData() + ".txt";
return android.os.Environment.getExternalStorageDirectory().getPath() + File.separator + path;
String name = NAME + "_" + CalendarUtils.getData() + ".log";
return android.os.Environment.getExternalStorageDirectory().getPath() + File.separator + name;
}
/**

@ -32,7 +32,7 @@ public class L {
static int JSON_INDENT = 4;
private L() {
/* cannot be instantiated */
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
@ -108,73 +108,99 @@ public class L {
// 下面四个是默认tag的函数
public static void i(String... msg) {
if (isDebug) printLog(I, msg);
if (isDebug) {
printLog(I, msg);
}
}
public static void d(String... msg) {
if (isDebug) printLog(D, msg);
if (isDebug) {
printLog(D, msg);
}
}
public static void w(String... msg) {
if (isDebug) printLog(W, msg);
if (isDebug) {
printLog(W, msg);
}
}
public static void e(String... msg) {
if (isDebug) printLog(E, msg);
}
public static void e(Throwable tr) {
if (isDebug) printLog(E, FL.getExceptionString(tr));
if (isDebug) {
printLog(E, msg);
}
}
public static void v(String... msg) {
if (isDebug) printLog(V, msg);
if (isDebug) {
printLog(V, msg);
}
}
// 下面是传入自定义tag的函数
public static void i(String tag, String msg) {
if (isDebug) Log.i(tag, msg);
if (isDebug) {
Log.i(tag, msg);
}
}
public static void d(String tag, String msg) {
if (isDebug) Log.d(tag, msg);
if (isDebug) {
Log.d(tag, msg);
}
}
public static void w(String tag, String msg) {
if (isDebug) Log.w(tag, msg);
if (isDebug) {
Log.w(tag, msg);
}
}
public static void e(String tag, String msg) {
if (isDebug) Log.e(tag, msg);
if (isDebug) {
Log.e(tag, msg);
}
}
public static void v(String tag, String msg) {
if (isDebug) Log.v(tag, msg);
if (isDebug) {
Log.v(tag, msg);
}
}
//带异常的
public static void i(String tag, String msg, Throwable tr) {
if (isDebug) Log.i(tag, msg, tr);
if (isDebug) {
Log.i(tag, msg, tr);
}
}
public static void d(String tag, String msg, Throwable tr) {
if (isDebug) Log.d(tag, msg, tr);
if (isDebug) {
Log.d(tag, msg, tr);
}
}
public static void w(String tag, String msg, Throwable tr) {
if (isDebug) Log.w(tag, msg, tr);
if (isDebug) {
Log.w(tag, msg, tr);
}
}
public static void e(String tag, String msg, Throwable tr) {
if (isDebug) Log.e(tag, msg, tr);
if (isDebug) {
Log.e(tag, msg, tr);
}
}
public static void v(String tag, String msg, Throwable tr) {
if (isDebug) Log.v(tag, msg, tr);
if (isDebug) {
Log.v(tag, msg, tr);
}
}
/**
* 统一打印
* 同意打印
*/
private static void printHunk(char type, String str) {
switch (type) {

@ -22,41 +22,53 @@ public class T {
* 短时间显示Toast
*/
public static void showShort(Context context, CharSequence message) {
if (isShow) Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
if (isShow) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
/**
* 短时间显示Toast
*/
public static void showShort(Context context, int message) {
if (isShow) Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
if (isShow) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
/**
* 长时间显示Toast
*/
public static void showLong(Context context, CharSequence message) {
if (isShow) Toast.makeText(context, message, Toast.LENGTH_LONG).show();
if (isShow) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
/**
* 长时间显示Toast
*/
public static void showLong(Context context, int message) {
if (isShow) Toast.makeText(context, message, Toast.LENGTH_LONG).show();
if (isShow) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
/**
* 自定义显示Toast时间
*/
public static void show(Context context, CharSequence message, int duration) {
if (isShow) Toast.makeText(context, message, duration).show();
if (isShow) {
Toast.makeText(context, message, duration).show();
}
}
/**
* 自定义显示Toast时间
*/
public static void show(Context context, int message, int duration) {
if (isShow) Toast.makeText(context, message, duration).show();
if (isShow) {
Toast.makeText(context, message, duration).show();
}
}
}

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#005bab"/>
<corners android:radius="30dp"/>
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="#095389"/>
<corners android:radius="30dp"/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#005bab"/>
<corners android:radius="30dp"/>
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="#095389"/>
<corners android:radius="30dp"/>
</shape>
</item>
</selector>

@ -15,8 +15,8 @@
<ProgressBar
android:id="@+id/pb"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:visibility="gone"
/>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="background_color">#E5E5E5</color>
<color name="white">#fff</color>
<color name="text_gray_color">#A5A5A5</color>
<color name="background_color">#E5E5E5</color>
<color name="white">#fff</color>
<color name="bg_line">#757575</color>
</resources>

@ -1,3 +1,3 @@
<resources>
<string name="app_name">Frame</string>
<string name="app_name">Frame</string>
</resources>

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<!-- Customize your theme here. -->
</style>
<!-- <item name="android:windowBackground">@drawable/white_pop_normal_background</item>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<!-- Customize your theme here. -->
</style>
<!-- <item name="android:windowBackground">@drawable/white_pop_normal_background</item>
-->
<style name="MyDialog" parent="AppTheme">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="MyDialog" parent="AppTheme">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
</resources>

@ -99,10 +99,18 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
this.groupHash = groupHash;
}
/**
* 后面会删除该方法请使用{@link #getFilePath()}
*/
@Deprecated
public String getDownloadPath() {
return downloadPath;
}
public String getFilePath() {
return downloadPath;
}
public DownloadEntity setDownloadPath(String downloadPath) {
this.downloadPath = downloadPath;
return this;

@ -39,7 +39,7 @@ import java.lang.annotation.Target;
/**
* "@Download.onPre"注解下载队列已经满了继续创建新任务将会回调该方法
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onWait{
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onWait {
String[] value() default { AriaConstance.NO_URL };
}
@ -108,9 +108,11 @@ import java.lang.annotation.Target;
/**
* "@Download.onNoSupportBreakPoint"注解如果该任务不支持断点Aria会调用该方法
*
* @deprecated 该注解将在后续版本删除
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD)
@interface onNoSupportBreakPoint {
@Deprecated
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onNoSupportBreakPoint {
String[] value() default { AriaConstance.NO_URL };
}
}

@ -71,7 +71,7 @@ __注意:3.5.4以下版本升级时,需要更新[配置文件]!!(https:/
```java
Aria.download(this)
.load(DOWNLOAD_URL) //读取下载地址
.setDownloadPath(DOWNLOAD_PATH) //设置文件保存的完整路径
.setFilePath(DOWNLOAD_PATH) //设置文件保存的完整路径
.start(); //启动下载
```

@ -44,8 +44,9 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
testImplementation 'junit:junit:4.12'
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}"
implementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.kotlin_version}"
api project(':Aria')
kapt project(':AriaCompiler')
@ -58,7 +59,7 @@ dependencies {
implementation project(':AppFrame')
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.pddstudio:highlightjs-android:1.5.0'
}
repositories {
mavenCentral()

@ -42,6 +42,11 @@
<activity android:name=".core.upload.HttpUploadActivity"/>
<activity android:name=".core.upload.FtpUploadActivity"/>
<activity android:name=".core.download.KotlinDownloadActivity"/>
<activity
android:name=".core.FullScreenCodeActivity"
android:theme="@style/FullScreen"
android:screenOrientation="landscape"
android:windowSoftInputMode="stateHidden|adjustResize"/>
<service android:name=".core.download.service_download.DownloadService"/>

@ -0,0 +1,90 @@
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityTestBinding;
import java.io.File;
/**
* Created by lyy on 2019/5/28.
* Ftp 下载
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
*/
public class FtpDownload extends BaseActivity<ActivityTestBinding> {
String TAG = "TestFTPActivity";
private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar";
@Override protected int setLayoutId() {
return R.layout.activity_test;
}
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
mBar.setVisibility(View.GONE);
Aria.download(this).register();
}
@Download.onWait void onWait(DownloadTask task) {
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
}
@Download.onPre protected void onPre(DownloadTask task) {
Log.d(TAG, "onPre");
}
@Download.onTaskStart void taskStart(DownloadTask task) {
Log.d(TAG, "onStart");
}
@Download.onTaskRunning protected void running(DownloadTask task) {
Log.d(TAG, "running,speed=" + task.getConvertSpeed());
}
@Download.onTaskResume void taskResume(DownloadTask task) {
Log.d(TAG, "resume");
}
@Download.onTaskStop void taskStop(DownloadTask task) {
Log.d(TAG, "stop");
}
@Download.onTaskCancel void taskCancel(DownloadTask task) {
Log.d(TAG, "cancel");
}
@Download.onTaskFail void taskFail(DownloadTask task) {
Log.d(TAG, "fail");
}
@Download.onTaskComplete void taskComplete(DownloadTask task) {
Log.d(TAG, "complete, md5 => " + CommonUtil.getFileMD5(new File(task.getKey())));
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.download(this)
.loadFtp(URL)
.setFilePath(FILE_PATH)
.login("lao", "123456")
//.asFtps() // ftps 配置
//.setStorePath("/mnt/sdcard/Download/server.crt") //设置证书路径
// .setAlias("www.laoyuyu.me") // 设置证书别名
.start();
break;
case R.id.stop:
Aria.download(this).loadFtp(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.download(this).loadFtp(FILE_PATH).cancel();
break;
}
}
}

@ -0,0 +1,127 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.ftp.FtpInterceptHandler;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import java.io.File;
import java.util.List;
/**
* Created by lyy on 2019/5/28. Ftp 文件上传demo
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
*/
public class FtpUpload extends Activity {
private static final String TAG = "FtpUpload";
private String mFilePath = Environment.getExternalStorageDirectory().getPath() + "/AriaPrj.rar";
private String mUrl = "ftp://172.168.1.2:2121/aa/你好";
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Aria.upload(this).register();
// 读取历史记录信息
UploadEntity entity = Aria.upload(this).getUploadEntity(mFilePath);
if (entity != null) {
// 设置界面的进度、文件大小等信息
}
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (Aria.upload(this).load(mFilePath).isRunning()) {
Aria.upload(this).loadFtp(mFilePath).stop(); // 停止任务
} else {
Aria.upload(this)
.loadFtp(mFilePath) // 需要上传的文件
.setUploadUrl(mUrl) // 服务器地址
// 如果ftp服务器端有同名文件,可通过拦截器处理是覆盖服务器端文件,还是修改文件名
.setUploadInterceptor(
new IFtpUploadInterceptor() {
@Override
public FtpInterceptHandler onIntercept(UploadEntity entity,
List<String> fileList) {
FtpInterceptHandler.Builder builder = new FtpInterceptHandler.Builder();
//builder.coverServerFile();
builder.resetFileName("test.zip");
return builder.build();
}
})
.login("N0rI", "0qcK")
.start();
}
break;
case R.id.cancel:
Aria.upload(this).loadFtp(mFilePath).cancel();
break;
}
}
@Upload.onWait void onWait(UploadTask task) {
Log.d(TAG, task.getTaskName() + "_wait");
}
@Upload.onPre public void onPre(UploadTask task) {
setFileSize(task.getConvertFileSize());
}
@Upload.onTaskStart public void taskStart(UploadTask task) {
Log.d(TAG, "开始上传,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
}
@Upload.onTaskResume public void taskResume(UploadTask task) {
Log.d(TAG, "恢复上传");
}
@Upload.onTaskStop public void taskStop(UploadTask task) {
setSpeed("");
Log.d(TAG, "停止上传");
}
@Upload.onTaskCancel public void taskCancel(UploadTask task) {
setSpeed("");
setFileSize("");
setProgress(0);
Log.d(TAG, "删除任务");
}
@Upload.onTaskFail public void taskFail(UploadTask task) {
Log.d(TAG, "上传失败");
}
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
Log.d(TAG, "PP = " + task.getPercent());
setProgress(task.getPercent());
setSpeed(task.getConvertSpeed());
}
@Upload.onTaskComplete public void taskComplete(UploadTask task) {
setProgress(100);
setSpeed("");
T.showShort(this, "文件:" + task.getEntity().getFileName() + ",上传完成");
}
}

@ -0,0 +1,119 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.core.upload;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.ftp.FtpInterceptHandler;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import java.io.File;
import java.util.List;
/**
* Created by lyy on 2017/7/28. HTTP 文件下载demo
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
*/
public class FtpUpload extends Activity {
private static final String TAG = "FtpUpload";
private String mFilePath = Environment.getExternalStorageDirectory().getPath() + "/test.apk";
private String mUrl = "http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Aria.download(this).register();
// 读取历史记录信息
DownloadEntity entity = Aria.download(this).getDownloadEntity(mFilePath);
if (entity != null) {
// 设置界面的进度、文件大小等信息
}
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (Aria.download(this).load(mUrl).isRunning()) {
Aria.download(this).load(mUrl).stop(); // 停止任务
} else {
Aria.download(this)
.load(mUrl) // 下载url
.setFilePath(mFilePath) // 文件保存路径
//.addHeader(key, value) // 添加头
//.asPost() //或 asGet()
//.setParam() // 设置参数
.start();
}
break;
case R.id.cancel:
Aria.download(this).load(mUrl).cancel();
break;
}
}
@Download.onWait void onWait(DownloadTask task) {
Log.d(TAG, task.getTaskName() + "_wait");
}
@Download.onPre public void onPre(DownloadTask task) {
setFileSize(task.getConvertFileSize());
}
@Download.onTaskStart public void taskStart(DownloadTask task) {
Log.d(TAG, "开始下载,md5:" + FileUtil.getFileMD5(new File(task.getEntity().getFilePath())));
}
@Download.onTaskResume public void taskResume(DownloadTask task) {
Log.d(TAG, "恢复下载");
}
@Download.onTaskStop public void taskStop(DownloadTask task) {
setSpeed("");
Log.d(TAG, "停止下载");
}
@Download.onTaskCancel public void taskCancel(DownloadTask task) {
setSpeed("");
setFileSize("");
setProgress(0);
Log.d(TAG, "删除任务");
}
@Download.onTaskFail public void taskFail(DownloadTask task) {
Log.d(TAG, "下载失败");
}
@Download.onTaskRunning public void taskRunning(DownloadTask task) {
Log.d(TAG, "PP = " + task.getPercent());
setProgress(task.getPercent());
setSpeed(task.getConvertSpeed());
}
@Download.onTaskComplete public void taskComplete(DownloadTask task) {
setProgress(100);
setSpeed("");
T.showShort(this, "文件:" + task.getEntity().getFileName() + ",下载完成");
}
}

@ -0,0 +1,170 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.Toast
import com.arialyy.annotations.Download
import com.arialyy.aria.core.Aria
import com.arialyy.aria.core.download.DownloadTarget
import com.arialyy.aria.core.download.DownloadTask
import com.arialyy.aria.core.inf.IEntity
import com.arialyy.simple.R
import com.arialyy.simple.base.BaseActivity
import com.arialyy.simple.databinding.ActivitySingleBinding
/**
* Created by lyy on 2017/10/23.
*/
class KotlinDownloadActivity : BaseActivity<ActivitySingleBinding>() {
private val DOWNLOAD_URL =
"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"
private lateinit var mStart: Button
private lateinit var mStop: Button
private lateinit var mCancel: Button
private lateinit var target: DownloadTarget
override fun setLayoutId(): Int {
return R.layout.activity_single
}
override fun init(savedInstanceState: Bundle?) {
title = "kotlin测试"
Aria.get(this)
.downloadConfig.maxTaskNum = 2
Aria.download(this)
.register()
mStart = findViewById(R.id.start)
mStop = findViewById(R.id.stop)
mCancel = findViewById(R.id.cancel)
mStop.visibility = View.GONE
target = Aria.download(this)
.load(DOWNLOAD_URL)
binding.progress = target.percent
if (target.taskState == IEntity.STATE_STOP) {
mStart.text = "恢复"
} else if (target.isRunning) {
mStart.text = "停止"
}
binding.fileSize = target.convertFileSize
}
/**
* 注解方法不能添加internal修饰符否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: index 1 for '$a' not in range (received 0 arguments)错误
*/
@Download.onTaskRunning
fun running(task: DownloadTask) {
Log.d(TAG, task.percent.toString())
val len = task.fileSize
if (len == 0L) {
binding.progress = 0
} else {
binding.progress = task.percent
}
binding.speed = task.convertSpeed
}
@Download.onWait
fun onWait(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
Log.d(TAG, "wait ==> " + task.downloadEntity.fileName)
}
}
@Download.onPre
fun onPre(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
mStart.text = "停止"
}
}
@Download.onTaskStart
fun taskStart(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
binding.fileSize = task.convertFileSize
}
}
@Download.onTaskComplete
fun complete(task: DownloadTask) {
Log.d(TAG, "完成")
}
@Download.onTaskResume
fun taskResume(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
mStart.text = "停止"
}
}
@Download.onTaskStop
fun taskStop(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
mStart.text = "恢复"
binding.speed = ""
}
}
@Download.onTaskCancel
fun taskCancel(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
binding.progress = 0
Toast.makeText(this@KotlinDownloadActivity, "取消下载", Toast.LENGTH_SHORT)
.show()
mStart.text = "开始"
binding.speed = ""
Log.d(TAG, "cancel")
}
}
@Download.onTaskFail
fun taskFail(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
Toast.makeText(this@KotlinDownloadActivity, "下载失败", Toast.LENGTH_SHORT)
.show()
mStart.text = "开始"
}
}
fun onClick(view: View) {
when (view.id) {
R.id.start -> {
if (target.isRunning) {
Aria.download(this)
.load(DOWNLOAD_URL)
.stop()
} else {
startD()
}
}
R.id.stop -> Aria.download(this).load(DOWNLOAD_URL).stop()
R.id.cancel -> Aria.download(this).load(DOWNLOAD_URL).cancel()
}
}
private fun startD() {
Aria.download(this)
.load(DOWNLOAD_URL)
.addHeader("groupHash", "value")
.setFilePath(Environment.getExternalStorageDirectory().path + "/kotlin.apk")
.start()
}
}

@ -43,9 +43,11 @@ public abstract class BaseActivity<VB extends ViewDataBinding> extends AbsActivi
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
mBar = findViewById(R.id.toolbar);
setSupportActionBar(mBar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mBar.setOnMenuItemClickListener(this);
if (mBar != null) {
setSupportActionBar(mBar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mBar.setOnMenuItemClickListener(this);
}
}
protected void setTile(String title) {

@ -23,7 +23,6 @@ import android.os.StrictMode;
import com.arialyy.aria.core.Aria;
import com.arialyy.frame.core.AbsFrame;
import com.arialyy.simple.BuildConfig;
import com.arialyy.simple.common.ConnectionChangeReceiver;
//import com.squareup.leakcanary.LeakCanary;
/**
@ -46,15 +45,15 @@ public class BaseApplication extends Application {
StrictMode.setThreadPolicy(
new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
//if (LeakCanary.isInAnalyzerProcess(this)) {//1
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
//return;
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
//return;
//}
//LeakCanary.install(this);
}
}
//registerReceiver(new ConnectionChangeReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
//registerReceiver(new ConnectionChangeReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
public static BaseApplication getApp() {
return INSTANCE;

@ -0,0 +1,58 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.common;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.text.TextUtils;
import com.arialyy.aria.util.ALog;
import com.arialyy.frame.base.BaseViewModule;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class DialogModule extends BaseViewModule {
private MutableLiveData<List<File>> mDirs = new MutableLiveData<>();
/**
* 获取指定目录下的文件夹
*
* @param path 指定路径
*/
LiveData<List<File>> getDirs(String path) {
if (TextUtils.isEmpty(path)) {
ALog.e(TAG, "路径为空");
return mDirs;
}
if (!path.startsWith("/")) {
ALog.e(TAG, "路径错误");
return mDirs;
}
File file = new File(path);
File[] files = file.listFiles();
List<File> data = new ArrayList<>();
for (File f : files) {
if (f.isDirectory()) {
data.add(f);
}
}
mDirs.postValue(data);
return mDirs;
}
}

@ -0,0 +1,177 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.common;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;
import com.arialyy.aria.util.ALog;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseDialog;
import com.arialyy.simple.base.adapter.AbsHolder;
import com.arialyy.simple.base.adapter.AbsRVAdapter;
import com.arialyy.simple.base.adapter.RvItemClickSupport;
import com.arialyy.simple.databinding.DialogChooseDirBinding;
import com.arialyy.simple.databinding.DialogMsgBinding;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Created by AriaL on 2019/5/28.
*/
@SuppressLint("ValidFragment") public class DirChooseDialog
extends BaseDialog<DialogChooseDirBinding> {
public static final int DIR_CHOOSE_DIALOG_RESULT = 0xB2;
private String mCurrentPath = Environment.getExternalStorageDirectory().getPath();
private List<File> mData = new ArrayList<>();
private DialogModule mModule;
public DirChooseDialog(Object obj) {
super(obj);
}
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
getBinding().list.setLayoutManager(new LinearLayoutManager(getContext()));
getBinding().list.addItemDecoration(
new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
final Adapter adapter = new Adapter(getContext(), mData);
getBinding().list.setAdapter(adapter);
getBinding().setCurrentPath(mCurrentPath);
mModule = ViewModelProviders.of(this).get(DialogModule.class);
mModule.getDirs(mCurrentPath).observe(this, new Observer<List<File>>() {
@Override public void onChanged(@Nullable List<File> files) {
mData.clear();
if (files != null && !files.isEmpty()) {
mData.addAll(files);
}
adapter.notifyDataSetChanged();
if (mCurrentPath.equals(Environment.getExternalStorageDirectory().getPath())) {
getBinding().up.setVisibility(View.GONE);
}
getBinding().setCurrentPath(mCurrentPath);
getBinding().currentPath.setSelected(true);
}
});
getBinding().up.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
up();
}
});
getBinding().enter.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
getSimplerModule().onDialog(DIR_CHOOSE_DIALOG_RESULT, mCurrentPath);
dismiss();
}
});
RvItemClickSupport.addTo(getBinding().list).setOnItemClickListener(
new RvItemClickSupport.OnItemClickListener() {
@Override public void onItemClicked(RecyclerView recyclerView, int position, View v) {
getBinding().up.setVisibility(View.VISIBLE);
mCurrentPath = mCurrentPath.concat("/").concat(mData.get(position).getName());
mModule.getDirs(mCurrentPath);
}
});
}
private void up() {
int endIndex = mCurrentPath.lastIndexOf("/");
mCurrentPath = mCurrentPath.substring(0, endIndex);
mModule.getDirs(mCurrentPath);
}
@Override public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
dialog.getWindow()
.setLayout((dm.widthPixels), ViewGroup.LayoutParams.WRAP_CONTENT);
// 拦截返回键
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
if (mCurrentPath.equals(Environment.getExternalStorageDirectory().getPath())) {
dismiss();
} else {
up();
}
return true;
}
return false;
}
});
}
}
@Override protected int setLayoutId() {
return R.layout.dialog_choose_dir;
}
/**
* 适配器
*/
private class Adapter extends AbsRVAdapter<File, Adapter.Holder> {
Adapter(Context context, List<File> data) {
super(context, data);
}
@Override protected Holder getViewHolder(View convertView, int viewType) {
return new Holder(convertView);
}
@Override protected int setLayoutId(int type) {
return R.layout.item_choose_dir;
}
@Override protected void bindData(Holder holder, int position, File item) {
holder.text.setSelected(true);
holder.text.setText(item.getName());
}
private class Holder extends AbsHolder {
private TextView text;
Holder(View itemView) {
super(itemView);
text = findViewById(R.id.text);
}
}
}
}

@ -0,0 +1,93 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.common;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseDialog;
import com.arialyy.simple.databinding.DialogModifyPathBinding;
import com.arialyy.simple.databinding.DialogMsgBinding;
import java.io.File;
/**
* Created by AriaL on 2019/5/28.
* 修改文件路径
*/
@SuppressLint("ValidFragment") public class ModifyPathDialog
extends BaseDialog<DialogModifyPathBinding> {
public static final int MODIFY_PATH_RESULT = 0xB3;
private String mTitle, mFilePath, mDir;
public ModifyPathDialog(Object obj, String title, String filePath) {
super(obj);
mTitle = title;
mFilePath = filePath;
}
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
getBinding().setTitle(mTitle);
getBinding().setViewModel(this);
final File temp = new File(mFilePath);
mDir = temp.getParent();
getBinding().setDir(mDir);
getBinding().setName(temp.getName());
getBinding().edit.post(new Runnable() {
@Override public void run() {
getBinding().edit.setSelection(temp.getName().length());
}
});
getBinding().enter.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
if (TextUtils.isEmpty(getBinding().getName())) {
Toast.makeText(getContext(), getString(R.string.error_file_name_null), Toast.LENGTH_SHORT)
.show();
return;
}
mFilePath = mDir + "/" + getBinding().getName();
getSimplerModule().onDialog(MODIFY_PATH_RESULT, mFilePath);
dismiss();
}
});
getBinding().cancel.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
dismiss();
}
});
}
public void chooseDir() {
DirChooseDialog dirChooseDialog = new DirChooseDialog(this);
dirChooseDialog.show(getChildFragmentManager(), "DirChooseDialog");
}
@Override protected int setLayoutId() {
return R.layout.dialog_modify_path;
}
@Override protected void dataCallback(int result, Object data) {
super.dataCallback(result, data);
if (result == DirChooseDialog.DIR_CHOOSE_DIALOG_RESULT) {
mDir = String.valueOf(data);
getBinding().setDir(mDir);
}
}
}

@ -23,7 +23,7 @@ import com.arialyy.simple.base.BaseDialog;
import com.arialyy.simple.databinding.DialogModifyUrlBinding;
/**
* Created by AriaL on 2017/6/3.
* Created by AriaL on 2019/5/27.
*/
@SuppressLint("ValidFragment") public class ModifyUrlDialog
extends BaseDialog<DialogModifyUrlBinding> {
@ -48,7 +48,9 @@ import com.arialyy.simple.databinding.DialogModifyUrlBinding;
});
getBinding().enter.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
mText = getBinding().getText();
getSimplerModule().onDialog(MODIFY_URL_DIALOG_RESULT, mText);
dismiss();
}
});
getBinding().edit.post(new Runnable() {

@ -0,0 +1,68 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.core;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Window;
import android.view.WindowManager;
import com.arialyy.aria.util.ALog;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityFullScreenCodeBinding;
import com.pddstudio.highlightjs.models.Language;
import com.pddstudio.highlightjs.models.Theme;
import java.io.File;
/**
* 全是显示代码的actiivty
*/
public class FullScreenCodeActivity extends BaseActivity<ActivityFullScreenCodeBinding> {
private static final String TAG = "FullScreenCodeActivity";
public static final String KEY_FILE_PATH = "KEY_FILE_PATH";
@Override protected int setLayoutId() {
return R.layout.activity_full_screen_code;
}
@Override protected void onCreate(Bundle savedInstanceState) {
//去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
//去除状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
}
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
String filePath = getIntent().getStringExtra(KEY_FILE_PATH);
if (TextUtils.isEmpty(filePath)) {
ALog.e(TAG, "代码的文件路径为空");
finish();
return;
}
getBinding().codeView.setZoomSupportEnabled(true);
getBinding().codeView.setHighlightLanguage(Language.JAVA);
getBinding().codeView.setTheme(Theme.ANDROID_STUDIO);
getBinding().codeView.setSource(new File(filePath));
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}

@ -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;
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 DownloadModule1 extends BaseViewModule {
private final String DOWNLOAD_URL_KEY = "DOWNLOAD_URL_KEY";
private final String DOWNLOAD_PATH_KEY = "DOWNLOAD_PATH_KEY";
private final String defUrl =
"http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
private final String defFilePath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
private DownloadEntity singDownloadInfo;
/**
* 单任务下载的信息
*/
LiveData<DownloadEntity> getSingDownloadInfo(Context context) {
String url = AppUtil.getConfigValue(context, DOWNLOAD_URL_KEY, defUrl);
String filePath = AppUtil.getConfigValue(context, DOWNLOAD_PATH_KEY, defFilePath);
singDownloadInfo = Aria.download(context).getDownloadEntity(url);
if (singDownloadInfo == null) {
singDownloadInfo = new DownloadEntity();
singDownloadInfo.setUrl(url);
File temp = new File(defFilePath);
singDownloadInfo.setDownloadPath(filePath);
singDownloadInfo.setFileName(temp.getName());
} else {
AppUtil.setConfigValue(context, DOWNLOAD_PATH_KEY, singDownloadInfo.getDownloadPath());
AppUtil.setConfigValue(context, DOWNLOAD_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, DOWNLOAD_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, DOWNLOAD_URL_KEY, url);
singDownloadInfo.setUrl(url);
liveData.postValue(singDownloadInfo);
}
}

@ -1,166 +1,317 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.core.download
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.Toast
import com.arialyy.annotations.Download
import com.arialyy.aria.core.Aria
import com.arialyy.aria.core.download.DownloadEntity
import com.arialyy.aria.core.download.DownloadTarget
import com.arialyy.aria.core.download.DownloadTask
import com.arialyy.aria.core.inf.IEntity
import com.arialyy.aria.core.inf.IHttpFileLenAdapter
import com.arialyy.aria.core.scheduler.ISchedulers
import com.arialyy.aria.util.ALog
import com.arialyy.aria.util.CommonUtil
import com.arialyy.frame.util.show.T
import com.arialyy.simple.R
import com.arialyy.simple.base.BaseActivity
import com.arialyy.simple.databinding.ActivitySingleBinding
import com.arialyy.simple.common.ModifyPathDialog
import com.arialyy.simple.common.ModifyUrlDialog
import com.arialyy.simple.databinding.ActivitySingleKotlinBinding
import com.arialyy.simple.util.AppUtil
import com.pddstudio.highlightjs.models.Language
/**
* Created by lyy on 2017/10/23.
*/
class KotlinDownloadActivity : BaseActivity<ActivitySingleBinding>() {
import java.io.IOException
private val DOWNLOAD_URL =
"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"
class KotlinDownloadActivity : BaseActivity<ActivitySingleKotlinBinding>() {
private lateinit var mStart: Button
private lateinit var mStop: Button
private lateinit var mCancel: Button
private lateinit var target: DownloadTarget
private var mUrl: String? = null
private var mFilePath: String? = null
private var mModule: DownloadModule1? = null
private var mTarget: DownloadTarget? = null
override fun setLayoutId(): Int {
return R.layout.activity_single
internal var receiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
if (intent.action == ISchedulers.ARIA_TASK_INFO_ACTION) {
ALog.d(TAG, "state = " + intent.getIntExtra(ISchedulers.TASK_STATE, -1))
ALog.d(TAG, "type = " + intent.getIntExtra(ISchedulers.TASK_TYPE, -1))
ALog.d(TAG, "speed = " + intent.getLongExtra(ISchedulers.TASK_SPEED, -1))
ALog.d(TAG, "percent = " + intent.getIntExtra(ISchedulers.TASK_PERCENT, -1))
ALog.d(
TAG, "entity = " + intent.getParcelableExtra<DownloadEntity>(
ISchedulers.TASK_ENTITY
).toString()
)
}
}
}
override fun onResume() {
super.onResume()
//registerReceiver(receiver, new IntentFilter(ISchedulers.ARIA_TASK_INFO_ACTION));
}
override fun onDestroy() {
super.onDestroy()
//unregisterReceiver(receiver);
Aria.download(this)
.unRegister()
}
override fun init(savedInstanceState: Bundle?) {
title = "kotlin测试"
Aria.get(this)
.downloadConfig.maxTaskNum = 2
super.init(savedInstanceState)
title = "单任务下载"
Aria.download(this)
.register()
mStart = findViewById(R.id.start)
mStop = findViewById(R.id.stop)
mCancel = findViewById(R.id.cancel)
mStop.visibility = View.GONE
target = Aria.download(this)
.load(DOWNLOAD_URL)
binding.progress = target.percent
if (target.taskState == IEntity.STATE_STOP) {
mStart.text = "恢复"
} else if (target.isRunning) {
mStart.text = "停止"
mModule = ViewModelProviders.of(this)
.get(DownloadModule1::class.java)
mModule!!.getSingDownloadInfo(this)
.observe(this, Observer { entity ->
if (entity == null) {
return@Observer
}
mTarget = Aria.download(this)
.load(entity.url)
if (mTarget!!.taskState == IEntity.STATE_STOP) {
binding.stateStr = getString(R.string.resume)
} else if (mTarget!!.isRunning) {
binding.stateStr = getString(R.string.stop)
}
if (entity.fileSize != 0L) {
binding.fileSize = CommonUtil.formatFileSize(entity.fileSize.toDouble())
binding.progress = if (entity.isComplete)
100
else
(entity.currentProgress * 100 / entity.fileSize).toInt()
}
binding.url = entity.url
binding.filePath = entity.filePath
mUrl = entity.url
mFilePath = entity.filePath
})
binding.viewModel = this
try {
binding.codeView.setSource(AppUtil.getHelpCode(this, "KotlinHttpDownload.kt"), Language.JAVA)
} catch (e: IOException) {
e.printStackTrace()
}
binding.fileSize = target.convertFileSize
}
/**
* 注解方法不能添加internal修饰符否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: index 1 for '$a' not in range (received 0 arguments)错误
*/
@Download.onTaskRunning
fun running(task: DownloadTask) {
Log.d(TAG, task.percent.toString())
val len = task.fileSize
if (len == 0L) {
binding.progress = 0
} else {
binding.progress = task.percent
fun chooseUrl() {
val dialog = ModifyUrlDialog(this, getString(R.string.modify_url_dialog_title), mUrl)
dialog.show(supportFragmentManager, "ModifyUrlDialog")
}
fun chooseFilePath() {
val dialog = ModifyPathDialog(this, getString(R.string.modify_file_path), mFilePath)
dialog.show(supportFragmentManager, "ModifyPathDialog")
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_single_task_activity, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onMenuItemClick(item: MenuItem): Boolean {
var speed = -1
var msg = ""
when (item.itemId) {
R.id.help -> {
msg = ("一些小知识点:\n"
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据")
showMsgDialog("tip", msg)
}
R.id.speed_0 -> speed = 0
R.id.speed_128 -> speed = 128
R.id.speed_256 -> speed = 256
R.id.speed_512 -> speed = 512
R.id.speed_1m -> speed = 1024
}
if (speed > -1) {
msg = item.title.toString()
Aria.download(this)
.setMaxSpeed(speed)
T.showShort(this, msg)
}
binding.speed = task.convertSpeed
return true
}
@Download.onWait
fun onWait(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
if (task.key == mUrl) {
Log.d(TAG, "wait ==> " + task.downloadEntity.fileName)
}
}
@Download.onPre
fun onPre(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
mStart.text = "停止"
if (task.key == mUrl) {
binding.stateStr = getString(R.string.stop)
}
}
@Download.onTaskStart
fun taskStart(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
if (task.key == mUrl) {
binding.fileSize = task.convertFileSize
}
}
@Download.onTaskComplete
fun complete(task: DownloadTask) {
Log.d(TAG, "完成")
@Download.onTaskRunning
fun running(task: DownloadTask) {
if (task.key == mUrl) {
//Log.d(TAG, task.getKey());
val len = task.fileSize
if (len == 0L) {
binding.progress = 0
} else {
binding.progress = task.percent
}
binding.speed = task.convertSpeed
}
}
@Download.onTaskResume
fun taskResume(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
mStart.text = "停止"
if (task.key == mUrl) {
binding.stateStr = getString(R.string.stop)
}
}
@Download.onTaskStop
fun taskStop(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
mStart.text = "恢复"
if (task.key == mUrl) {
binding.stateStr = getString(R.string.resume)
binding.speed = ""
}
}
@Download.onTaskCancel
fun taskCancel(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
if (task.key == mUrl) {
binding.progress = 0
Toast.makeText(this@KotlinDownloadActivity, "取消下载", Toast.LENGTH_SHORT)
.show()
mStart.text = "开始"
binding.stateStr = getString(R.string.start)
binding.speed = ""
Log.d(TAG, "cancel")
}
}
/**
*
*/
@Download.onTaskFail
fun taskFail(task: DownloadTask) {
if (task.key == DOWNLOAD_URL) {
Toast.makeText(this@KotlinDownloadActivity, "下载失败", Toast.LENGTH_SHORT)
fun taskFail(
task: DownloadTask,
e: Exception
) {
if (task.key == mUrl) {
Toast.makeText(this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
.show()
mStart.text = "开始"
binding.stateStr = getString(R.string.start)
}
}
@Download.onNoSupportBreakPoint
fun onNoSupportBreakPoint(task: DownloadTask) {
Log.d(TAG, "该下载链接不支持断点")
if (task.key == DOWNLOAD_URL) {
T.showShort(this@KotlinDownloadActivity, "该下载链接不支持断点")
@Download.onTaskComplete
fun taskComplete(task: DownloadTask) {
if (task.key == mUrl) {
binding.progress = 100
Toast.makeText(
this, getString(R.string.download_success),
Toast.LENGTH_SHORT
)
.show()
binding.stateStr = getString(R.string.re_start)
binding.speed = ""
}
}
override fun setLayoutId(): Int {
return R.layout.activity_single_kotlin
}
fun onClick(view: View) {
when (view.id) {
R.id.start -> {
if (target.isRunning) {
Aria.download(this)
.load(DOWNLOAD_URL)
.stop()
} else {
startD()
}
R.id.start -> if (mTarget!!.isRunning) {
Aria.download(this)
.load(mUrl!!)
.stop()
} else {
startD()
}
R.id.stop -> Aria.download(this).load(DOWNLOAD_URL).stop()
R.id.cancel -> Aria.download(this).load(DOWNLOAD_URL).cancel()
R.id.stop -> Aria.download(this).load(mUrl!!).stop()
R.id.cancel -> Aria.download(this).load(mUrl!!).cancel(true)
}
}
private fun startD() {
Aria.download(this)
.load(DOWNLOAD_URL)
.addHeader("groupHash", "value")
.setFilePath(Environment.getExternalStorageDirectory().path + "/kotlin.apk")
.load(mUrl!!)
//.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
//.addHeader("Accept-Encoding", "gzip, deflate")
//.addHeader("DNT", "1")
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
.useServerFileName(true)
.setFilePath(mFilePath!!, true)
.setFileLenAdapter(IHttpFileLenAdapter { headers ->
val sLength = headers["Content-Length"]
if (sLength == null || sLength.isEmpty()) {
return@IHttpFileLenAdapter -1
}
val temp = sLength[0]
java.lang.Long.parseLong(temp)
})
.start()
}
override fun onStop() {
super.onStop()
//Aria.download(this).unRegister();
}
override fun dataCallback(
result: Int,
data: Any
) {
super.dataCallback(result, data)
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
mModule!!.uploadUrl(this, data.toString())
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
mModule!!.updateFilePath(this, data.toString())
}
}
}

@ -16,25 +16,21 @@
package com.arialyy.simple.core.download;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.TextUtils;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
@ -43,43 +39,24 @@ import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.common.ModifyPathDialog;
import com.arialyy.simple.common.ModifyUrlDialog;
import com.arialyy.simple.databinding.ActivitySingleBinding;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.bumptech.glide.load.resource.transcode.BitmapBytesTranscoder;
import java.io.File;
import java.util.HashMap;
import com.arialyy.simple.util.AppUtil;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
private String DOWNLOAD_URL =
//"http://kotlinlang.org/docs/kotlin-docs.pdf";
//"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe";
//"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apks";
"http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
//"http://120.55.95.61:8811/ghcg/zg/武义总规纲要成果.zip";
//"https://yizi-kejian.oss-cn-beijing.aliyuncs.com/qimeng/package1/qmtable11.zip";
//"http://rs.0.gaoshouyou.com/d/04/1e/400423a7551e1f3f0eb1812afa1f9b44.apk";
//"http://chargepile2.techsum.net/car-manage/file/download?path=2019-04-26/c0242efd18be4ecbb23911b1c509dcad--掌通各系统汇总.xls"; // 无长度的chunked
//"http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载
//"http://apk500.bce.baidu-mgame.com/game/67000/67734/20170622040827_oem_5502845.apk?r=1";
//"https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe";
//"http://9.9.9.50:5000/download/CentOS-7-x86_64-Minimal-1804.iso";
//"http://v2.qingdian1.com/m_20180730_991/2/2B9FB34A4BCD8CE61481D1C8418EFE36_1080P.m3u8";
//"https://firmwareapi.azurewebsites.net/firmware-overview?name=A19_Filament_W_IMG0038_00102411-encrypted.ota";
Button mStart;
Button mStop;
Button mCancel;
RadioGroup mRg;
DownloadTarget target;
private String mUrl;
private String mFilePath;
private DownloadModule1 mModule;
private DownloadTarget mTarget;
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
@ -110,22 +87,51 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
@Override
protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
mStart = findViewById(R.id.start);
mStop = findViewById(R.id.stop);
mCancel = findViewById(R.id.cancel);
mRg = findViewById(R.id.speeds);
mStop.setVisibility(View.GONE);
setTitle("单任务下载");
Aria.download(this).register();
target = Aria.download(this).load(DOWNLOAD_URL);
getBinding().setProgress(target.getPercent());
if (target.getTaskState() == IEntity.STATE_STOP) {
mStart.setText("恢复");
//mStart.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
} else if (target.isRunning()) {
mStart.setText("停止");
mModule = ViewModelProviders.of(this).get(DownloadModule1.class);
mModule.getSingDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
@Override public void onChanged(@Nullable DownloadEntity entity) {
if (entity == null) {
return;
}
mTarget = Aria.download(SingleTaskActivity.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);
try {
getBinding().codeView.setSource(AppUtil.getHelpCode(this, "HttpDownload.java"));
} catch (IOException e) {
e.printStackTrace();
}
getBinding().setFileSize(target.getConvertFileSize());
}
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
@ -172,61 +178,59 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
@Download.onWait
void onWait(DownloadTask task) {
if (task.getKey().equals(DOWNLOAD_URL)) {
if (task.getKey().equals(mUrl)) {
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
}
}
@Download.onPre
protected void onPre(DownloadTask task) {
if (task.getKey().equals(DOWNLOAD_URL)) {
mStart.setText("停止");
if (task.getKey().equals(mUrl)) {
getBinding().setStateStr(getString(R.string.stop));
}
}
@Download.onTaskStart
void taskStart(DownloadTask task) {
if (task.getKey().equals(DOWNLOAD_URL)) {
if (task.getKey().equals(mUrl)) {
getBinding().setFileSize(task.getConvertFileSize());
}
}
@Download.onTaskRunning
protected void running(DownloadTask task) {
//ALog.d(TAG, String.format("%s_running_%s", getClass().getName(), hashCode()));
//if (task.getKey().equals(DOWNLOAD_URL)) {
//Log.d(TAG, task.getKey());
long len = task.getFileSize();
if (len == 0) {
getBinding().setProgress(0);
} else {
getBinding().setProgress(task.getPercent());
if (task.getKey().equals(mUrl)) {
//Log.d(TAG, task.getKey());
long len = task.getFileSize();
if (len == 0) {
getBinding().setProgress(0);
} else {
getBinding().setProgress(task.getPercent());
}
getBinding().setSpeed(task.getConvertSpeed());
}
getBinding().setSpeed(task.getConvertSpeed());
//}
}
@Download.onTaskResume
void taskResume(DownloadTask task) {
if (task.getKey().equals(DOWNLOAD_URL)) {
mStart.setText("停止");
if (task.getKey().equals(mUrl)) {
getBinding().setStateStr(getString(R.string.stop));
}
}
@Download.onTaskStop
void taskStop(DownloadTask task) {
if (task.getKey().equals(DOWNLOAD_URL)) {
mStart.setText("恢复");
if (task.getKey().equals(mUrl)) {
getBinding().setStateStr(getString(R.string.resume));
getBinding().setSpeed("");
}
}
@Download.onTaskCancel
void taskCancel(DownloadTask task) {
if (task.getKey().equals(DOWNLOAD_URL)) {
if (task.getKey().equals(mUrl)) {
getBinding().setProgress(0);
Toast.makeText(SingleTaskActivity.this, "取消下载", Toast.LENGTH_SHORT).show();
mStart.setText("开始");
getBinding().setStateStr(getString(R.string.start));
getBinding().setSpeed("");
Log.d(TAG, "cancel");
}
@ -237,48 +241,22 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
*/
@Download.onTaskFail
void taskFail(DownloadTask task, Exception e) {
if (task.getKey().equals(DOWNLOAD_URL)) {
Toast.makeText(SingleTaskActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
mStart.setText("开始");
if (task.getKey().equals(mUrl)) {
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
.show();
getBinding().setStateStr(getString(R.string.start));
}
}
@Download.onTaskComplete
void taskComplete(DownloadTask task) {
//Glide.with(this).load("").asBitmap().transform(new BitmapTransformation() {
// @Override
// protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
// return null;
// }
//
// @Override public String getId() {
// return null;
// }
//})
//if (task.getKey().equals(DOWNLOAD_URL)) {
getBinding().setProgress(100);
Toast.makeText(SingleTaskActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
mStart.setText("重新开始?");
//mCancel.setEnabled(false);
getBinding().setSpeed("");
L.d(TAG, "path = " + task.getDownloadEntity().getDownloadPath());
L.d(TAG, "md5Code = " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
L.d(TAG, "data = " + Aria.download(this).getDownloadEntity(DOWNLOAD_URL));
//DownloadEntity temp = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
//L.d(TAG, "status = " + temp.getState() + ", isComplete = " + temp.isComplete());
//Intent install = new Intent(Intent.ACTION_VIEW);
//install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//File apkFile = new File(task.getDownloadPath());
//install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
//startActivity(install);
//}
}
@Download.onNoSupportBreakPoint
public void onNoSupportBreakPoint(DownloadTask task) {
Log.d(TAG, "该下载链接不支持断点");
if (task.getKey().equals(DOWNLOAD_URL)) {
T.showShort(SingleTaskActivity.this, "该下载链接不支持断点");
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("");
}
}
@ -290,35 +268,30 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (target.isRunning()) {
Aria.download(this).load(DOWNLOAD_URL).stop();
if (mTarget.isRunning()) {
Aria.download(this).load(mUrl).stop();
} else {
startD();
}
break;
case R.id.stop:
Aria.download(this).load(DOWNLOAD_URL).stop();
Aria.download(this).load(mUrl).stop();
break;
case R.id.cancel:
Aria.download(this).load(DOWNLOAD_URL).reStart();
//Aria.download(this).load(DOWNLOAD_URL).cancel(true);
//Aria.download(this).load(DOWNLOAD_URL).removeRecord();
Aria.download(this).load(mUrl).cancel(true);
break;
}
}
int i = 1;
private void startD() {
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ggsg14.apk";
Aria.download(SingleTaskActivity.this)
.load(DOWNLOAD_URL)
.load(mUrl)
//.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
//.addHeader("Accept-Encoding", "gzip, deflate")
//.addHeader("DNT", "1")
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
.useServerFileName(true)
.setFilePath(path, true)
.setFilePath(mFilePath, true)
.setFileLenAdapter(new IHttpFileLenAdapter() {
@Override public long handleFileLen(Map<String, List<String>> headers) {
@ -331,15 +304,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
return Long.parseLong(temp);
}
})
//.asGet()
//.asPost()
//.setParams(params)
//.setExtendField("{\n"
// + "\"id\":\"你的样子\"\n< > "
// + "}")
//.resetState()
.start();
//.add();
}
@Override
@ -347,4 +312,13 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
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));
}
}
}

@ -3,9 +3,9 @@ package com.arialyy.simple.core.test;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Upload;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
@ -13,16 +13,14 @@ import com.arialyy.simple.databinding.ActivityTestBinding;
import java.io.File;
/**
* Created by Administrator on 2018/4/12.
* Created by lyy on 2019/5/28.
* Ftp 下载
* <a href="https://aria.laoyuyu.me/aria_doc/">文档</>
*/
public class TestFTPActivity extends BaseActivity<ActivityTestBinding> {
String TAG = "TestFTPActivity";
//String URL = "http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载
//private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
private final String FILE_PATH = "/mnt/sdcard/mmm.mp4";
private final String URL = "ftps://9.9.9.59:990/aa/你好";
private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar";
@Override protected int setLayoutId() {
return R.layout.activity_test;
@ -31,65 +29,62 @@ public class TestFTPActivity extends BaseActivity<ActivityTestBinding> {
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
mBar.setVisibility(View.GONE);
Aria.upload(this).register();
Aria.upload(this).setMaxSpeed(128);
Aria.download(this).register();
}
@Upload.onWait void onWait(UploadTask task) {
@Download.onWait void onWait(DownloadTask task) {
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
}
@Upload.onPre protected void onPre(UploadTask task) {
@Download.onPre protected void onPre(DownloadTask task) {
Log.d(TAG, "onPre");
}
@Upload.onTaskStart void taskStart(UploadTask task) {
@Download.onTaskStart void taskStart(DownloadTask task) {
Log.d(TAG, "onStart");
}
@Upload.onTaskRunning protected void running(UploadTask task) {
@Download.onTaskRunning protected void running(DownloadTask task) {
Log.d(TAG, "running,speed=" + task.getConvertSpeed());
}
@Upload.onTaskResume void taskResume(UploadTask task) {
@Download.onTaskResume void taskResume(DownloadTask task) {
Log.d(TAG, "resume");
}
@Upload.onTaskStop void taskStop(UploadTask task) {
@Download.onTaskStop void taskStop(DownloadTask task) {
Log.d(TAG, "stop");
}
@Upload.onTaskCancel void taskCancel(UploadTask task) {
@Download.onTaskCancel void taskCancel(DownloadTask task) {
Log.d(TAG, "cancel");
}
@Upload.onTaskFail void taskFail(UploadTask task) {
@Download.onTaskFail void taskFail(DownloadTask task) {
Log.d(TAG, "fail");
}
@Upload.onTaskComplete void taskComplete(UploadTask task) {
@Download.onTaskComplete void taskComplete(DownloadTask task) {
Log.d(TAG, "complete, md5 => " + CommonUtil.getFileMD5(new File(task.getKey())));
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.upload(this)
.loadFtp(FILE_PATH)
Aria.download(this)
.loadFtp(URL)
.setFilePath(FILE_PATH)
.login("lao", "123456")
.setUploadUrl(URL)
.asFtps()
.setStorePath("/mnt/sdcard/Download/server.crt")
.setAlias("www.laoyuyu.me")
//.asFtps() // ftps 配置
//.setStorePath("/mnt/sdcard/Download/server.crt") //设置证书路径
// .setAlias("www.laoyuyu.me") // 设置证书别名
.start();
//Uri uri = Uri.parse("ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv");
//ALog.d(TAG, "sh = " + uri.getScheme() + ", user = " + uri.getUserInfo() + ", host = " + uri.getHost() + ", port = " + uri.getPort() + " remotePath = " + uri.getPath());
break;
case R.id.stop:
Aria.upload(this).loadFtp(FILE_PATH).stop();
Aria.download(this).loadFtp(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.upload(this).loadFtp(FILE_PATH).cancel();
Aria.download(this).loadFtp(FILE_PATH).cancel();
break;
}
}

@ -15,11 +15,11 @@
*/
package com.arialyy.simple.core.upload;
import android.arch.lifecycle.Observer;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.FileProvider;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Upload;
@ -28,38 +28,64 @@ import com.arialyy.aria.core.common.ftp.FtpInterceptHandler;
import com.arialyy.aria.core.common.ftp.IFtpUploadInterceptor;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.FileUtil;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.BuildConfig;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.common.ModifyUrlDialog;
import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
import com.arialyy.simple.util.AppUtil;
import java.io.File;
import java.io.IOException;
import java.util.List;
import android.arch.lifecycle.ViewModelProviders;
/**
* Created by lyy on 2017/7/28. Ftp 文件上传demo
*/
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private final int OPEN_FILE_MANAGER_CODE = 0xB1;
private String mFilePath = "/mnt/sdcard/AriaPrj.rar";
private String mUrl = "ftp://9.9.9.205:2121/aa/你好";
private String mFilePath;
private String mUrl;
private UploadModule mModule;
@Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传");
super.init(savedInstanceState);
Aria.upload(this).register();
UploadEntity entity = Aria.upload(this).getUploadEntity(mFilePath);
if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
}
getBinding().setUrl(mUrl);
getBinding().setFilePath(mFilePath);
getBinding().setViewModel(this);
setUI();
}
private void setUI() {
mModule = ViewModelProviders.of(this).get(UploadModule.class);
mModule.getFtpInfo(this).observe(this, new Observer<UploadEntity>() {
@Override public void onChanged(@Nullable UploadEntity entity) {
if (entity != null) {
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();
}
}
});
setHelpCode();
}
private void setHelpCode() {
try {
getBinding().codeView.setSource(AppUtil.getHelpCode(this, "FtpUpload.java"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override protected int setLayoutId() {
@ -73,23 +99,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
}
public void chooseFilePath() {
File parentFile = new File(mFilePath);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(this,
BuildConfig.APPLICATION_ID + ".provider",
parentFile.getParentFile());
} else {
uri = Uri.fromFile(parentFile.getParentFile());
}
intent.setDataAndType(uri, "*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, OPEN_FILE_MANAGER_CODE);
AppUtil.chooseFile(this, new File(mFilePath), null, OPEN_FILE_MANAGER_CODE);
}
public void onClick(View view) {
@ -169,8 +179,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
@Override protected void dataCallback(int result, Object data) {
super.dataCallback(result, data);
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
mUrl = String.valueOf(data);
getBinding().setUrl(mUrl);
mModule.updateFtpUrl(this, String.valueOf(data));
}
}
@ -178,7 +187,12 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OPEN_FILE_MANAGER_CODE && resultCode == RESULT_OK) {
Uri uri = data.getData();
//Toast.makeText(this, "文件路径:" + uri.getPath(), Toast.LENGTH_SHORT).show();
if (uri != null) {
mModule.updateFtpFilePath(this, uri.getPath());
ALog.d(TAG, String.format("选择的文件路径:%s", uri.getPath()));
} else {
ALog.d(TAG, "没有选择文件");
}
}
}
}

@ -0,0 +1,74 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.core.upload;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.content.Context;
import android.os.Environment;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.frame.base.BaseViewModule;
import com.arialyy.simple.util.AppUtil;
public class UploadModule extends BaseViewModule {
private final String FTP_URL_KEY = "FTP_URL_KEY";
private final String FTP_PATH_KEY = "FTP_PATH_KEY";
private MutableLiveData<UploadEntity> liveData = new MutableLiveData<>();
UploadEntity uploadInfo;
/**
* 获取Ftp上传信息
*/
LiveData<UploadEntity> getFtpInfo(Context context) {
String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.205:2121/aa/你好");
String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
Environment.getExternalStorageDirectory().getPath() + "/AriaPrj.rar");
UploadEntity entity = Aria.upload(context).getUploadEntity(filePath);
if (entity != null) {
uploadInfo = entity;
AppUtil.setConfigValue(context, FTP_URL_KEY, uploadInfo.getUrl());
AppUtil.setConfigValue(context, FTP_PATH_KEY, uploadInfo.getFilePath());
} else {
uploadInfo = new UploadEntity();
uploadInfo.setUrl(url);
uploadInfo.setFilePath(filePath);
}
liveData.postValue(uploadInfo);
return liveData;
}
/**
* 更新Url
*/
void updateFtpUrl(Context context, String url) {
uploadInfo.setUrl(url);
AppUtil.setConfigValue(context, FTP_URL_KEY, url);
liveData.postValue(uploadInfo);
}
/**
* 更新文件路径
*/
void updateFtpFilePath(Context context, String filePath) {
uploadInfo.setFilePath(filePath);
AppUtil.setConfigValue(context, FTP_PATH_KEY, filePath);
liveData.postValue(uploadInfo);
}
}

@ -0,0 +1,106 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.simple.BuildConfig;
import java.io.File;
import java.io.IOException;
public class AppUtil {
private static final String TAG = "AppUtil";
private static final String ARIA_SHARE_PRE_KEY = "ARIA_SHARE_PRE_KEY";
/**
* http下载示例代码
*/
public static File getHelpCode(Context context, String fileName) throws IOException {
String path = String.format("%s/code/%s", context.getFilesDir().getPath(), fileName);
File ftpCode = new File(path);
if (!ftpCode.exists()) {
CommonUtil.createFile(path);
CommonUtil.createFileFormInputStream(context.getAssets()
.open(String.format("help_code/%s", fileName)),
path);
}
return ftpCode;
}
/**
* 读取配置文件字段
*
* @param key key
* @param defStr 默认字符串
*/
public static String getConfigValue(Context context, String key, String defStr) {
SharedPreferences preferences =
context.getSharedPreferences(ARIA_SHARE_PRE_KEY, Context.MODE_PRIVATE);
return preferences.getString(key, defStr);
}
/**
* set配置文件字段
*
* @param key key
* @param value 需要保存的字符串
*/
public static void setConfigValue(Context context, String key, String value) {
SharedPreferences preferences =
context.getSharedPreferences(ARIA_SHARE_PRE_KEY, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
editor.apply();
}
/**
* 调用系统文件管理器选择文件
*
* @param file 不能是文件夹
* @param mineType android 可用的minetype
* @param requestCode 请求码
*/
public static void chooseFile(Activity activity, File file, String mineType, int requestCode) {
if (file.isDirectory()) {
ALog.e(TAG, "不能选择文件夹");
return;
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(activity.getApplicationContext(),
BuildConfig.APPLICATION_ID + ".provider",
file);
} else {
uri = Uri.fromFile(file);
}
intent.setDataAndType(uri, TextUtils.isEmpty(mineType) ? "*/*" : mineType);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivityForResult(intent, requestCode);
}
}

@ -0,0 +1,76 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.simple.widget;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RelativeLayout;
import com.arialyy.simple.R;
import com.arialyy.simple.core.FullScreenCodeActivity;
import com.pddstudio.highlightjs.HighlightJsView;
import com.pddstudio.highlightjs.models.Language;
import com.pddstudio.highlightjs.models.Theme;
import java.io.File;
/**
* 代码高亮控件
*/
public class CodeView extends RelativeLayout {
private HighlightJsView mCodeView;
private File mSourceFile;
public CodeView(Context context) {
super(context, null);
}
public CodeView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.layout_code_demo, this, true);
mCodeView = findViewById(R.id.js_view);
mCodeView.setHighlightLanguage(Language.JAVA);
mCodeView.setTheme(Theme.ANDROID_STUDIO);
mCodeView.setZoomSupportEnabled(true);
findViewById(R.id.full_screen).setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) {
// 横屏显示代码
Intent intent = new Intent(getContext(), FullScreenCodeActivity.class);
intent.putExtra(FullScreenCodeActivity.KEY_FILE_PATH, mSourceFile.getPath());
getContext().startActivity(intent);
}
});
}
public void setSource(File sourceFile) {
mSourceFile = sourceFile;
mCodeView.setSource(sourceFile);
}
public void setSource(File sourceFile, Language language) {
mSourceFile = sourceFile;
mCodeView.setHighlightLanguage(language);
mCodeView.setSource(sourceFile);
}
}

@ -21,6 +21,7 @@ import android.databinding.BindingAdapter;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.v7.widget.AppCompatImageView;
import android.text.Html;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@ -78,7 +79,7 @@ public class SvgTextView extends RelativeLayout {
icon.setImageResource(drawable);
}
public void setText(CharSequence text) {
textView.setText(text);
public void setText(String text) {
textView.setText(Html.fromHtml(text));
}
}

@ -1,6 +1,15 @@
<vector android:height="24dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#2b2b2b" android:pathData="M895.65,672.81c14.3,0 23.74,-9.54 23.74,-23.74L919.39,269.29a30.46,30.46 0,0 0,-8.66 -21.29L738.23,71.19A30.46,30.46 0,0 0,716.42 62L199.21,62c-52.29,0 -95.07,42.78 -95.07,95.07v654h-0.1v51.85h0.1c0,52.25 42.81,95.07 95.07,95.07h625.11c52.25,0 95.07,-42.81 95.07,-95.07v-71.31c0,-14.31 -9.54,-23.74 -23.74,-23.74s-23.74,9.54 -23.74,23.74v71.32a47.69,47.69 0,0 1,-47.48 47.58L199.21,910.51a47.72,47.72 0,0 1,-47.58 -47.58v-28.11h0.1L151.73,157.06a47.63,47.63 0,0 1,47.58 -47.48h482.47v123.57a71.32,71.32 0,0 0,71.32 71.32h118.8v344.6c-0.09,14.2 9.44,23.74 23.75,23.74zM847.19,256.81L753,256.81v0.1c-14.3,0 -23.74,-11.92 -23.74,-23.74v-98.75a2.4,2.4 0,0 1,4.13 -1.67l115.52,120a2.4,2.4 0,0 1,-1.73 4.04z"/>
<path android:fillColor="#2b2b2b" android:pathData="M318.91,394.59c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h300.47c14.78,0 26.81,12.25 26.81,27.3s-12,27.3 -26.81,27.3zM318.91,569.8c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h384.85c14.78,0 26.81,12.25 26.81,27.3s-12,27.3 -26.81,27.3zM318.91,742c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h261.3c14.78,0 26.81,12.25 26.81,27.3S595,742 580.21,742z"/>
<path android:fillColor="#2b2b2b" android:pathData="M704.01,367.3m-27.3,0a27.3,27.3 0,1 0,54.6 0,27.3 27.3,0 1,0 -54.6,0Z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="1024"
android:viewportWidth="1024"
android:width="24dp">
<path
android:fillColor="@color/icon_black"
android:pathData="M895.65,672.81c14.3,0 23.74,-9.54 23.74,-23.74L919.39,269.29a30.46,30.46 0,0 0,-8.66 -21.29L738.23,71.19A30.46,30.46 0,0 0,716.42 62L199.21,62c-52.29,0 -95.07,42.78 -95.07,95.07v654h-0.1v51.85h0.1c0,52.25 42.81,95.07 95.07,95.07h625.11c52.25,0 95.07,-42.81 95.07,-95.07v-71.31c0,-14.31 -9.54,-23.74 -23.74,-23.74s-23.74,9.54 -23.74,23.74v71.32a47.69,47.69 0,0 1,-47.48 47.58L199.21,910.51a47.72,47.72 0,0 1,-47.58 -47.58v-28.11h0.1L151.73,157.06a47.63,47.63 0,0 1,47.58 -47.48h482.47v123.57a71.32,71.32 0,0 0,71.32 71.32h118.8v344.6c-0.09,14.2 9.44,23.74 23.75,23.74zM847.19,256.81L753,256.81v0.1c-14.3,0 -23.74,-11.92 -23.74,-23.74v-98.75a2.4,2.4 0,0 1,4.13 -1.67l115.52,120a2.4,2.4 0,0 1,-1.73 4.04z"/>
<path
android:fillColor="@color/icon_black"
android:pathData="M318.91,394.59c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h300.47c14.78,0 26.81,12.25 26.81,27.3s-12,27.3 -26.81,27.3zM318.91,569.8c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h384.85c14.78,0 26.81,12.25 26.81,27.3s-12,27.3 -26.81,27.3zM318.91,742c-14.78,0 -26.81,-12.25 -26.81,-27.3s12,-27.3 26.81,-27.3h261.3c14.78,0 26.81,12.25 26.81,27.3S595,742 580.21,742z"/>
<path
android:fillColor="@color/icon_black"
android:pathData="M704.01,367.3m-27.3,0a27.3,27.3 0,1 0,54.6 0,27.3 27.3,0 1,0 -54.6,0Z"/>
</vector>

@ -0,0 +1,6 @@
<vector android:height="24dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#CE9F06" android:pathData="M975,774.77H49V220.37h857.09c38.11,0 69.04,30.93 69.04,69.04v485.37h-0.14zM627.71,220.37c0,-63.93 -51.78,-115.71 -115.71,-115.71H49v115.71h578.71"/>
<path android:fillColor="#FFFFFF" android:pathData="M164.72,620.26V273.11h694.56v347.14h-694.56z"/>
<path android:fillColor="#FFCD2C" android:pathData="M975,848.1V398.49c0,-31.9 -25.96,-57.86 -57.86,-57.86H106.86c-31.9,0 -57.86,25.96 -57.86,57.86v449.46c0,39.35 31.9,71.39 71.39,71.39h783.35c39.35,0.14 71.25,-31.9 71.25,-71.25z"/>
</vector>

@ -0,0 +1,4 @@
<vector android:height="24dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/icon_black" android:pathData="M432,636.8l-41.6,-41.6 -150.4,150.4L128,633.6L128,896h259.2l-108.8,-108.8 153.6,-150.4zM595.2,387.2l41.6,41.6 150.4,-150.4 108.8,108.8L896,128h-259.2l108.8,108.8 -150.4,150.4zM128,128v259.2l108.8,-108.8 150.4,150.4 41.6,-41.6 -147.2,-150.4L390.4,128L128,128zM595.2,636.8l150.4,150.4 -108.8,108.8L896,896v-259.2l-108.8,108.8 -150.4,-150.4 -41.6,41.6zM595.2,636.8"/>
</vector>

@ -4,6 +4,6 @@
android:viewportWidth="1024"
android:width="24dp">
<path
android:fillColor="#2b2b2b"
android:fillColor="@color/icon_black"
android:pathData="M768.49,388.36L590.76,215.07 210.93,594.49l-66.2,242.16v0.4L386.48,769.8zM739.52,66.62l-95.2,95.04 178.3,172.65 92.38,-92.3c48.49,-48.41 48.49,-126.99 0,-175.39 -48.4,-48.41 -127.07,-48.41 -175.47,-0zM79.03,878.71h872.33v114.98H79.03z"/>
</vector>

@ -71,5 +71,13 @@
bind:stateStr="@{stateStr}"
/>
<com.arialyy.simple.widget.CodeView
android:id="@+id/code_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</layout>

@ -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"
>
<com.pddstudio.highlightjs.HighlightJsView
android:id="@+id/code_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
/>
</LinearLayout>
</layout>

@ -16,40 +16,71 @@
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.SingleTaskActivity"
/>
</data>
<android.support.design.widget.CoordinatorLayout
<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"
>
<android.support.design.widget.AppBarLayout
<include layout="@layout/layout_bar"/>
<com.arialyy.simple.widget.SvgTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<include layout="@layout/layout_bar"/>
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)}"
/>
</android.support.design.widget.AppBarLayout>
<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/content_single"
layout="@layout/layout_content_single"
bind:fileSize="@{fileSize}"
bind:progress="@{progress}"
bind:speed="@{speed}"
bind:stateStr="@{stateStr}"
/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"
<com.arialyy.simple.widget.CodeView
android:id="@+id/code_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
</layout>

@ -0,0 +1,86 @@
<?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.KotlinDownloadActivity"
/>
</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}"
/>
<com.arialyy.simple.widget.CodeView
android:id="@+id/code_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</layout>

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="currentPath"
type="String"
/>
<import type="android.text.Html"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_color"
android:maxHeight="400dp"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp"
android:text="@string/choose_dir"
android:textColor="@android:color/black"
android:textSize="22sp"
/>
<TextView
android:id="@+id/current_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="4dp"
android:ellipsize="marquee"
android:singleLine="true"
android:text="@{Html.fromHtml(@string/current_path(currentPath))}"
/>
<TextView
android:id="@+id/up"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/current_path"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:gravity="center_vertical"
android:text=".."
android:textColor="@color/text_black"
android:textSize="18sp"
android:textStyle="bold"
/>
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/enter"
android:layout_below="@+id/up"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="4dp"
/>
<Button
android:id="@+id/enter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="@string/choose_current_dir"
style="?buttonBarButtonStyle"
/>
</RelativeLayout>
</layout>

@ -0,0 +1,120 @@
<?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="title"
type="String"
/>
<variable
name="name"
type="String"
/>
<variable
name="dir"
type="String"
/>
<variable
name="viewModel"
type="com.arialyy.simple.common.ModifyPathDialog"
/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_color"
android:gravity="center|left"
android:maxHeight="400dp"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp"
android:text="@{title}"
android:textColor="@android:color/black"
android:textSize="22sp"
/>
<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.chooseDir()}"
bind:svg_text_view_icon="@drawable/ic_modify"
bind:text="@{@string/dir_path(dir)}"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
>
<TextView
android:id="@+id/dir_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/name"
android:textColor="@color/text_black"
android:textSize="@dimen/text_size_normal"
android:textStyle="bold"
/>
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="15dp"
android:layout_marginLeft="8dp"
android:layout_toRightOf="@+id/dir_hint"
android:background="@android:color/transparent"
android:hint="@string/file_name_hint"
android:lineSpacingMultiplier="1.2"
android:text="@={name}"
android:textColor="@color/text_black"
android:textSize="@dimen/text_size_normal"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel"
style="?buttonBarButtonStyle"
/>
<Button
android:id="@+id/enter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/enter"
style="?buttonBarButtonStyle"
/>
</LinearLayout>
</LinearLayout>
</layout>

@ -41,8 +41,9 @@
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
android:background="@android:color/transparent"
android:hint="@string/url_hint"
android:lineSpacingMultiplier="1.2"
android:text="@{text}"
android:text="@={text}"
android:textColor="#000"
android:textSize="16sp"
/>

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/bar_height"
android:background="@drawable/item_bg"
android:orientation="vertical"
>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
android:layout_centerVertical="true"
app:srcCompat="@drawable/ic_dir"
/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:layout_toRightOf="@+id/icon"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/text_black"
android:textSize="@dimen/text_size_normal"
/>
</RelativeLayout>

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
>
<TextView
android:id="@+id/hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/code_simple"
android:textColor="@color/text_black"
android:textSize="@dimen/text_size_normal"
android:textStyle="bold"
/>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/full_screen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
app:srcCompat="@drawable/ic_full_screen"
/>
</RelativeLayout>
<com.pddstudio.highlightjs.HighlightJsView
android:id="@+id/js_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>

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

Loading…
Cancel
Save