Adroid Studio app远程升级

摘要:
手机APP开发完成后,需要远程自动升级版本。否则,每次更新版本都必须重新安装,这是不合理的。一开始,我觉得自己没有头绪,于是我让百度复制、粘贴、修复、修改和更改它,并直接将代码放入:首先,在Android Manifest中添加版本号。

 手机APP开发完了,远程升级自动更新版本必不可少,不然每次更新版本就要重新安装,那就不合理了。刚开始感觉还没啥头绪,不会了就问百度,复制粘贴修修改改就搞定了,直接上代码:

首先要在AndroidManifest添加版本号。

Adroid Studio app远程升级第1张

 远程升级类

package com.example.appview.Common;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;

import java.io.File;
import java.io.IOException;

public class AppUpdataManger {
    private String tag = "AppUpdataManger";
    private DownloadManager downloadManager;
    private Context mContext;
    private long mTaskId;
    private String downloadPath;
    private String versionName;

    public AppUpdataManger(Context context) {
        this.mContext = context;

    }

    //广播接收者,接收下载状态
    private BroadcastReceiver receiver = new BroadcastReceiver() {


        @Override
        public void onReceive(Context context, Intent intent) {
            checkDownloadStatus();//检查下载状态
        }
    };
    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
    public void downloadAPK(String versionUrl, String versionName) {
        this.versionName = versionName;
        Log.e("下载", versionUrl + versionName);
        //将下载请求加入下载队列
        downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        //创建下载任务
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(versionUrl));
        request.setAllowedOverRoaming(false);//漫游网络是否可以下载
        //设置文件类型,可以在下载结束后自动打开该文件
        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
        String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(versionUrl));
        request.setMimeType(mimeString);//加入任务队列
        //在通知栏显示,默认就是显示的
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        //设置通知栏标题
        request.setTitle("Download");
        request.setDescription("OYVFit Downloading...");
        request.setAllowedOverRoaming(false);
        request.setVisibleInDownloadsUi(true);
        //设置下载的路径
        File file = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), versionName);
        request.setDestinationUri(Uri.fromFile(file));
        downloadPath = file.getAbsolutePath();
        //加入下载列后会给该任务返回一个long型的id,
        //通过该id可以取消任务,重启任务等等
        mTaskId = downloadManager.enqueue(request);
        //注册广播接收,监听下载状态
        mContext.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

    }


    //检查下载状态
    private void checkDownloadStatus() {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(mTaskId);//赛选下载任务,传入任务ID,可变参数
        Cursor cursor = downloadManager.query(query);
        if (cursor.moveToFirst()) {
            int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            switch (status) {
                case DownloadManager.STATUS_PAUSED:
                    //下载暂停
                    Log.d(tag, "下载暂停");
                    break;
                case DownloadManager.STATUS_PENDING:
                    //下载延迟
                    Log.d(tag, "下载延迟");
                    break;
                case DownloadManager.STATUS_RUNNING:
                    //正在下载
                    Log.d(tag, "正在下载");
                    break;
                case DownloadManager.STATUS_SUCCESSFUL:
                    Toast.makeText(mContext, "下载完成", Toast.LENGTH_LONG).show();
                    //打开文件进行安装
                    installAPK();
                    break;
                case DownloadManager.STATUS_FAILED:
                    //下载失败
                    Log.d(tag, "下载失败");
                    Toast.makeText(mContext, "更新失败", Toast.LENGTH_LONG).show();
                    break;

            }
        }
        cursor.close();
    }

    //下载到本地后执行安装根据获得的id进行安装
    protected void installAPK() {
        setPermission(downloadPath);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        // 由于没有在Activity环境下启动Activity,设置下面的标签
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //Android 7.0以上要使用FileProvider
        if (Build.VERSION.SDK_INT >= 24) {
            File file = (new File(downloadPath));
            //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
            Uri apkUri = FileProvider.getUriForFile(mContext, "com.example.appview.fileProvider", file);
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(new File(Environment.DIRECTORY_DOWNLOADS, versionName)), "application/vnd.android.package-archive");
        }
        mContext.startActivity(intent);

    }

    //修改文件权限
    private void setPermission(String absolutePath) {
        String command = "chmod " + "777" + " " + absolutePath;
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec(command);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

判断远程是否需要升级是根据版本号来判断的,所以你要在数据库要有一个版本列表的。每次登录都要获取数据库中最新版本和本地版本作比较。较之低的话,启用远程升级。

package com.example.appview;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

import com.example.appview.Common.AppUpdataManger;
import com.example.appview.Common.HttpRequestHelper;
import com.example.appview.Common.MyMD5;
import com.example.appview.mian_page.Activity.LoginMainPage;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Activity.Preject_Item_Img;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    private EditText user_edit;
    private EditText passward_edit;
    private CheckBox remeber_check;
    private Button login_btn;
    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor ;//获取编辑器
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
            finish();
            return;
        }
        setContentView(R.layout.activity_main);

       user_edit=findViewById(R.id.user_edit);
       passward_edit=findViewById(R.id.passward_edit);
       remeber_check=findViewById(R.id.remeber_passward);
       login_btn=findViewById(R.id.login_btn);
        updateversion();
        quanxian();

        sharedPreferences = getSharedPreferences("userInfo", Context.MODE_PRIVATE);
        editor = sharedPreferences.edit();//获取编辑器
        boolean isRemember = sharedPreferences.getBoolean("remember_password",false);
        if (isRemember){
            String Name = sharedPreferences.getString("loginname","");
            String Password = sharedPreferences.getString("userpassward","");
            user_edit.setText(Name);
            passward_edit.setText(Password);
            remeber_check.setChecked(true);
        }else{
            user_edit.setText("");
            passward_edit.setText("");
            remeber_check.setChecked(false);
        }
        login_btn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              String username=user_edit.getText().toString();
              String userpassward=passward_edit.getText().toString();
              if (username.isEmpty()||userpassward.isEmpty())
              {
                  Toast.makeText(MainActivity.this, "用户名和密码不能为空!", Toast.LENGTH_LONG).show();
                  return;
              }else{
                  String repassward= MyMD5.MD5Capital(userpassward);
                  String url="AppPro_UserLogin?username="+username+"&password="+repassward;
                  new Thread(){
                      @Override
                      public void run() {
                          try {
                              String result= HttpRequestHelper.get(url);
                              Log.i("url",result);
                              SaveUserInfo(result);
                          } catch (JSONException | IOException e) {
                              e.printStackTrace();
                          }
                      }
                  }.start();

              }
          }
      });
    }
    private void SaveUserInfo(String result) throws JSONException {
        JSONObject result_json=new JSONObject(result);
      Log.i("data=",result_json.toString());
        if ( Integer.parseInt( result_json.getString("success"))==1){
            int uid=0;
            JSONArray data=result_json.getJSONArray("data");
            for (int i = 0; i < data.length(); i++) {
                JSONObject object=data.getJSONObject(i);
                uid=Integer.parseInt(object.getString("uid"));
                editor.putInt("UserID", Integer.parseInt(object.getString("uid")));
                editor.putInt("DepartId", Integer.parseInt(object.getString("DepartId")));
                editor.putString("departname",object.getString("departname"));
                editor.putString("realname",object.getString("realname"));
                editor.putString("Phone",object.getString("Phone"));
            }
            if (remeber_check.isChecked()){
                //remember_password
                editor.putBoolean("remember_password",true);
                editor.putString("loginname",user_edit.getText().toString());
                editor.putString("userpassward",passward_edit.getText().toString());
            }else{
                editor.putBoolean("remember_password",false);
            }
            //版本存储
            editor.putString("banben",getVersionName(getApplicationContext()));
            editor.commit();//提交修改
            Intent intent=new Intent(MainActivity.this, LoginMainPage.class);
            startActivity(intent);
        }else{
            Message message=new Message();
            message.what=1;
            handler.sendMessage(message);
        }

    }
    //数据回调
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    Toast.makeText(MainActivity.this,"账号密码错误",Toast.LENGTH_SHORT).show();
                    break;
                case 2:
                    try {
                        SaveVersionInfo(msg.obj.toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    break;

                default:
                    break;
            }

        }
    };
    private void updateversion(){
        String updateurl="AppPro_UpLog";
        new Thread(){
            @Override
            public void run() {
                try {
                    String result= HttpRequestHelper.get(updateurl);
                    Message message=new Message();
                    message.what=2;
                    message.obj=result;
                    handler.sendMessage(message);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }
    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
    private void SaveVersionInfo(String result) throws JSONException {
        JSONObject result_json=new JSONObject(result);
        int versioncode=1;
        String versionname="1.0";
        if ( Integer.parseInt( result_json.getString("success"))==1){

            JSONArray data=result_json.getJSONArray("data");
            for (int i = 0; i < data.length(); i++) {
                JSONObject object=data.getJSONObject(i);
                // Log.i("TW1",String.valueOf(object.getDouble("TW1"))+"°C");
                versioncode=object.getInt("editionId");
                versionname=object.getString("editionName");

            }

        }
        int version= getVersionCode(getApplicationContext());
        if (version<versioncode){
            AppUpdataManger appUpdataManger=new AppUpdataManger(getApplicationContext());
            appUpdataManger.downloadAPK("http://124.160.103.218:1111/upFile/app-release.apk",versionname);
        }

    }
    //版本名
    public static String getVersionName(Context context) {
        return getPackageInfo(context).versionName;
    }
    //版本号
    public static int getVersionCode(Context context) {
        return getPackageInfo(context).versionCode;
    }

    //获取版本info
    private static PackageInfo getPackageInfo(Context context) {
        PackageInfo pi = null;

        try {
            PackageManager pm = context.getPackageManager();
            pi = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_CONFIGURATIONS);

            return pi;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return pi;
    }
    /**
     * 手机文件读写权限的授权
     */
    public void quanxian(){

        if (Build.VERSION.SDK_INT >= 23) {
            int REQUEST_CODE_CONTACT = 101;
            String[] permissions = {
                    Manifest.permission.WRITE_EXTERNAL_STORAGE};
            //验证是否许可权限
            for (String str : permissions) {
                if (MainActivity.this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
                    //申请权限
                    MainActivity.this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
                    return;
                } else {
                    //这里就是权限打开之后自己要操作的逻辑

                }
            }
        }
    }
}

免责声明:文章转载自《Adroid Studio app远程升级》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇antd-design LocaleProvider国际化CentOS基础命令大全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

android 事件分发机制详解(OnTouchListener,OnClick)

  昨天做东西做到触摸事件冲突,以前也经常碰到事件冲突,想到要研究一下Android的事件冲突机制,于是从昨天开始到今天整整一天时间都要了解这方面的知识,这才懂了安卓的触摸和点击事件的机制。探究如下:   首先重写三个View布局,用来做测试:      package com.example.yzj.android_8_10; import andro...

ASP.NET Core:使用EntityFrameworkCore操作MySql来丰富仓储模块

概述 上一篇简单介绍了Dapper的基本用法,数据的存储为SqlServer。那么这一篇就记录一下使用EFCore来操作MySql的一些方式,这种模式比较适合那种一个项目中需要操作多种数据库的模式。不过因为微软官方并没有提供其驱动,所以我们需要借助MySql官方提供的驱动进行基本的增删改查操作。这样一来我们也可以将数据库迁移到Linux服务器上了,是不是很...

转:android中APK开机自动运行

背景知识:当Android启动时,会发出一个系统广播,内容为ACTION_BOOT_COMPLETED,它的字符串常量表示为android.intent.action.BOOT_COMPLETED。只要在程序中“捕捉”到这个消息,再启动之即可。记住,Android框架说:Don't call me, I'll call you back。我们要做的是做好接...

Tomcat学习总结(2)——Tomcat使用详解

一、Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件。 如果想修改Tomcat服务器的启动端口,则可以在server.xml配置文件中的Connector节点进行的端口修改 例如:将Tomcat服务器的启动端口由默认的8080改成8081端口 Tomcat服务器启动端口默认配置 1...

图片轮播插件-carouFredSel

carouFredSel图片轮播插件基于Jquery,比较常规的轮播插件,支持滚轮及键盘左右按键,加入其它插件可实现更加复杂的特效。 主页地址:http://caroufredsel.dev7studios.com/ 例子: html: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio...

Android夜间模式的几种实现

一、直接修改widget颜色,这种方式实现起来最简单,但需要每个控件都去修改,太过复杂。例如: /** * 相应交互,修改控件颜色 * @param view */ public void onMethod1Click(View view) { if (view.getId() == R.id....