登陆时splash初始页调用接口检查app版本。如有更新,使用okGo的文件下载,保存到指定位置,调用Android安装apk。

<!-- Android 8.0 (Android O)为了针对一些流氓软件引导用户安装其他无关应用。在应用权限设置的“特殊访问权限”中,加入了“安装其他应用”的设置 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
package com.test.activity.sys;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast; import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.FileCallback;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.convert.FileConvert;
import com.lzy.okgo.model.Progress;
import com.lzy.okgo.model.Response;
import com.test.BuildConfig;
import com.test.Constant;
import com.test.R;
import com.test.activity.MainActivity;
import com.test.activity.sys.LoginActivity;
import com.test.util.DataUtils; import com.test.view.NumberProgressBar; import org.json.JSONException;
import org.json.JSONObject; import java.io.File;
import java.text.NumberFormat; /**
* @author cralor
* @date 2018/8/8
* 启动页 Activity
*/
public class SplashActivity extends Activity{ public static final int INSTALL_APK_REQUESTCODE = 3;
public static final int GET_UNKNOWN_APP_SOURCES = 7;
private File apkFile;
/**
* 可以额外指定文件的下载目录和下载完成后的文件名
*/
private String destFileDir = Environment.getExternalStorageDirectory() + FileConvert.DM_TARGET_FOLDER + "myAppDownload" + File.separator; private String destFileName = "myApp.apk"; private Handler handler;
private Context content;
private TextView tvDownloadSize;
private TextView tvProgress;
private TextView tvNetSpeed;
private NumberProgressBar pbProgress; private NumberFormat numberFormat;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
//去掉标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
// getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN ,WindowManager.LayoutParams. FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
content = this;
handler = new Handler(Looper.getMainLooper()); numberFormat = NumberFormat.getPercentInstance();
numberFormat.setMinimumFractionDigits(2);
initView();
} /**
* 打开程序时判断是否已经登陆过,且token有效
*/
private void initView() { // ... handler.postDelayed(new Runnable() {
@Override
public void run() {
OkGo.<String>post(Constant.GET_VERSION)
.tag(1)
.execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) { String data = response.body();
String code = "";
String sysVersion = "";
try {
JSONObject jsonObject = new JSONObject(data);
code = jsonObject.get("code").toString();
sysVersion = jsonObject.get("data").toString();
} catch (JSONException e) {
e.printStackTrace();
}
Log.v("data",""+code);
if(Constant.SUCCESS_CODE.equals(code)){ // Android studio 中 build.gradle 中的版本号
// 获取PackageManager的实例
PackageManager packageManager = getPackageManager();
// getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = null;
String appVersion = "";
try {
packInfo = packageManager.getPackageInfo(getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (packInfo != null) {
appVersion = packInfo.versionName;
} if(appVersion.equals(sysVersion)){
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
finish();
}else{
Log.e("SplashActivity","需要更新版本到---"+sysVersion);
Toast.makeText(content, "有新版本需要更新", Toast.LENGTH_SHORT).show();
getVersion();
}
}
}
@Override
public void onError(Response<String> response) {
Toast.makeText(content, "请求失败", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(intent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
finish();
}
});
}
}, 3);
} /**
* 更新弹出框
*/
public void getVersion(){
//退出的确认弹出框
new AlertDialog.Builder(content)
.setTitle("提示")
.setMessage("请更新最新版本")
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
Toast.makeText(content, "dianjixiazai ", Toast.LENGTH_SHORT).show();
fileDownload();
View view1 = getLayoutInflater().inflate(R.layout.update_app_progress, null); tvDownloadSize = view1.findViewById(R.id.downloadSize);
tvProgress = view1.findViewById(R.id.tvProgress);
tvNetSpeed = view1.findViewById(R.id.netSpeed);
pbProgress = view1.findViewById(R.id.pbProgress); AlertDialog.Builder builder = new AlertDialog.Builder(content);
builder.setTitle("正在下载");
builder.setView(view1);
builder.setCancelable(false);
builder.setNegativeButton("取消", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.create().show();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
})
.show();
} /**
* 获取服务器apk
*/
public void fileDownload() {
//检查是否获得写入权限,未获得则向用户请求。Android 7.0 以上需要动态获取权限
if (ActivityCompat.checkSelfPermission(SplashActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//未获得,向用户请求
ActivityCompat.requestPermissions(SplashActivity.this, new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 200);
}
OkGo.<File>get("https://app地址/app.apk")
.tag(1)
.headers("header1", "headerValue1")
.params("param1", "paramValue1")
/*
* 文件目录如果不指定,默认下载的目录为 sdcard/download/,文件名如果不指定,则按照以下规则命名:
1.首先检查用户是否传入了文件名,如果传入,将以用户传入的文件名命名
2.如果没有传入,那么将会检查服务端返回的响应头是否含有Content-Disposition=attachment;filename=FileName.txt该种形式的响应头,如果有,则按照该响应头中指定的文件名命名文件,如FileName.txt
3.如果上述响应头不存在,则检查下载的文件url,例如:http://image.baidu.com/abc.jpg,那么将会自动以abc.jpg命名文件
4.如果url也把文件名解析不出来,那么最终将以"unknownfile_" + System.currentTimeMillis()命名文件
*/
.execute(new FileCallback(""+destFileDir, ""+destFileName) {
@Override
public void onSuccess(Response<File> response) { String absolutePath = response.body().getAbsolutePath();
apkFile = response.body().getAbsoluteFile();
Log.e("appInstall---", ""+absolutePath); //Android8.0 版本更新无法自动安装问题解决
if (Build.VERSION.SDK_INT >= 26) {
//来判断应用是否有权限安装apk
Log.e("appInstall---", "android版本8.0以上");
boolean installAllowed= getPackageManager().canRequestPackageInstalls();
//有权限
if (installAllowed) {
//安装apk
Log.e("appInstall---", "有权限安装apk");
installApk(apkFile);
} else {
//无权限 申请权限
Log.e("appInstall---", "无权限 申请权限");
ActivityCompat.requestPermissions(SplashActivity.this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, INSTALL_APK_REQUESTCODE);
}
} else {
Log.e("appInstall---", "android版本低于8.0");
installApk(apkFile);
}
}
@Override
public void onError(Response<File> response) {
Throwable exception = response.getException();
exception.printStackTrace();
Log.e("eeeee", exception.getMessage());
}
@Override
public void downloadProgress(Progress progress) {
System.out.println(progress);
String downloadLength = Formatter.formatFileSize(getApplicationContext(), progress.currentSize);
String totalLength = Formatter.formatFileSize(getApplicationContext(), progress.totalSize);
tvDownloadSize.setText(downloadLength + "/" + totalLength);
String speed = Formatter.formatFileSize(getApplicationContext(), progress.speed);
tvNetSpeed.setText(String.format("%s/s", speed));
tvProgress.setText(numberFormat.format(progress.fraction));
pbProgress.setMax(10000);
pbProgress.setProgress((int) (progress.fraction * 10000));
}
});
}
/**
* 权限申请回调
* @param requestCode requestCode
* @param permissions permissions
* @param grantResults grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case INSTALL_APK_REQUESTCODE:
//有注册权限且用户允许安装
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("appInstall---", "有注册权限且用户允许安装");
installApk(apkFile);
} else {
//将用户引导至安装未知应用界面。
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
startActivityForResult(intent, GET_UNKNOWN_APP_SOURCES);
Log.e("appInstall---", "将用户引导至安装未知应用界面");
}
break;
default:break;
}
}
/**
* 将用户引导至安装未知应用界面,允许安装未知应用后,回到当前activity继续安装应用
* @param requestCode requestCode
* @param resultCode resultCode
* @param data data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e("appInstall---", "将用户引导至安装未知应用界面,允许安装未知应用后,回到当前activity继续安装应用");
installApk(apkFile);
}
/**
* 安装APK
* @param apkFile apkFile
*/
public void installApk(File apkFile){
//判读版本是否在7.0以上
if(Build.VERSION.SDK_INT >= 24) {
Log.e("appInstall---", "android版本7.");
//在AndroidManifest中的android:authorities的值, BuildConfig.APPLICATION_ID = com.test
Uri apkUri = FileProvider.getUriForFile(content, BuildConfig.APPLICATION_ID+".provider", apkFile);
       Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(install);
} else {
Log.e("appInstall---", "android版本低于7.0");
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(install); }
finish();
} /**
* 调用默认浏览器下载apk
*/
public void getApk(){
Uri uri = Uri.parse("https://lighttruck.com.cn:8086/app.apk");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
} }
activity_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context="com.test.activity.sys.SplashActivity"> </LinearLayout>

初始页面自定义主题
<!-- 加载页面 -->
<activity
android:name=".activity.sys.SplashActivity"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
   <style name="SplashTheme" parent="AppBaseTheme">
<!-- 欢迎页背景引用刚才写好的 -->
<item name="android:windowBackground">@drawable/splash</item>
<item name="android:windowFullscreen">true</item>
<!-- <item name="android:windowIsTranslucent">true</item> --> <!-- 透明背景 -->
</style>

update_app_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/update_app_progress"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/bg_gray"
android:orientation="vertical" > <RelativeLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="10dp"> <TextView
android:id="@+id/downloadSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="--M/--M"
android:textSize="10sp"/> <TextView
android:id="@+id/netSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:text="---K/s"
android:textSize="10sp"/> <TextView
android:id="@+id/tvProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="--.--%"
android:textSize="10sp"/> </RelativeLayout> <com.test.view.NumberProgressBar
android:id="@+id/pbProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:progress_reached_bar_height="1.5dp"
app:progress_reached_color="#3498DB"
app:progress_text_color="#3498DB"
app:progress_text_size="10sp"
app:progress_unreached_bar_height="0.75dp"
app:progress_unreached_color="#CCCCCC"/>
</LinearLayout>
NumberProgressBar 为okGo中的view
/*
* Copyright 2016 jeasonlzy(廖子尧)
*
* 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.test.view; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View; import com.test.R; /**
* ================================================
* 作 者:jeasonlzy(廖子尧)Github地址:https://github.com/jeasonlzy
* 版 本:1.0
* 创建日期:16/9/11
* 描 述:
* 修订历史:
* ================================================
*/
public class NumberProgressBar extends View { public interface OnProgressBarListener { void onProgressChange(int current, int max);
} private int mMaxProgress = 100; /**
* Current progress, can not exceed the max progress.
*/
private int mCurrentProgress = 0; /**
* The progress area bar color.
*/
private int mReachedBarColor; /**
* The bar unreached area color.
*/
private int mUnreachedBarColor; /**
* The progress text color.
*/
private int mTextColor; /**
* The progress text size.
*/
private float mTextSize; /**
* The height of the reached area.
*/
private float mReachedBarHeight; /**
* The height of the unreached area.
*/
private float mUnreachedBarHeight; /**
* The suffix of the number.
*/
private String mSuffix = "%"; /**
* The prefix.
*/
private String mPrefix = ""; private final int default_text_color = Color.rgb(66, 145, 241);
private final int default_reached_color = Color.rgb(66, 145, 241);
private final int default_unreached_color = Color.rgb(204, 204, 204);
private final float default_progress_text_offset;
private final float default_text_size;
private final float default_reached_bar_height;
private final float default_unreached_bar_height; /**
* For save and restore instance of progressbar.
*/
private static final String INSTANCE_STATE = "saved_instance";
private static final String INSTANCE_TEXT_COLOR = "text_color";
private static final String INSTANCE_TEXT_SIZE = "text_size";
private static final String INSTANCE_REACHED_BAR_HEIGHT = "reached_bar_height";
private static final String INSTANCE_REACHED_BAR_COLOR = "reached_bar_color";
private static final String INSTANCE_UNREACHED_BAR_HEIGHT = "unreached_bar_height";
private static final String INSTANCE_UNREACHED_BAR_COLOR = "unreached_bar_color";
private static final String INSTANCE_MAX = "max";
private static final String INSTANCE_PROGRESS = "progress";
private static final String INSTANCE_SUFFIX = "suffix";
private static final String INSTANCE_PREFIX = "prefix";
private static final String INSTANCE_TEXT_VISIBILITY = "text_visibility"; private static final int PROGRESS_TEXT_VISIBLE = 0; /**
* The width of the text that to be drawn.
*/
private float mDrawTextWidth; /**
* The drawn text start.
*/
private float mDrawTextStart; /**
* The drawn text end.
*/
private float mDrawTextEnd; /**
* The text that to be drawn in onDraw().
*/
private String mCurrentDrawText; /**
* The Paint of the reached area.
*/
private Paint mReachedBarPaint;
/**
* The Paint of the unreached area.
*/
private Paint mUnreachedBarPaint;
/**
* The Paint of the progress text.
*/
private Paint mTextPaint; /**
* Unreached bar area to draw rect.
*/
private RectF mUnreachedRectF = new RectF(0, 0, 0, 0);
/**
* Reached bar area rect.
*/
private RectF mReachedRectF = new RectF(0, 0, 0, 0); /**
* The progress text offset.
*/
private float mOffset; /**
* Determine if need to draw unreached area.
*/
private boolean mDrawUnreachedBar = true; private boolean mDrawReachedBar = true; private boolean mIfDrawText = true; /**
* Listener
*/
private OnProgressBarListener mListener; public enum ProgressTextVisibility {
Visible, Invisible
} public NumberProgressBar(Context context) {
this(context, null);
} public NumberProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public NumberProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); default_reached_bar_height = dp2px(1.5f);
default_unreached_bar_height = dp2px(1.0f);
default_text_size = sp2px(10);
default_progress_text_offset = dp2px(3.0f); //load styled attributes.
final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.NumberProgressBar, defStyleAttr, 0); mReachedBarColor = attributes.getColor(R.styleable.NumberProgressBar_progress_reached_color, default_reached_color);
mUnreachedBarColor = attributes.getColor(R.styleable.NumberProgressBar_progress_unreached_color, default_unreached_color);
mTextColor = attributes.getColor(R.styleable.NumberProgressBar_progress_text_color, default_text_color);
mTextSize = attributes.getDimension(R.styleable.NumberProgressBar_progress_text_size, default_text_size); mReachedBarHeight = attributes.getDimension(R.styleable.NumberProgressBar_progress_reached_bar_height, default_reached_bar_height);
mUnreachedBarHeight = attributes.getDimension(R.styleable.NumberProgressBar_progress_unreached_bar_height, default_unreached_bar_height);
mOffset = attributes.getDimension(R.styleable.NumberProgressBar_progress_text_offset, default_progress_text_offset); int textVisible = attributes.getInt(R.styleable.NumberProgressBar_progress_text_visibility, PROGRESS_TEXT_VISIBLE);
if (textVisible != PROGRESS_TEXT_VISIBLE) {
mIfDrawText = false;
} setProgress(attributes.getInt(R.styleable.NumberProgressBar_progress_current, 0));
setMax(attributes.getInt(R.styleable.NumberProgressBar_progress_max, 100)); attributes.recycle();
initializePainters();
} @Override
protected int getSuggestedMinimumWidth() {
return (int) mTextSize;
} @Override
protected int getSuggestedMinimumHeight() {
return Math.max((int) mTextSize, Math.max((int) mReachedBarHeight, (int) mUnreachedBarHeight));
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false));
} private int measure(int measureSpec, boolean isWidth) {
int result;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight();
result += padding;
if (mode == MeasureSpec.AT_MOST) {
if (isWidth) {
result = Math.max(result, size);
} else {
result = Math.min(result, size);
}
}
}
return result;
} @Override
protected void onDraw(Canvas canvas) {
if (mIfDrawText) {
calculateDrawRectF();
} else {
calculateDrawRectFWithoutProgressText();
} if (mDrawReachedBar) {
canvas.drawRect(mReachedRectF, mReachedBarPaint);
} if (mDrawUnreachedBar) {
canvas.drawRect(mUnreachedRectF, mUnreachedBarPaint);
} if (mIfDrawText) canvas.drawText(mCurrentDrawText, mDrawTextStart, mDrawTextEnd, mTextPaint);
} private void initializePainters() {
mReachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mReachedBarPaint.setColor(mReachedBarColor); mUnreachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mUnreachedBarPaint.setColor(mUnreachedBarColor); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextSize(mTextSize);
} private void calculateDrawRectFWithoutProgressText() {
mReachedRectF.left = getPaddingLeft();
mReachedRectF.top = getHeight() / 2.0f - mReachedBarHeight / 2.0f;
mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() + getPaddingLeft();
mReachedRectF.bottom = getHeight() / 2.0f + mReachedBarHeight / 2.0f; mUnreachedRectF.left = mReachedRectF.right;
mUnreachedRectF.right = getWidth() - getPaddingRight();
mUnreachedRectF.top = getHeight() / 2.0f + -mUnreachedBarHeight / 2.0f;
mUnreachedRectF.bottom = getHeight() / 2.0f + mUnreachedBarHeight / 2.0f;
} private void calculateDrawRectF() { mCurrentDrawText = String.format("%d", getProgress() * 100 / getMax());
mCurrentDrawText = mPrefix + mCurrentDrawText + mSuffix;
mDrawTextWidth = mTextPaint.measureText(mCurrentDrawText); if (getProgress() == 0) {
mDrawReachedBar = false;
mDrawTextStart = getPaddingLeft();
} else {
mDrawReachedBar = true;
mReachedRectF.left = getPaddingLeft();
mReachedRectF.top = getHeight() / 2.0f - mReachedBarHeight / 2.0f;
mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() - mOffset + getPaddingLeft();
mReachedRectF.bottom = getHeight() / 2.0f + mReachedBarHeight / 2.0f;
mDrawTextStart = (mReachedRectF.right + mOffset);
} mDrawTextEnd = (int) ((getHeight() / 2.0f) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2.0f)); if ((mDrawTextStart + mDrawTextWidth) >= getWidth() - getPaddingRight()) {
mDrawTextStart = getWidth() - getPaddingRight() - mDrawTextWidth;
mReachedRectF.right = mDrawTextStart - mOffset;
} float unreachedBarStart = mDrawTextStart + mDrawTextWidth + mOffset;
if (unreachedBarStart >= getWidth() - getPaddingRight()) {
mDrawUnreachedBar = false;
} else {
mDrawUnreachedBar = true;
mUnreachedRectF.left = unreachedBarStart;
mUnreachedRectF.right = getWidth() - getPaddingRight();
mUnreachedRectF.top = getHeight() / 2.0f + -mUnreachedBarHeight / 2.0f;
mUnreachedRectF.bottom = getHeight() / 2.0f + mUnreachedBarHeight / 2.0f;
}
} /**
* Get progress text color.
*
* @return progress text color.
*/
public int getTextColor() {
return mTextColor;
} /**
* Get progress text size.
*
* @return progress text size.
*/
public float getProgressTextSize() {
return mTextSize;
} public int getUnreachedBarColor() {
return mUnreachedBarColor;
} public int getReachedBarColor() {
return mReachedBarColor;
} public int getProgress() {
return mCurrentProgress;
} public int getMax() {
return mMaxProgress;
} public float getReachedBarHeight() {
return mReachedBarHeight;
} public float getUnreachedBarHeight() {
return mUnreachedBarHeight;
} public void setProgressTextSize(float textSize) {
this.mTextSize = textSize;
mTextPaint.setTextSize(mTextSize);
invalidate();
} public void setProgressTextColor(int textColor) {
this.mTextColor = textColor;
mTextPaint.setColor(mTextColor);
invalidate();
} public void setUnreachedBarColor(int barColor) {
this.mUnreachedBarColor = barColor;
mUnreachedBarPaint.setColor(mUnreachedBarColor);
invalidate();
} public void setReachedBarColor(int progressColor) {
this.mReachedBarColor = progressColor;
mReachedBarPaint.setColor(mReachedBarColor);
invalidate();
} public void setReachedBarHeight(float height) {
mReachedBarHeight = height;
} public void setUnreachedBarHeight(float height) {
mUnreachedBarHeight = height;
} public void setMax(int maxProgress) {
if (maxProgress > 0) {
this.mMaxProgress = maxProgress;
invalidate();
}
} public void setSuffix(String suffix) {
if (suffix == null) {
mSuffix = "";
} else {
mSuffix = suffix;
}
} public String getSuffix() {
return mSuffix;
} public void setPrefix(String prefix) {
if (prefix == null) mPrefix = "";
else {
mPrefix = prefix;
}
} public String getPrefix() {
return mPrefix;
} public void incrementProgressBy(int by) {
if (by > 0) {
setProgress(getProgress() + by);
} if (mListener != null) {
mListener.onProgressChange(getProgress(), getMax());
}
} public void setProgress(int progress) {
if (progress <= getMax() && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
} @Override
protected Parcelable onSaveInstanceState() {
final Bundle bundle = new Bundle();
bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor());
bundle.putFloat(INSTANCE_TEXT_SIZE, getProgressTextSize());
bundle.putFloat(INSTANCE_REACHED_BAR_HEIGHT, getReachedBarHeight());
bundle.putFloat(INSTANCE_UNREACHED_BAR_HEIGHT, getUnreachedBarHeight());
bundle.putInt(INSTANCE_REACHED_BAR_COLOR, getReachedBarColor());
bundle.putInt(INSTANCE_UNREACHED_BAR_COLOR, getUnreachedBarColor());
bundle.putInt(INSTANCE_MAX, getMax());
bundle.putInt(INSTANCE_PROGRESS, getProgress());
bundle.putString(INSTANCE_SUFFIX, getSuffix());
bundle.putString(INSTANCE_PREFIX, getPrefix());
bundle.putBoolean(INSTANCE_TEXT_VISIBILITY, getProgressTextVisibility());
return bundle;
} @Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
final Bundle bundle = (Bundle) state;
mTextColor = bundle.getInt(INSTANCE_TEXT_COLOR);
mTextSize = bundle.getFloat(INSTANCE_TEXT_SIZE);
mReachedBarHeight = bundle.getFloat(INSTANCE_REACHED_BAR_HEIGHT);
mUnreachedBarHeight = bundle.getFloat(INSTANCE_UNREACHED_BAR_HEIGHT);
mReachedBarColor = bundle.getInt(INSTANCE_REACHED_BAR_COLOR);
mUnreachedBarColor = bundle.getInt(INSTANCE_UNREACHED_BAR_COLOR);
initializePainters();
setMax(bundle.getInt(INSTANCE_MAX));
setProgress(bundle.getInt(INSTANCE_PROGRESS));
setPrefix(bundle.getString(INSTANCE_PREFIX));
setSuffix(bundle.getString(INSTANCE_SUFFIX));
setProgressTextVisibility(bundle.getBoolean(INSTANCE_TEXT_VISIBILITY) ? ProgressTextVisibility.Visible : ProgressTextVisibility.Invisible);
super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
return;
}
super.onRestoreInstanceState(state);
} public float dp2px(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
} public float sp2px(float sp) {
final float scale = getResources().getDisplayMetrics().scaledDensity;
return sp * scale;
} public void setProgressTextVisibility(ProgressTextVisibility visibility) {
mIfDrawText = visibility == ProgressTextVisibility.Visible;
invalidate();
} public boolean getProgressTextVisibility() {
return mIfDrawText;
} public void setOnProgressBarListener(OnProgressBarListener listener) {
mListener = listener;
}
}

Android 6.0 7.0 8.0 一个简单的app内更新版本-okgo app版本更新的更多相关文章

  1. 一个简单的数据增量更新策略(Android / MongoDB / Django)

    我在做个人APP - CayKANJI - 的时候遇到一个问题: 如何增量式地把日语汉字数据地从server更新到APP端,即每次用户运行更新操作时,仅仅获取版本号高于本地缓存的内容. 数据格式 为了 ...

  2. Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载)

    http://blog.csdn.net/yanzi1225627/article/details/21294553 原文

  3. 用.netcore写一个简单redis驱动,调试windows版本的redis.平且给set和get命令添加参数.

    1. 下载windows版本的redis 2.开发环境vs2017  新建一个 .net core控制台. private static Socket socket = new Socket(Addr ...

  4. 实现一个简单的WebSocket聊天室

    WebSocket 简介 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主 ...

  5. SmartSql使用教程(1)——初探,建立一个简单的CURD接口服务

    一.引言 最近SmartSql被正式引入到了NCC,借着这个契机写一个使用教程系列 二.SmartSql简介[摘自官方文档] 1. SmartSql是什么? SmartSql = MyBatis + ...

  6. Django入门第一步:构建一个简单的Django项目

    Django入门第一步:构建一个简单的Django项目 1.简介 Django是一个功能完备的Python Web框架,可用于构建复杂的Web应用程序.在本文中,将通过示例跳入并学习Django.您将 ...

  7. Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tool

    重装操作系统后,要重新配置Android开发环境.配置成功后,添加原本项目时却出现了错误! Android requires compiler compliance level 5.0 or 6.0. ...

  8. Android 自定义View修炼-仿QQ5.0 的侧滑菜单效果的实现

    有一段时间没有写博客了,最近比较忙,没什么时间写,刚好今天有点时间, 我就分享下,侧滑菜单的实现原理,一般android侧滑的实现原理和步骤如下:(源码下载在下面最后给出哈) 1.使用ViewGrou ...

  9. Android获取设备隐私 忽略6.0权限管理

    1.前言 (1).由于MIUI等部分国产定制系统也有权限管理,没有相关api,故无法判断用户是否允许获取联系人等隐私.在Android 6.0之后,新增权限管理可以通过官方api判断用户的运行状态: ...

随机推荐

  1. eclipse异常关闭,而Tomcat然在运行解决方法

    1.eclipse异常关闭,而Tomcat然在运行,再启动tomcat会出现端口冲突 解决方法:打开任务管理器,找到javaw.exe,点击关闭,就可以了

  2. HTTP&HTTPS、GET&POST

    1.HTTP&HTTPS: HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure ...

  3. 通过Get-Group导出组的成员

    导出组邮箱的前十个成员,需要注意的是: Get-Group没有Get-GroupMember命令,但是在结果中有一个Members的属性,这个属性包含了所有子成员的对象,用循环将它们列出来即可.有点对 ...

  4. 网页正文提取,降噪的实现(readability/Document)

    安装: pip install readability-lxml 使用: # encoding:utf-8import html2textimport requestsimport refrom re ...

  5. filebeat向kafka中传输数据报WARN Failed to connect to broker DOMSDev07:9092: dial tcp: lookup DOMSDev07: getaddrinfow: No such host is known.解决方法

    打开filebeat客户端所在机器C:\Windows\System32\drivers\etc目录,找到hosts文件 以记事本形式打开,在底部追加 “IP 主机名” 即可

  6. UVA 12633 Super Rooks on Chessboard(FFT)

    题意: 给你一个R*C的棋盘,棋盘上的棋子会攻击,一个棋子会覆盖它所在的行,它所在的列,和它所在的从左上到右下的对角线,那么问这个棋盘上没有被覆盖的棋盘格子数.数据范围R,C,N<=50000 ...

  7. zabbix自定义web检测

    zabbix自定义web检测 本博客使用zabbix 版本 4.0.3 Web监控的原理 Web监控即对HTTP服务的监控,模拟用户去访问网站,对特定的结果进行比较,如状态码.返回字符串等特定的数据进 ...

  8. easyui布局隐藏伸缩按钮

    1. 在html中加入 <script> /** * layout方法扩展 * @param {Object} jq * @param {Object} region */ $.exten ...

  9. DAY6-Python学习笔记

    前记: 坚持写学习笔记今天是第六天了,今天事情有点多想起来还没写赶快补起来,学习Python已经快一个星期了,大部分的知识点已经跟着廖雪峰老师的教程了解了一下,由于自学能力不强还有很多知识点掌握不牢固 ...

  10. http站点如何启用为https站点?对收录的影响

    首先看一下百度官方对https站点的态度:百度开放收录https站点公告 百度搜索再次推出:全面支持https页面直接收录:另外从相关性的角度,百度搜索引擎认为权值相同的站点,采用https协议的页面 ...