{
+
+ /**
+ * 网络请求成功
+ */
+ public void onResponse(T response);
+
+ /**
+ * 请求失败
+ */
+ public void onFailure(Throwable e);
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/base/net/JsonCodeAnalysisUtil.java b/AppFrame/src/main/java/com/arialyy/frame/base/net/JsonCodeAnalysisUtil.java
new file mode 100644
index 00000000..4cc6eeb0
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/base/net/JsonCodeAnalysisUtil.java
@@ -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;
+ }
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/base/net/NetManager.java b/AppFrame/src/main/java/com/arialyy/frame/base/net/NetManager.java
new file mode 100644
index 00000000..71d2f144
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/base/net/NetManager.java
@@ -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 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 为 网络实体
+ *
+ * Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken() {
+ * }.getType(), new BasicDeserializer()).create();
+ *
+ * //如启动图,需要将‘ENTITY’替换为启动图实体‘LauncherImgEntity’
+ * Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken() {
+ * }.getType(), new BasicDeserializer()).create();
+ *
+ *
+ */
+ public SERVICE request(Class 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();
+ }
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/base/net/OkHttpLogger.java b/AppFrame/src/main/java/com/arialyy/frame/base/net/OkHttpLogger.java
new file mode 100644
index 00000000..f6f023da
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/base/net/OkHttpLogger.java
@@ -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;
+ }
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/cache/AbsCache.java b/AppFrame/src/main/java/com/arialyy/frame/cache/AbsCache.java
index a9936f09..15ae613c 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/cache/AbsCache.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/cache/AbsCache.java
@@ -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);
+ }
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/cache/CacheParam.java b/AppFrame/src/main/java/com/arialyy/frame/cache/CacheParam.java
index c243b642..783bab70 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/cache/CacheParam.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/cache/CacheParam.java
@@ -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;
/**
* 小容量磁盘缓存
*/
diff --git a/AppFrame/src/main/java/com/arialyy/frame/cache/CacheUtil.java b/AppFrame/src/main/java/com/arialyy/frame/cache/CacheUtil.java
index 84873664..5a1dad4b 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/cache/CacheUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/cache/CacheUtil.java
@@ -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);
- }
- }
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/cache/DiskLruCache.java b/AppFrame/src/main/java/com/arialyy/frame/cache/DiskLruCache.java
new file mode 100644
index 00000000..48c60fb0
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/cache/DiskLruCache.java
@@ -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 created 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 edited, 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 lruEntries =
+ new LinkedHashMap(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[] 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());
+ private final Callable cleanupCallable = new Callable() {
+ @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 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(lruEntries.values())) {
+ if (entry.currentEditor != null) {
+ entry.currentEditor.abort();
+ }
+ }
+ trimToSize();
+ journalWriter.close();
+ journalWriter = null;
+ }
+
+ private void trimToSize() throws IOException {
+ while (size > maxSize) {
+ // Map.Entry toEvict = lruEntries.eldest();
+ final Map.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");
+ }
+ }
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/cache/PathConstaant.java b/AppFrame/src/main/java/com/arialyy/frame/cache/PathConstaant.java
new file mode 100644
index 00000000..dd17a25e
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/cache/PathConstaant.java
@@ -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";
+ }
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/config/CommonConstant.java b/AppFrame/src/main/java/com/arialyy/frame/config/CommonConstant.java
new file mode 100644
index 00000000..13ed8690
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/config/CommonConstant.java
@@ -0,0 +1,9 @@
+package com.arialyy.frame.config;
+
+/**
+ * Created by AriaL on 2017/11/26.
+ */
+
+public interface CommonConstant {
+ boolean DEBUG = true;
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/config/NetConstant.java b/AppFrame/src/main/java/com/arialyy/frame/config/NetConstant.java
new file mode 100644
index 00000000..2d326151
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/config/NetConstant.java
@@ -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/";
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsActivity.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsActivity.java
index f2272ba4..19bb0d57 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsActivity.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsActivity.java
@@ -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 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 extends AppCompatA
}
}
- protected void reNewModule() {
- if (mModuleF == null) {
- mModuleF = ModuleFactory.newInstance();
- }
- }
-
/**
* 获取填充View
*/
@@ -115,7 +111,8 @@ public abstract class AbsActivity 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 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 extends AppCompatA
}
- @Override public void finish() {
+ @Override
+ public void finish() {
super.finish();
mAm.removeActivity(this);
}
@@ -228,13 +228,15 @@ public abstract class AbsActivity 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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsAlertDialog.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsAlertDialog.java
index 2d854a00..34a5f2c0 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsAlertDialog.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsAlertDialog.java
@@ -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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialog.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialog.java
index 7ac41cfc..583f03de 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialog.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialog.java
@@ -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
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialogFragment.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialogFragment.java
index 3e056023..58a97170 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialogFragment.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsDialogFragment.java
@@ -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 extends Dial
return mRootView;
}
- public 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 extends Dial
}
}
+ public T findViewById(@IdRes int id){
+ return mRootView.findViewById(id);
+ }
+
private void initFragment() {
TAG = StringUtil.getClassName(this);
mProxy = IOCProxy.newInstance(this);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsFragment.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsFragment.java
index 42f20852..c44de757 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsFragment.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsFragment.java
@@ -29,7 +29,6 @@ import com.arialyy.frame.util.show.L;
import java.lang.reflect.Field;
-
/**
* Created by lyy on 2015/11/4.
* 基础Fragment
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsFrame.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsFrame.java
index 39486428..5dc34ee7 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsFrame.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsFrame.java
@@ -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 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());
}
}
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/AbsPopupWindow.java b/AppFrame/src/main/java/com/arialyy/frame/core/AbsPopupWindow.java
index 7715d50e..053bc285 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/AbsPopupWindow.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/AbsPopupWindow.java
@@ -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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/BindingFactory.java b/AppFrame/src/main/java/com/arialyy/frame/core/BindingFactory.java
index 578f6b28..2b71abe4 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/BindingFactory.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/BindingFactory.java
@@ -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 mBindings = new ConcurrentHashMap<>();
+ private Map mBindings = new HashMap<>();
private BindingFactory() {
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/CrashHandler.java b/AppFrame/src/main/java/com/arialyy/frame/core/CrashHandler.java
index 2b02d561..62897f4c 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/CrashHandler.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/CrashHandler.java
@@ -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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/DialogSimpleModule.java b/AppFrame/src/main/java/com/arialyy/frame/core/DialogSimpleModule.java
index b0af6322..2a868622 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/DialogSimpleModule.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/DialogSimpleModule.java
@@ -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);
}
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/core/ModuleFactory.java b/AppFrame/src/main/java/com/arialyy/frame/core/ModuleFactory.java
index 0f99fec2..2f16b3f9 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/core/ModuleFactory.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/core/ModuleFactory.java
@@ -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 mModules = new ConcurrentHashMap<>();
+ private Map mModules = new HashMap<>();
private ModuleFactory() {
@@ -50,7 +49,6 @@ public class ModuleFactory {
Object[] params = { context };
try {
Constructor con = clazz.getConstructor(paramTypes);
- con.setAccessible(true);
T module = con.newInstance(params);
mModules.put(clazz.hashCode(), module);
return module;
diff --git a/AppFrame/src/main/java/com/arialyy/frame/http/HttpUtil.java b/AppFrame/src/main/java/com/arialyy/frame/http/HttpUtil.java
index f6cf56a4..3f11c65f 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/http/HttpUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/http/HttpUtil.java
@@ -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 header,
+ @NonNull final String key,
+ final String contentType, final Map 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 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 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 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 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) {
}
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/module/AbsModule.java b/AppFrame/src/main/java/com/arialyy/frame/module/AbsModule.java
index 754d90dc..2c0e6d07 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/module/AbsModule.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/module/AbsModule.java
@@ -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);
}
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/module/IOCProxy.java b/AppFrame/src/main/java/com/arialyy/frame/module/IOCProxy.java
index d5f3a8e7..36cdb2bd 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/module/IOCProxy.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/module/IOCProxy.java
@@ -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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/module/ModuleFactory.java b/AppFrame/src/main/java/com/arialyy/frame/module/ModuleFactory.java
index ad4ac3d3..a9797481 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/module/ModuleFactory.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/module/ModuleFactory.java
@@ -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;
}
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionManager.java b/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionManager.java
index f20db64b..c85ae01a 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionManager.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionManager.java
@@ -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) {
diff --git a/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionUtil.java b/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionUtil.java
index 72ccd7d1..19857cd3 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/permission/PermissionUtil.java
@@ -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;
}
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/temp/AbsTempView.java b/AppFrame/src/main/java/com/arialyy/frame/temp/AbsTempView.java
index 108820b2..52745a60 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/temp/AbsTempView.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/temp/AbsTempView.java
@@ -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();
diff --git a/AppFrame/src/main/java/com/arialyy/frame/temp/TempView.java b/AppFrame/src/main/java/com/arialyy/frame/temp/TempView.java
index 83297ece..f12b2b42 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/temp/TempView.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/temp/TempView.java
@@ -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);
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/AESEncryption.java b/AppFrame/src/main/java/com/arialyy/frame/util/AESEncryption.java
index 4607f81d..182aa69f 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/AESEncryption.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/AESEncryption.java
@@ -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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/AndroidUtils.java b/AppFrame/src/main/java/com/arialyy/frame/util/AndroidUtils.java
index 252a4744..03333054 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/AndroidUtils.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/AndroidUtils.java
@@ -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)
*/
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/AppUtils.java b/AppFrame/src/main/java/com/arialyy/frame/util/AppUtils.java
index 22b609d1..c53b3ab5 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/AppUtils.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/AppUtils.java
@@ -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();
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/DensityUtils.java b/AppFrame/src/main/java/com/arialyy/frame/util/DensityUtils.java
index e52e2b30..9ea43b67 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/DensityUtils.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/DensityUtils.java
@@ -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());
}
/**
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/DrawableUtil.java b/AppFrame/src/main/java/com/arialyy/frame/util/DrawableUtil.java
index 9d7c531e..c30f1e05 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/DrawableUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/DrawableUtil.java
@@ -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);
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/FileUtil.java b/AppFrame/src/main/java/com/arialyy/frame/util/FileUtil.java
index dbf57705..f0db1066 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/FileUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/FileUtil.java
@@ -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;
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/KeyBoardUtils.java b/AppFrame/src/main/java/com/arialyy/frame/util/KeyBoardUtils.java
index c4a77dfd..d71111d4 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/KeyBoardUtils.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/KeyBoardUtils.java
@@ -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);
}
}
\ No newline at end of file
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/MediaUtil.java b/AppFrame/src/main/java/com/arialyy/frame/util/MediaUtil.java
new file mode 100644
index 00000000..4282d81f
--- /dev/null
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/MediaUtil.java
@@ -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;
+ }
+}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/NetUtils.java b/AppFrame/src/main/java/com/arialyy/frame/util/NetUtils.java
index 36c05eb8..1444f0e2 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/NetUtils.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/NetUtils.java
@@ -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;
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/RegularExpression.java b/AppFrame/src/main/java/com/arialyy/frame/util/RegularExpression.java
index fe0a9f57..4b405f48 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/RegularExpression.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/RegularExpression.java
@@ -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)$";
/**
* 音频
*/
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/ScreenUtil.java b/AppFrame/src/main/java/com/arialyy/frame/util/ScreenUtil.java
index 4a448667..fa458212 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/ScreenUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/ScreenUtil.java
@@ -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);
}
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/ShellUtils.java b/AppFrame/src/main/java/com/arialyy/frame/util/ShellUtils.java
index ec150e0b..61fb2137 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/ShellUtils.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/ShellUtils.java
@@ -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());
}
/**
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/StringUtil.java b/AppFrame/src/main/java/com/arialyy/frame/util/StringUtil.java
index 0a31f6ec..32d404a2 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/StringUtil.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/StringUtil.java
@@ -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
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/show/FL.java b/AppFrame/src/main/java/com/arialyy/frame/util/show/FL.java
index 1665cd57..e0a2a6fe 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/show/FL.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/show/FL.java
@@ -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;
}
/**
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/show/L.java b/AppFrame/src/main/java/com/arialyy/frame/util/show/L.java
index c7caf117..4a8145a8 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/show/L.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/show/L.java
@@ -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) {
diff --git a/AppFrame/src/main/java/com/arialyy/frame/util/show/T.java b/AppFrame/src/main/java/com/arialyy/frame/util/show/T.java
index 60a1b86c..985ff4b2 100644
--- a/AppFrame/src/main/java/com/arialyy/frame/util/show/T.java
+++ b/AppFrame/src/main/java/com/arialyy/frame/util/show/T.java
@@ -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();
+ }
}
}
\ No newline at end of file
diff --git a/AppFrame/src/main/res/drawable/selector_green_bt.xml b/AppFrame/src/main/res/drawable/selector_green_bt.xml
index 72bd5b97..f9e4e2e9 100644
--- a/AppFrame/src/main/res/drawable/selector_green_bt.xml
+++ b/AppFrame/src/main/res/drawable/selector_green_bt.xml
@@ -1,15 +1,15 @@
- -
-
-
-
-
-
- -
-
-
-
-
-
+ -
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/AppFrame/src/main/res/layout/layout_error_temp.xml b/AppFrame/src/main/res/layout/layout_error_temp.xml
index e0c2831b..23b8ba13 100644
--- a/AppFrame/src/main/res/layout/layout_error_temp.xml
+++ b/AppFrame/src/main/res/layout/layout_error_temp.xml
@@ -15,8 +15,8 @@
diff --git a/AppFrame/src/main/res/values/color.xml b/AppFrame/src/main/res/values/color.xml
index 33322e7b..48312e04 100644
--- a/AppFrame/src/main/res/values/color.xml
+++ b/AppFrame/src/main/res/values/color.xml
@@ -1,6 +1,6 @@
- #E5E5E5
- #fff
- #A5A5A5
+ #E5E5E5
+ #fff
+ #757575
\ No newline at end of file
diff --git a/AppFrame/src/main/res/values/strings.xml b/AppFrame/src/main/res/values/strings.xml
index 087ebb00..1bb5c0ef 100644
--- a/AppFrame/src/main/res/values/strings.xml
+++ b/AppFrame/src/main/res/values/strings.xml
@@ -1,3 +1,3 @@
- Frame
+ Frame
diff --git a/AppFrame/src/main/res/values/style.xml b/AppFrame/src/main/res/values/style.xml
index cc70cbd6..2492071d 100644
--- a/AppFrame/src/main/res/values/style.xml
+++ b/AppFrame/src/main/res/values/style.xml
@@ -1,15 +1,15 @@
-
-
-
+
+
-
+
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
index de69ee0d..2768b77b 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
@@ -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;
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
index d33608c8..83084ed9 100644
--- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
@@ -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 };
}
}
diff --git a/README.md b/README.md
index da6ed806..87f4806d 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ __注意:3.5.4以下版本升级时,需要更新[配置文件]!!(https:/
```java
Aria.download(this)
.load(DOWNLOAD_URL) //读取下载地址
- .setDownloadPath(DOWNLOAD_PATH) //设置文件保存的完整路径
+ .setFilePath(DOWNLOAD_PATH) //设置文件保存的完整路径
.start(); //启动下载
```
diff --git a/app/build.gradle b/app/build.gradle
index 6b0b4ec1..eaf22fc7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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()
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 269769f7..6b7eedf0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -42,6 +42,11 @@
+
diff --git a/app/src/main/assets/help_code/FtpDownload.java b/app/src/main/assets/help_code/FtpDownload.java
new file mode 100644
index 00000000..2aefed21
--- /dev/null
+++ b/app/src/main/assets/help_code/FtpDownload.java
@@ -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 下载
+ * 文档>
+ */
+public class FtpDownload extends BaseActivity {
+ 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;
+ }
+ }
+}
diff --git a/app/src/main/assets/help_code/FtpUpload.java b/app/src/main/assets/help_code/FtpUpload.java
new file mode 100644
index 00000000..48ad3c99
--- /dev/null
+++ b/app/src/main/assets/help_code/FtpUpload.java
@@ -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
+ * 文档>
+ */
+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 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() + ",上传完成");
+ }
+}
diff --git a/app/src/main/assets/help_code/HttpDownload.java b/app/src/main/assets/help_code/HttpDownload.java
new file mode 100644
index 00000000..61d82669
--- /dev/null
+++ b/app/src/main/assets/help_code/HttpDownload.java
@@ -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
+ * 文档>
+ */
+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() + ",下载完成");
+ }
+}
diff --git a/app/src/main/assets/help_code/KotlinHttpDownload.kt b/app/src/main/assets/help_code/KotlinHttpDownload.kt
new file mode 100644
index 00000000..88892ffb
--- /dev/null
+++ b/app/src/main/assets/help_code/KotlinHttpDownload.kt
@@ -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() {
+
+ 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()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/base/BaseActivity.java b/app/src/main/java/com/arialyy/simple/base/BaseActivity.java
index 97448773..1e71236e 100644
--- a/app/src/main/java/com/arialyy/simple/base/BaseActivity.java
+++ b/app/src/main/java/com/arialyy/simple/base/BaseActivity.java
@@ -43,9 +43,11 @@ public abstract class BaseActivity 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) {
diff --git a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
index 3dcd7f94..0a58422e 100644
--- a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
+++ b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
@@ -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;
diff --git a/app/src/main/java/com/arialyy/simple/common/DialogModule.java b/app/src/main/java/com/arialyy/simple/common/DialogModule.java
new file mode 100644
index 00000000..c594550f
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/common/DialogModule.java
@@ -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> mDirs = new MutableLiveData<>();
+
+ /**
+ * 获取指定目录下的文件夹
+ *
+ * @param path 指定路径
+ */
+ LiveData> 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 data = new ArrayList<>();
+ for (File f : files) {
+ if (f.isDirectory()) {
+ data.add(f);
+ }
+ }
+ mDirs.postValue(data);
+
+ return mDirs;
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/common/DirChooseDialog.java b/app/src/main/java/com/arialyy/simple/common/DirChooseDialog.java
new file mode 100644
index 00000000..23376c67
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/common/DirChooseDialog.java
@@ -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 {
+ public static final int DIR_CHOOSE_DIALOG_RESULT = 0xB2;
+ private String mCurrentPath = Environment.getExternalStorageDirectory().getPath();
+ private List 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>() {
+ @Override public void onChanged(@Nullable List 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 {
+
+ Adapter(Context context, List 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);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/common/ModifyPathDialog.java b/app/src/main/java/com/arialyy/simple/common/ModifyPathDialog.java
new file mode 100644
index 00000000..df2f0cc1
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/common/ModifyPathDialog.java
@@ -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 {
+ 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);
+ }
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/common/ModifyUrlDialog.java b/app/src/main/java/com/arialyy/simple/common/ModifyUrlDialog.java
index ccb14259..c4592af4 100644
--- a/app/src/main/java/com/arialyy/simple/common/ModifyUrlDialog.java
+++ b/app/src/main/java/com/arialyy/simple/common/ModifyUrlDialog.java
@@ -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 {
@@ -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() {
diff --git a/app/src/main/java/com/arialyy/simple/core/FullScreenCodeActivity.java b/app/src/main/java/com/arialyy/simple/core/FullScreenCodeActivity.java
new file mode 100644
index 00000000..d0fcb3bd
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/core/FullScreenCodeActivity.java
@@ -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 {
+ 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);
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/core/download/DownloadModule1.java b/app/src/main/java/com/arialyy/simple/core/download/DownloadModule1.java
new file mode 100644
index 00000000..8219f7ff
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/core/download/DownloadModule1.java
@@ -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 liveData = new MutableLiveData<>();
+ private DownloadEntity singDownloadInfo;
+
+ /**
+ * 单任务下载的信息
+ */
+ LiveData 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);
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt b/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt
index 25a8cc59..93297e02 100644
--- a/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt
+++ b/app/src/main/java/com/arialyy/simple/core/download/KotlinDownloadActivity.kt
@@ -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() {
+import java.io.IOException
- private val DOWNLOAD_URL =
- "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"
+class KotlinDownloadActivity : BaseActivity() {
- 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(
+ 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())
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
index d0d72cee..22aa11e6 100644
--- a/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
+++ b/app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
@@ -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 {
- 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 {
@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() {
+
+ @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 {
@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 {
*/
@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 {
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> headers) {
@@ -331,15 +304,7 @@ public class SingleTaskActivity extends BaseActivity {
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 {
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));
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/core/test/TestFTPActivity.java b/app/src/main/java/com/arialyy/simple/core/test/TestFTPActivity.java
index bc82ce26..a738ca08 100644
--- a/app/src/main/java/com/arialyy/simple/core/test/TestFTPActivity.java
+++ b/app/src/main/java/com/arialyy/simple/core/test/TestFTPActivity.java
@@ -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 下载
+ * 文档>
*/
-
public class TestFTPActivity extends BaseActivity {
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 {
@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;
}
}
diff --git a/app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java b/app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
index c46c6868..8f70f0bf 100644
--- a/app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
+++ b/app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
@@ -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 {
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() {
+ @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 {
}
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 {
@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 {
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, "没有选择文件");
+ }
}
}
}
diff --git a/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java b/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java
new file mode 100644
index 00000000..c4460160
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java
@@ -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 liveData = new MutableLiveData<>();
+ UploadEntity uploadInfo;
+
+ /**
+ * 获取Ftp上传信息
+ */
+ LiveData 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);
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/util/AppUtil.java b/app/src/main/java/com/arialyy/simple/util/AppUtil.java
new file mode 100644
index 00000000..ce3f97c7
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/util/AppUtil.java
@@ -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);
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/widget/CodeView.java b/app/src/main/java/com/arialyy/simple/widget/CodeView.java
new file mode 100644
index 00000000..83767e9e
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/widget/CodeView.java
@@ -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);
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/widget/SvgTextView.java b/app/src/main/java/com/arialyy/simple/widget/SvgTextView.java
index cdd72166..e2cb2d09 100644
--- a/app/src/main/java/com/arialyy/simple/widget/SvgTextView.java
+++ b/app/src/main/java/com/arialyy/simple/widget/SvgTextView.java
@@ -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));
}
}
diff --git a/app/src/main/res/drawable/ic_choose_file.xml b/app/src/main/res/drawable/ic_choose_file.xml
index 2a4617a0..224fbad5 100644
--- a/app/src/main/res/drawable/ic_choose_file.xml
+++ b/app/src/main/res/drawable/ic_choose_file.xml
@@ -1,6 +1,15 @@
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_dir.xml b/app/src/main/res/drawable/ic_dir.xml
new file mode 100644
index 00000000..b92c5ddc
--- /dev/null
+++ b/app/src/main/res/drawable/ic_dir.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_full_screen.xml b/app/src/main/res/drawable/ic_full_screen.xml
new file mode 100644
index 00000000..7c1d6bd1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_full_screen.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_modify.xml b/app/src/main/res/drawable/ic_modify.xml
index ee86c638..cc88dcdf 100644
--- a/app/src/main/res/drawable/ic_modify.xml
+++ b/app/src/main/res/drawable/ic_modify.xml
@@ -4,6 +4,6 @@
android:viewportWidth="1024"
android:width="24dp">
diff --git a/app/src/main/res/layout/activity_ftp_upload.xml b/app/src/main/res/layout/activity_ftp_upload.xml
index adab8e88..174e9ab4 100644
--- a/app/src/main/res/layout/activity_ftp_upload.xml
+++ b/app/src/main/res/layout/activity_ftp_upload.xml
@@ -71,5 +71,13 @@
bind:stateStr="@{stateStr}"
/>
+
+
+
+
diff --git a/app/src/main/res/layout/activity_full_screen_code.xml b/app/src/main/res/layout/activity_full_screen_code.xml
new file mode 100644
index 00000000..552c5cbd
--- /dev/null
+++ b/app/src/main/res/layout/activity_full_screen_code.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_single.xml b/app/src/main/res/layout/activity_single.xml
index 0fac024c..7716da64 100644
--- a/app/src/main/res/layout/activity_single.xml
+++ b/app/src/main/res/layout/activity_single.xml
@@ -16,40 +16,71 @@
name="progress"
type="int"
/>
+
+
+
+
+
-
-
+
+
-
-
+ 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)}"
+ />
-
+
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_single_kotlin.xml b/app/src/main/res/layout/activity_single_kotlin.xml
new file mode 100644
index 00000000..1dfc66fd
--- /dev/null
+++ b/app/src/main/res/layout/activity_single_kotlin.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_choose_dir.xml b/app/src/main/res/layout/dialog_choose_dir.xml
new file mode 100644
index 00000000..633f980a
--- /dev/null
+++ b/app/src/main/res/layout/dialog_choose_dir.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_modify_path.xml b/app/src/main/res/layout/dialog_modify_path.xml
new file mode 100644
index 00000000..17778750
--- /dev/null
+++ b/app/src/main/res/layout/dialog_modify_path.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_modify_url.xml b/app/src/main/res/layout/dialog_modify_url.xml
index 266ce871..f991c98e 100644
--- a/app/src/main/res/layout/dialog_modify_url.xml
+++ b/app/src/main/res/layout/dialog_modify_url.xml
@@ -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"
/>
diff --git a/app/src/main/res/layout/item_choose_dir.xml b/app/src/main/res/layout/item_choose_dir.xml
new file mode 100644
index 00000000..acf6109c
--- /dev/null
+++ b/app/src/main/res/layout/item_choose_dir.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_code_demo.xml b/app/src/main/res/layout/layout_code_demo.xml
new file mode 100644
index 00000000..73a11b16
--- /dev/null
+++ b/app/src/main/res/layout/layout_code_demo.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_content_single.xml b/app/src/main/res/layout/layout_content_single.xml
index 8b310b48..d9823e51 100644
--- a/app/src/main/res/layout/layout_content_single.xml
+++ b/app/src/main/res/layout/layout_content_single.xml
@@ -96,12 +96,5 @@
/>
-
-
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 81a1426f..29977b3f 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -6,6 +6,7 @@
#FF4081
#2B2B2B
#2B2B2B
+ #2B2B2B
#efefef
#597F96
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index b6ff7002..e11411ce 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -14,5 +14,6 @@
18sp
24dp
+ 48dp
diff --git a/app/src/main/res/values/help_code_string.xml b/app/src/main/res/values/help_code_string.xml
new file mode 100644
index 00000000..68746fcf
--- /dev/null
+++ b/app/src/main/res/values/help_code_string.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ Aria.upload(this)
+ .loadFtp("/mnt/sdcard/gggg.apk") //上传文件路径
+ .setUploadUrl(URL) //上传的ftp服务器地址
+ .login("lao", "123456")
+ .start();
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 11b20efb..202d2e1e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,9 +2,9 @@
Aria
Settings
- URL: %1$s
- 文件名: %1$s
- 文件路径: %1$s
+ URL:]]> %1$s
+ NAME:]]> %1$s
+ PATH:]]> %1$s
确认
取消
修改URL
@@ -12,6 +12,21 @@
开始
恢复
删除
+ 代码示例:
+ 下载完成
+ 下载失败
+ 重新开始
+ 选择当前文件夹
+ 选择文件夹
+ PATH:]]> %1$s
+ DIR:]]> %1$s
+ 文件名
+ url
+ NAME:
+ 修改文件路径
+
+
+ 文件名为空
- http 下载
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 85fd98ff..6a6ec6c0 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -23,9 +23,9 @@
@@ -38,5 +38,10 @@
- true
+
+
diff --git a/build.gradle b/build.gradle
index 43720267..f9f4fbf7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -43,7 +43,7 @@ task clean(type: Delete) {
ext {
userOrg = 'arialyy'
groupId = 'com.arialyy.aria'
- publishVersion = '3.6.4'
+ publishVersion = '3.6.5_dev_1'
// publishVersion = '1.0.4' //FTP插件
repoName='maven'
desc = 'android 下载框架'
@@ -51,8 +51,13 @@ ext {
licences = ['Apache-2.0']
compileSdkVersion = 28
- supportLibVersion = "28.0.0"
+ supportLibVersion = "27.1.1"
buildToolsVersion = "28.0.3"
targetSdkVersion = 28
+ lifecycleVersion = "1.1.1"
+// compileSdkVersion = 28
+// supportLibVersion = "28.0.0"
+// buildToolsVersion = "28.0.3"
+// targetSdkVersion = 28
minSdkVersion = 15
}