之前有篇博文是使用第三方蒲公英提示更新,但是蒲公英更新推荐大家内测使用,实际的开发中我们还得需要自己来编写版本更新代码,我就简单了写了一个简单demo,大致的功能就是如果有新的版本,提示更新下载到sd卡位置 不多说怼代码:
代码中用到了okhttp框架相信大家都会导入就不在这写了.
demo目录(Android studio): 效果图:
json数据:(versionName版本号,url是apk下载的地址,title是更新的内容)
{
"versionName": "1.02",
"versionCode": 1,
"url": "http://100.100.110.1/IXCd8a8c6a3058ab4c74b4e3af99c6c2fb7/data/wisegame/
09bd127e31d541a2/weibo_3424.apk",
"title": "1、新版本提示
2、换行测试
2、换行测试"
}
1、activity_main布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.wdl.updatedemo.MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="检查新版本" />
</RelativeLayout>
2、创建dialog.xml布局,显示弹框
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:orientation="vertical"
>
<TextView
android:layout_margin="10dp"
android:id="@+id/text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="更新内容"
android:textSize="18sp" />
<TextView
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="更改部分bug,添加XXX功能,优化XXX,那是不可能滴"
android:textSize="18sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_alignParentBottom="true"
android:id="@+id/ll"
android:background="#ccc"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<Button
android:id="@+id/close"
android:layout_width="0dp"
android:background="@drawable/btn_selector"
android:layout_weight="1"
android:layout_marginRight="0.5dp"
android:layout_height="wrap_content"
android:layout_marginTop="0.5dp"
android:text="取消" />
<Button
android:id="@+id/download"
android:layout_width="0dp"
android:background="@drawable/btn_selector"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginTop="0.5dp"
android:text="立即更新" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
3、在res文件夹下创建drawable文件夹,在drawable文件夹下创建btn_selector.xml文件(用来给Button按钮设置按下时颜色)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/ccc"/>
<item android:drawable="@color/fff"/>
</selector>
colors.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="transparent">#00000000</color>
<color name="ccc">#cccccc</color>
<color name="fff">#ffffffff</color>
</resources>
<style name="loading_dialog"> <item name="android:windowFrame">@null</item><!--边框--> <item name="android:windowNoTitle">true</item><!--无标题--> <item name="android:windowIsFloating">true</item><!--是否浮现在activity之上--> <item name="android:windowAnimationStyle">@style/Theme.AppCompat.Dialog</item><!--样式--> </style>
4、创建自定义弹框dialogActivity:
public class dialogActivity extends Dialog {
public Context context;
private View view;
public dialogActivity(Context context) {
super(context);
this.context=context;
}
protected dialogActivity(Context context, int cancelable) {
super(context, cancelable);
this.context=context;
LayoutInflater inflater= LayoutInflater.from(context);
view = inflater.inflate(R.layout.dialog, null);
}
public void close(){
dialogActivity.this.dismiss();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(view);
// 获取屏幕宽、高用
Window dialogWindow = this.getWindow();
DisplayMetrics dm = new DisplayMetrics();
dialogWindow.getWindowManager().getDefaultDisplay().getMetrics(dm);
WindowManager.LayoutParams p = dialogWindow.getAttributes();
// 屏幕的高0.5
p.height = (int) (dm.heightPixels * 0.5);
// 屏幕的宽0.8
p.width = (int) (dm.widthPixels * 0.8);
dialogWindow.setAttributes(p);
//按返回键是否可以退出 默认true可以退出 false禁止
this.setCancelable(true);
}
@Override
public View findViewById(int id) {
return super.findViewById(id);
}
public View getCustomView() {
return view;
}
}
5、MainActivity.java
public class MainActivity extends AppCompatActivity {
//json数据
String date;
//json数据中版本号,下载地址和标题
String code,url,title;
//给用户显示的版本号
String versionName;
//用户不可见控制版本号
int versionCode;
int versionCode_code;//json数据中的versioncode
public dialogActivity dialog;
//调用更新布局id使用
public View view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏标题栏
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
Button btn= (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AndroidDown();
}
});
//自定义dialog
dialog = new dialogActivity(MainActivity.this,R.style.loading_dialog);
view = dialog.getCustomView();
//获取当前应用的版本号和版本名称
AndroidDown();
//点击事件
initdate();
}
//提示更新框上的两个按钮点击事件
private void initdate() {
Button close= (Button) view.findViewById(R.id.close);
Button dowm_btn= (Button) view.findViewById(R.id.download);
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.close();
}
});
dowm_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
down();
dialog.close();
}
});
}
private void AndroidDown() {
//获取packagemanager的实例
PackageManager packageManager = getPackageManager();
try {
//getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
versionName=packInfo.versionName;
versionCode=packInfo.versionCode;
//获取的是手机安装应用的版本号
Toast.makeText(MainActivity.this,"当前版本号是:"+versionName,Toast.LENGTH_SHORT).show();
//获取json数据
init();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
} ;
}
//获取json数据
private void init() {
//网络请求写到线程中
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient okhttp=new OkHttpClient();
Request request=new Request.Builder().url("http://192.168.1.6/json.json").build();
try {
Response response=okhttp.newCall(request).execute();
//得到数据
date=response.body().string();
//打印数据是否正确
Message mes=new Message();
mes.what=1;
han.sendMessage(mes);
//解析
JsonJX(date);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
//解析json数据
public void JsonJX(String date) throws JSONException {
JSONObject json=new JSONObject(date);
//显示的版本号
code=json.getString("versionName");
//apk下载地址
url=json.getString("url");
//修改内容
title=json.getString("title");
//版本号
versionCode_code=json.getInt("versionCode");
//进行主线程更新
Message mes=new Message();
mes.what=2;
han.sendMessage(mes);
}
//系统自带下载功能
public void down(){
DownloadManager dManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(uri);
// 设置下载路径和文件名(download文件夹下)
request.setDestinationInExternalPublicDir("download", "ceshi.apk");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setMimeType("application/vnd.android.package-archive");
// 设置为可被媒体扫描器找到
request.allowScanningByMediaScanner();
// 设置为可见和可管理
request.setVisibleInDownloadsUi(true);
long refernece = dManager.enqueue(request);
// 把当前下载的ID保存起来
SharedPreferences sPreferences = getSharedPreferences("dialog", 0);
sPreferences.edit().putLong("is", refernece).commit();
}
public Handler han=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
Toast.makeText(MainActivity.this,"数据"+date,Toast.LENGTH_LONG).show();
break;
case 2:
//判断当前版本号和json数据解析的版本号是否一致
if(versionCode>=versionCode_code){
//如果应用当前的版本大就不更新
Toast.makeText(MainActivity.this,"目前是最新版本!",Toast.LENGTH_LONG).show();
}else{
//如果获取json数据里的versionCode_code大就提示更新界面
TextView tv= (TextView) view.findViewById(R.id.title);
tv.setText(title);
//显示弹框
dialog.show();
}
break;
}
}
};
}
Android开发中控制app版本号的是versioncode而不是versionname,versionname只是显示给用户看的版本信息,versioncode通过改变值得大小来控制版本更改信息(必须比原来的值大)
6、创建广播接收者DialogReceiver.java(用来接收下载完成后发送的广播来提示用户安装界面,也可以不创建但是不是提示安装),大家可以试试不创建是什么效果
public class DialogReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
long myDwonloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
SharedPreferences sPreferences = context.getSharedPreferences("dialog", 0);
long refernece = sPreferences.getLong("is", 0);
if (refernece == myDwonloadID) {
String serviceString = Context.DOWNLOAD_SERVICE;
DownloadManager dManager = (DownloadManager) context.getSystemService(serviceString);
Intent install = new Intent(Intent.ACTION_VIEW);
Uri downloadFileUri = dManager.getUriForDownloadedFile(myDwonloadID);
install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
}
}
}
7、不要忘记在AndroidManifest.xml中注册广播和使用到的权限
<receiver android:name=".DialogReceiver">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
好了到这就实现了提示更新下载.这里使用的是Android系统的下载器,如果大家想要自定义下载布局请转到博文:http://blog.csdn.net/wcbcslg/article/details/46364453