Commit e89e38d3 by gao.chao

下载更新(未完成)

parent 47585350
...@@ -2,6 +2,22 @@ ...@@ -2,6 +2,22 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mayi.demo"> package="com.mayi.demo">
<!-- CAMERA动态权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.ADD_VOICEMAIL" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.USE_SIP" />
<application <application
android:name=".MyApplication" android:name=".MyApplication"
android:allowBackup="true" android:allowBackup="true"
...@@ -17,7 +33,10 @@ ...@@ -17,7 +33,10 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".FunctionActivity" />
<activity android:name=".OnMultiClickActivity" />
<activity android:name=".PermissionActivity" />
<activity android:name=".SmartRefreshLayoutActivity" />
<activity android:name=".LoadingPicturesActivity" /> <activity android:name=".LoadingPicturesActivity" />
<activity android:name=".BannerActivity" /> <activity android:name=".BannerActivity" />
<activity android:name=".ViewActviity" /> <activity android:name=".ViewActviity" />
......
package com.mayi.demo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import com.mayi.fastdevelop.base.BaseActivity;
import com.mayi.fastdevelop.view.OnMultiClickListener;
public class FunctionActivity extends BaseActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_function);
findViewById(R.id.b1).setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
gotoActivity(QRActivity.class);
}
});
findViewById(R.id.b2).setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
gotoActivity(PermissionActivity.class);
}
});
findViewById(R.id.b3).setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
downLoadAPK();
}
});
}
private void downLoadAPK() {
}
}
...@@ -29,10 +29,10 @@ public class MainActivity extends BaseActivity { ...@@ -29,10 +29,10 @@ public class MainActivity extends BaseActivity {
gotoActivity(ViewActviity.class); gotoActivity(ViewActviity.class);
} }
})); }));
list.add(new ItemBean("二维码", new View.OnClickListener() { list.add(new ItemBean("常用功能", new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
gotoActivity(QRActivity.class); gotoActivity(FunctionActivity.class);
} }
})); }));
listView.setAdapter(new RecyclerView.Adapter<MyViewHolder>() { listView.setAdapter(new RecyclerView.Adapter<MyViewHolder>() {
......
package com.mayi.demo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import com.mayi.fastdevelop.base.BaseActivity;
import com.mayi.fastdevelop.view.OnMultiClickListener;
public class OnMultiClickActivity extends BaseActivity {
private long last;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onmulticlick);
Button click = findViewById(R.id.click);
click.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
if (last == 0) {
showToast("点击时间:" + System.currentTimeMillis());
} else {
showToast("与上次点击时间差:" + (System.currentTimeMillis() - last));
}
last = System.currentTimeMillis();
}
});
}
}
package com.mayi.demo;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.alibaba.fastjson.JSON;
import com.mayi.fastdevelop.base.BaseActivity;
import com.mayi.fastdevelop.util.PermissionUtil;
import com.mayi.fastdevelop.view.OnMultiClickListener;
import com.yanzhenjie.permission.Permission;
import java.util.List;
/**
* 权限申请
*/
public class PermissionActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission);
Button install = findViewById(R.id.install);
Button apply = findViewById(R.id.apply);
final TextView result=findViewById(R.id.result);
apply.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
PermissionUtil.requestPermission(new PermissionUtil.PermissionCallback() {
@Override
public void onSuccess(List<String> data) {
showToast("ANT PermissionUtil"+ "onSuccess:" + JSON.toJSONString(data));
result.setText("请求成功:"+JSON.toJSONString(data));
}
@Override
public void onFail(List<String> data) {
showToast("ANT PermissionUtil"+ "onFail:" + JSON.toJSONString(data));
result.setText("请求失败:"+JSON.toJSONString(data));
}
}, Permission.Group.CAMERA);
}
});
install.setOnClickListener(new OnMultiClickListener() {
@Override
public void onMultiClick(View v) {
PermissionUtil.installAPP(new PermissionUtil.PermissionInstallCallback() {
@Override
public void onSuccess() {
showToast("安装成功");
}
@Override
public void onFail() {
showToast("安装失败");
}
}, Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+"app-debug.apk");
}
});
}
}
package com.mayi.demo; package com.mayi.demo;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mayi.fastdevelop.base.BaseActivity; import com.mayi.fastdevelop.base.BaseActivity;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
/**
* git 地址:https://github.com/scwang90/SmartRefreshLayout
*/
public class SmartRefreshLayoutActivity extends BaseActivity {
private int size = 50;
Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smartrefreshlayout);
handler = new Handler();
final SmartRefreshLayout layout = findViewById(R.id.layout);
final RecyclerView list = findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
list.setAdapter(new MyAdapter());
layout.setEnableRefresh(true);
layout.setEnableLoadmore(true);
layout.setOnLoadmoreListener(new OnLoadmoreListener() {
@Override
public void onLoadmore(RefreshLayout refreshlayout) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
size = size + 10;
list.getAdapter().notifyDataSetChanged();
layout.finishLoadmore();//完成加载
if (size > 100) {
layout.setLoadmoreFinished(true);//数据全部加载完成
}
}
}, 1000);
}
});
layout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
size = 50;
list.getAdapter().notifyDataSetChanged();
layout.finishRefresh();//完成刷新
}
}, 1000);
}
});
}
class MyAdapter extends RecyclerView.Adapter<MyVH> {
@NonNull
@Override
public MyVH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new MyVH(new TextView(viewGroup.getContext()));
}
@Override
public void onBindViewHolder(@NonNull MyVH viewHolder, int i) {
viewHolder.textView.setText("i=" + i);
}
@Override
public int getItemCount() {
return size;
}
}
class MyVH extends RecyclerView.ViewHolder {
TextView textView;
public MyVH(@NonNull View itemView) {
super(itemView);
textView = (TextView) itemView;
}
}
public class SmartRefreshLayoutActivity extends BaseActivity{
} }
...@@ -14,6 +14,9 @@ import com.mayi.fastdevelop.view.wheel.ChangeBirthDialog; ...@@ -14,6 +14,9 @@ import com.mayi.fastdevelop.view.wheel.ChangeBirthDialog;
import com.mayi.fastdevelop.view.wheel.ChangeDateDialog; import com.mayi.fastdevelop.view.wheel.ChangeDateDialog;
import com.mayi.fastdevelop.view.wheel.ChangeTimeDialog; import com.mayi.fastdevelop.view.wheel.ChangeTimeDialog;
/**
* 常用控件
*/
public class ViewActviity extends BaseActivity { public class ViewActviity extends BaseActivity {
...@@ -146,5 +149,18 @@ public class ViewActviity extends BaseActivity { ...@@ -146,5 +149,18 @@ public class ViewActviity extends BaseActivity {
} }
}); });
findViewById(R.id.b12).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gotoActivity(SmartRefreshLayoutActivity.class);
}
});
findViewById(R.id.b13).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gotoActivity(OnMultiClickActivity.class);
}
});
} }
} }
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="二维码" />
<Button
android:id="@+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="申请权限" />
<Button
android:id="@+id/b3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下载安装APP" />
</LinearLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="防止多次点击"/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/apply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="申请定位权限" />
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="安装APP" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
\ No newline at end of file
...@@ -77,5 +77,18 @@ ...@@ -77,5 +77,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="图片加载" /> android:text="图片加载" />
<Button
android:id="@+id/b12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉刷新,加载更多" />
<Button
android:id="@+id/b13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="防止多次点击" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
\ No newline at end of file
...@@ -26,6 +26,7 @@ android { ...@@ -26,6 +26,7 @@ android {
dependencies { dependencies {
api fileTree(include: ['*.jar'], dir: 'libs') api fileTree(include: ['*.jar'], dir: 'libs')
api 'com.yanzhenjie:permission:2.0.0-rc12'//权限申请
api 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.3'//下拉刷新,加载更多 api 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.3'//下拉刷新,加载更多
api 'com.youth.banner:banner:1.4.10' //图片轮播控件 api 'com.youth.banner:banner:1.4.10' //图片轮播控件
api "com.tencent.bugly:crashreport_upgrade:1.3.4" api "com.tencent.bugly:crashreport_upgrade:1.3.4"
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.mayi.fastdevelop"> package="com.mayi.fastdevelop">
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
......
package com.mayi.fastdevelop.base; package com.mayi.fastdevelop.base;
import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.Context;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import com.mayi.fastdevelop.util.ActivitysManager;
import com.mayi.fastdevelop.util.DateUtil; import com.mayi.fastdevelop.util.DateUtil;
import com.mayi.fastdevelop.util.FileUtil; import com.mayi.fastdevelop.util.FileUtil;
import com.mayi.fastdevelop.util.LogUtils; import com.mayi.fastdevelop.util.LogUtils;
...@@ -15,13 +19,21 @@ import com.orhanobut.logger.CsvFormatStrategy; ...@@ -15,13 +19,21 @@ import com.orhanobut.logger.CsvFormatStrategy;
import com.orhanobut.logger.DiskLogAdapter; import com.orhanobut.logger.DiskLogAdapter;
import com.orhanobut.logger.DiskLogStrategy; import com.orhanobut.logger.DiskLogStrategy;
import com.orhanobut.logger.Logger; import com.orhanobut.logger.Logger;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreater;
import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreater;
import com.scwang.smartrefresh.layout.api.RefreshFooter;
import com.scwang.smartrefresh.layout.api.RefreshHeader;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.constant.SpinnerStyle;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.tencent.bugly.crashreport.CrashReport; import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.smtt.sdk.CookieManager; import com.tencent.smtt.sdk.CookieManager;
import com.tencent.smtt.sdk.CookieSyncManager; import com.tencent.smtt.sdk.CookieSyncManager;
import com.tencent.smtt.sdk.QbSdk; import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebStorage; import com.tencent.smtt.sdk.WebStorage;
import java.io.File;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
...@@ -29,16 +41,90 @@ public abstract class BaseApplication extends Application { ...@@ -29,16 +41,90 @@ public abstract class BaseApplication extends Application {
private static BaseApplication mInstance; private static BaseApplication mInstance;
private int logSize = 5 * 1024 * 1024;//默认记录Log文件大小--5M private int logSize = 5 * 1024 * 1024;//默认记录Log文件大小--5M
// 全局Activity 个数
private int mActivityNum = 0;
private boolean mBackground = false;
@Override @Override
public void onCreate() { public void onCreate() {
mInstance = this; mInstance = this;
super.onCreate(); super.onCreate();
registerActivityListener();
initLog(); initLog();
initX5Webview(); initX5Webview();
initSmartRefreshLayout();
} }
public void initBugly(String key,boolean isDebug){ private void initSmartRefreshLayout() {
SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
layout.setPrimaryColorsId(android.R.color.black, android.R.color.white);//全局设置主题颜色
layout.setReboundDuration(75);
return new ClassicsHeader(context)
.setSpinnerStyle(SpinnerStyle.Translate)
.setFinishDuration(75);//指定为经典Header,默认是 贝塞尔雷达Header
}
});
//设置全局的Footer构建器
SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() {
@Override
public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
layout.setReboundDuration(75);
//指定为经典Footer,默认是 BallPulseFooter
return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate).setFinishDuration(75);
}
});
}
/**
* 全局Activity 生命周期监听
*/
private void registerActivityListener() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
// 监听到 Activity创建事件 将该 Activity 加入list
ActivitysManager.addActivity(activity);
}
@Override
public void onActivityStarted(Activity activity) {
if (mActivityNum == 0 && mBackground) {
mBackground = false;
}
mActivityNum++;
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
mActivityNum--;
if (mActivityNum == 0) {
mBackground = true;
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
// 监听到 Activity销毁事件 将该Activity 从list中移除
ActivitysManager.finishActivity(activity);
}
});
}
public void initBugly(String key, boolean isDebug) {
CrashReport.initCrashReport(getApplicationContext(), key, isDebug); CrashReport.initCrashReport(getApplicationContext(), key, isDebug);
} }
...@@ -82,7 +168,7 @@ public abstract class BaseApplication extends Application { ...@@ -82,7 +168,7 @@ public abstract class BaseApplication extends Application {
} }
private void initLog() { private void initLog() {
LogUtils.TAG=getPackageName(); LogUtils.TAG = getPackageName();
if (isWriteLog()) { if (isWriteLog()) {
String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getPackageName() + "/logger/"; String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getPackageName() + "/logger/";
String folder = diskPath + DateUtil.getCurrentDate(); String folder = diskPath + DateUtil.getCurrentDate();
...@@ -103,7 +189,6 @@ public abstract class BaseApplication extends Application { ...@@ -103,7 +189,6 @@ public abstract class BaseApplication extends Application {
FileUtil.deleteFile(diskPath + time); FileUtil.deleteFile(diskPath + time);
} }
} }
Logger.addLogAdapter(new AndroidLogAdapter() { Logger.addLogAdapter(new AndroidLogAdapter() {
@Override @Override
public boolean isLoggable(int priority, String tag) { public boolean isLoggable(int priority, String tag) {
...@@ -112,18 +197,6 @@ public abstract class BaseApplication extends Application { ...@@ -112,18 +197,6 @@ public abstract class BaseApplication extends Application {
}); });
} }
//flie:要删除的文件夹的所在位置
// private void deleteFile(File file) {
// if (file.isDirectory()) {
// File[] files = file.listFiles();
// for (int i = 0; i < files.length; i++) {
// File f = files[i];
// deleteFile(f);
// }
// file.delete();//如要保留文件夹,只删除文件,请注释这行
// }
// }
public static BaseApplication getInstance() { public static BaseApplication getInstance() {
return mInstance; return mInstance;
} }
...@@ -157,4 +230,8 @@ public abstract class BaseApplication extends Application { ...@@ -157,4 +230,8 @@ public abstract class BaseApplication extends Application {
public int getLogSaveDay() { public int getLogSaveDay() {
return 3; return 3;
} }
public boolean isBackground() {
return mBackground;
}
} }
package com.mayi.fastdevelop.bean;
import java.io.Serializable;
/**
* app 启动 - 配置信息
*/
public class AppConfig implements Serializable {
private String wxUpdateUrl; // "微信更新地址",
/**
* 是否需要更新.
*/
private boolean needUpdate;
/**
* 更新地址.
*/
private String updateUrl;
/**
* 服务器最新版本号.
*/
private int serverVersion;
/**
* 是否强制更新.
*/
private boolean forceUpdate;
/**
* 更新文件大小.
*/
private String fileSize;
/**
* 更新说明.
*/
private String updateRemark;
public String getWxUpdateUrl() {
return wxUpdateUrl;
}
public void setWxUpdateUrl(String wxUpdateUrl) {
this.wxUpdateUrl = wxUpdateUrl;
}
public String getFileSize() {
return fileSize;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
public String getUpdateRemark() {
return updateRemark;
}
public void setUpdateRemark(String updateRemark) {
this.updateRemark = updateRemark;
}
public boolean isNeedUpdate() {
return needUpdate;
}
public void setNeedUpdate(boolean needUpdate) {
this.needUpdate = needUpdate;
}
public String getUpdateUrl() {
return updateUrl;
}
public void setUpdateUrl(String updateUrl) {
this.updateUrl = updateUrl;
}
public int getServerVersion() {
return serverVersion;
}
public void setServerVersion(int serverVersion) {
this.serverVersion = serverVersion;
}
public boolean isForceUpdate() {
return forceUpdate;
}
public void setForceUpdate(boolean forceUpdate) {
this.forceUpdate = forceUpdate;
}
}
package com.mayi.fastdevelop.constant;
public class Key {
public static final String ANT_DOWNLOAD_ID = "ant_download_id";
}
package com.mayi.fastdevelop.util;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import java.util.Stack;
/**
* Activity堆栈管理
*/
public class ActivitysManager {
private static Stack<Activity> activityStack = new Stack<>();
/**
* 添加Activity到堆栈
*/
public static void addActivity(Activity activity) {
activityStack.push(activity);
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public static Activity currentActivity() {
return activityStack.lastElement();
}
/**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public static void finishCurrentActivity() {
Activity activity = activityStack.pop();
activity.finish();
}
/**
* 结束指定的Activity
*/
public static void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
if (!activity.isFinishing()) {
activity.finish();
}
}
}
/**
* 找到指定类名的Activity
*/
public static Activity getActivity(Class<?> cls) {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
return activity;
}
}
return null;
}
/**
* 结束指定类名的Activity
*/
public static void finishActivity(Class<?> cls) {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
}
}
}
/**
* 结束所有Activity
*/
public static void finishAllActivity() {
for (Activity activity : activityStack) {
if (activity != null) {
activity.finish();
}
}
activityStack.clear();
}
/**
* 退出应用程序
*/
public static void exitApp(Context context) {
try {
finishAllActivity();
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
manager.killBackgroundProcesses(context.getPackageName());
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.mayi.fastdevelop.util;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.webkit.MimeTypeMap;
import com.mayi.fastdevelop.constant.Key;
import java.io.File;
/**
* 下载更新的util 主要是负责 版本的相关更新工作
* 实际 下载更新的具体步骤:
* 将下载返回的ID存放在sharedPreference中
* 如果成功就直接跳转到安装界面
*/
public class DownLoadUtil {
public static String DOWNLOAD_FILE_NAME = "";
//使用DownloadManager 下载
public static void downLoadAPK(Context context, String url) {
DOWNLOAD_FILE_NAME= System.currentTimeMillis()+".apk";
Request request = new Request(Uri.parse(url));
//设置状态栏中显示Notification
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//设置可用的网络类型
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
//不显示下载界面
request.setVisibleInDownloadsUi(true);
//指定下载的路径为和上面创建的路径相同
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, DOWNLOAD_FILE_NAME);
//设置文件类型
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url));
request.setMimeType(mimeString);
request.setTitle(SystemUtil.getAppName(context));
//将请求加入请求队列会 downLoadManager会自动调用对应的服务执行者个请求
DownloadManager downLoadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
if (downLoadManager != null) {
long requestId = downLoadManager.enqueue(request);
SpUtil.set(Key.ANT_DOWNLOAD_ID, requestId);
}
}
//文件的安装 方法
public static boolean install(Context context, String filePath) {
Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(filePath);
if (file != null && file.length() > 0 && file.exists() && file.isFile()) {
intent.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
}
return false;
}
///获取当前下载进度
public static int[] getBytesAndStatus(Context context, long downloadId) {
DownloadManager downLoadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
int[] bytesAndStatus = new int[]{-1, -1, 0};
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
Cursor c = null;
try {
if (downLoadManager != null) {
c = downLoadManager.query(query);
if (c != null && c.moveToFirst()) {
bytesAndStatus[0] = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytesAndStatus[1] = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
bytesAndStatus[2] = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
}
}
} finally {
if (c != null) {
c.close();
}
}
return bytesAndStatus;
}
}
\ No newline at end of file
package com.mayi.fastdevelop.util;
import android.content.Context;
import com.mayi.fastdevelop.base.BaseApplication;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.Rationale;
import com.yanzhenjie.permission.RequestExecutor;
import java.io.File;
import java.util.List;
public class PermissionUtil {
/**
* 请求权限
*
* @param callback
* @param permissions
*/
public static void requestPermission(final PermissionCallback callback, final String... permissions) {
AndPermission.with(BaseApplication.getInstance().getChildApplication())
.runtime()
.permission(permissions)
.onGranted(new Action<List<String>>() {
@Override
public void onAction(List<String> data) {
callback.onSuccess(data);
}
})
.onDenied(new Action<List<String>>() {
@Override
public void onAction(List<String> data) {
callback.onFail(data);
}
}).start();
}
/**
* 安装APP
* @param callback
* @param pathname
*/
public static void installAPP(final PermissionInstallCallback callback, String pathname) {
AndPermission.with(BaseApplication.getInstance().getChildApplication())
.install()
.file(new File(pathname))
.rationale(new Rationale<File>() {
@Override
public void showRationale(Context c, File f, RequestExecutor e) {
}
})
.onGranted(new Action<File>() {
@Override
public void onAction(File data) {
callback.onSuccess();
}
})
.onDenied(new Action<File>() {
@Override
public void onAction(File data) {
callback.onFail();
}
})
.start();
}
public interface PermissionInstallCallback {
void onSuccess();
void onFail();
}
public interface PermissionCallback {
void onSuccess(List<String> data);
void onFail(List<String> data);
}
}
package com.mayi.fastdevelop.view;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.mayi.fastdevelop.R;
import com.mayi.fastdevelop.bean.AppConfig;
import com.mayi.fastdevelop.constant.Key;
import com.mayi.fastdevelop.util.ActivitysManager;
import com.mayi.fastdevelop.util.DownLoadUtil;
import com.mayi.fastdevelop.util.SpUtil;
import com.mayi.fastdevelop.view.dialog.BaseDialog;
import com.mayi.fastdevelop.view.dialog.DialogViewHolder;
/**
* APP 升级管理
*/
public class AppUpgradeManager {
private Context mContext;
// 进度条
private ProgressBar mProgressBar;
// 进度显示
private TextView mTxtPercent;
private TextView mTxtTotal;
private final int INTERVAL = 500;
public AppUpgradeManager(Context context) {
this.mContext = context;
}
/**
* 显示更新提示
*/
private void showUpdateTipDialog(final AppConfig info) {
new BaseDialog(mContext, R.layout.dialog_update) {
@Override
public void convert(DialogViewHolder holder) {
holder.setText(R.id.pack_content, info.getUpdateRemark());
holder.setText(R.id.pack_size, String.format(mContext.getResources().getString(R.string.package_size), info.getFileSize()));
holder.setOnClick(R.id.txt_sure, new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
showApkProgressDialog();
mHandler.post(mRunnable);
DownLoadUtil.downLoadAPK(mContext, info.getUpdateUrl());
}
});
holder.setOnClick(R.id.txt_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
//如果是强制更新 点击取消 直接退出app
ActivitysManager.exitApp(mContext);
}
});
}
}.fullWidth()
.setCancelAble(false)
.setCanceledOnTouchOutside(false)
.show();
}
/**
* 显示apk下载进度条
*/
private void showApkProgressDialog() {
new BaseDialog(mContext, R.layout.dialog_download_apk_progress) {
@Override
public void convert(DialogViewHolder holder) {
mProgressBar = holder.getConvertView().findViewById(R.id.progress_bar);
mTxtPercent = holder.getConvertView().findViewById(R.id.txt_percent);
mTxtTotal = holder.getConvertView().findViewById(R.id.txt_total);
mTxtPercent.setText("0%");
}
}.fullWidth()
.setCancelAble(false)
.setCanceledOnTouchOutside(false)
.show();
}
private void updateProgress(int percent, int total) {
int per = 0;
if (total == 0) {
per = 0;
} else {
per = (int) (percent * 100f / total);
}
if (mProgressBar != null) {
mProgressBar.setProgress(per);
}
if (mTxtPercent != null) {
mTxtPercent.setText(per + "%");
}
if (mTxtTotal != null) {
mTxtTotal.setText(percent + "/" + total);
}
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
try {
mHandler.postDelayed(this, INTERVAL);
final int[] arr = DownLoadUtil.getBytesAndStatus(mContext, SpUtil.get(Key.ANT_DOWNLOAD_ID, -1L));
if (arr[0] == arr[1]) {
mHandler.post(new Runnable() {
@Override
public void run() {
BaseDialog.getDialog().dismiss();
mHandler.removeCallbacks(mRunnable);
}
});
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
updateProgress(arr[0], arr[1]);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false;
}
});
}
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置背景 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp"/>
<stroke
android:width="@dimen/line_height"
android:color="@color/colorAccent"/>
<solid android:color="@color/white"/>
</shape>
</item>
<!-- 设置进度条颜色(红色) -->
<item android:id="@android:id/progress">
<scale
android:drawable="@drawable/bg_statistics_progress_drawable_shape1"
android:scaleWidth="100%"/>
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/shape_radius_default"/>
<solid android:color="@color/white"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置背景色(蓝色) -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp" />
<gradient
android:endColor="@color/gray"
android:startColor="@color/gray" />
</shape>
</item>
<!-- 设置进度条颜色(红色) -->
<item android:id="@android:id/progress">
<scale
android:drawable="@drawable/bg_statistics_progress_drawable_shape1"
android:scaleWidth="100%" />
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:endColor="@color/statistics_progress_bar_end_color"
android:startColor="@color/statistics_progress_bar_start_color" />
<corners android:radius="20dp" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="@color/white"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/shape_radius_default"/>
<solid android:color="@color/white"/>
<stroke
android:width="@dimen/line_height"
android:color="@color/colorAccent"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true">
<shape android:shape="rectangle">
<corners android:radius="@dimen/shape_radius_default"/>
<solid android:color="@color/color_DF0029"/>
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<corners android:radius="@dimen/shape_radius_default"/>
<solid android:color="@color/border_grey"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:background="@drawable/bg_statistics_white_round"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:text="@string/downloading"
android:textColor="@color/txt_black"
android:textSize="16sp" />
<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/title"
android:layout_marginTop="25dp"
android:background="@color/statistics_radar_color" />
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="250dp"
android:layout_height="10dp"
android:layout_below="@+id/line"
android:layout_centerHorizontal="true"
android:layout_marginTop="42dp"
android:max="100"
android:progressDrawable="@drawable/bg_statistics_progress_drawable_round" />
<TextView
android:id="@+id/txt_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/progress_bar"
android:layout_below="@+id/progress_bar"
android:layout_marginBottom="54dp"
android:layout_marginTop="12dp"
android:textColor="@color/colorAccent"
android:textSize="13sp" />
<TextView
android:id="@+id/txt_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/progress_bar"
android:layout_below="@+id/progress_bar"
android:layout_marginBottom="54dp"
android:layout_marginTop="12dp"
android:textColor="@color/colorAccent"
android:textSize="13sp" />
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_rectangle_white_radius"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/txt_title"
style="@style/txt_big"
android:layout_marginBottom="@dimen/space_40px"
android:layout_marginTop="@dimen/space_40px"
android:text="@string/app_version_update" />
<View style="@style/line_h" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible">
<TextView
android:id="@+id/pack_content"
style="@style/txt_normal"
android:padding="@dimen/space_30px" />
<TextView
android:id="@+id/pack_size"
style="@style/txt_normal"
android:layout_width="match_parent"
android:gravity="left"
android:paddingLeft="@dimen/space_30px" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginLeft="@dimen/space_30px"
android:layout_marginRight="@dimen/space_30px"
android:layout_marginTop="30dp"
android:orientation="horizontal">
<TextView
android:id="@+id/txt_cancel"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_marginRight="@dimen/space_40px"
android:layout_weight="1"
android:background="@drawable/bg_white_border_accent_rectangle"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/colorAccent"
android:textSize="@dimen/txt_size_36px" />
<TextView
android:id="@+id/txt_sure"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:background="@drawable/btn_accont_grey_radius"
android:gravity="center"
android:text="@string/sure"
android:textColor="@color/white"
android:textSize="@dimen/txt_size_36px" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="@dimen/space_30px"
android:layout_marginRight="@dimen/space_30px"
android:orientation="vertical">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="10dp"
android:max="100"
android:progress="50"
android:progressDrawable="@drawable/bg_progress_rount_border_accent" />
<TextView
style="@style/txt_normal"
android:layout_marginTop="@dimen/space_20px"
android:text="60%"
android:textColor="@color/colorAccent" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
...@@ -93,4 +93,9 @@ ...@@ -93,4 +93,9 @@
<color name="color_333333">#333333</color> <color name="color_333333">#333333</color>
<color name="color_666666">#666666</color> <color name="color_666666">#666666</color>
<color name="color_999999">#999999</color> <color name="color_999999">#999999</color>
<color name="color_DF0029">#DF0029</color>
<color name="statistics_progress_bar_start_color">#ffba43</color>
<color name="statistics_progress_bar_end_color">#ff8521</color>
<color name="statistics_radar_color">#cdcdcd</color>
</resources> </resources>
...@@ -7,5 +7,7 @@ ...@@ -7,5 +7,7 @@
<string name="sure">确定</string> <string name="sure">确定</string>
<string name="cancel">取消</string> <string name="cancel">取消</string>
<string name="back">返回</string> <string name="back">返回</string>
<string name="app_version_update">新版本发布</string>
<string name="package_size">更新包大小:%1$sM</string>
<string name="downloading">正在下载</string>
</resources> </resources>
...@@ -68,4 +68,26 @@ ...@@ -68,4 +68,26 @@
<item name="android:layout_height">@dimen/line_height</item> <item name="android:layout_height">@dimen/line_height</item>
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
</style> </style>
<!--textview默认设置-->
<style name="txt_default">
<item name="android:gravity">center_vertical|left</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColorHint">@color/txt_color_hint</item>
<item name="android:lineSpacingExtra">3dp</item>
<item name="android:textColor">@color/txt_black</item>
<item name="android:ellipsize">end</item>
</style>
<!--字体 大-->
<style name="txt_big" parent="txt_default">
<item name="android:textSize">@dimen/txt_size_32px</item>
</style>
<!--字体 常用-->
<style name="txt_normal" parent="txt_default">
<item name="android:textSize">@dimen/txt_size_28px</item>
</style>
</resources> </resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment