Logo

Adroid Studio app远程升级

photo

2023年09月19日

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

首先要在AndroidManifest添加版本号。

 

 远程升级类

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 {
                    //这里就是权限打开之后自己要操作的逻辑

                }
            }
        }
    }
}

 

本文为原创文章,请注意保留出处!

热门文章

修复群晖Synology Drive client右键菜单缺失问题 本教程主要解决windows10右键菜单中没有SynologyDrive菜单的问题,整体思路是找到...修复群晖SynologyDriveclient右键菜单缺失问题 作者:Pastore Antonio
1827 浏览量
docker如何查看一个镜像内部的目录结构及其内部都有哪些文件 前言:有时候我们会在docker上下载一个镜像,或者是上传一个镜像到docker上,甚至有时候就是在...docker如何查看一个镜像内部的目录结构及其内部都有哪些文件 作者:Pastore Antonio
1808 浏览量
configure: error: Package requirements (oniguruma) were not met configure:error:Packagerequirements(oniguruma)...configure:error:Packagerequirements(oniguruma)werenotmet 作者:Pastore Antonio
1536 浏览量
Adobe Acrobat Pro 激活 这里记录了一些AdobeAcrobat的激活教程和组件。浏览量:1,688 作者:Pastore Antonio
1535 浏览量
追寻日出,找回自己 为什么我要去追寻日出?其实我是一个很懒的人,每次都起不来,直到有一次我在租房中睡到了大天亮,阳光照...追寻日出,找回自己 作者:Pastore Antonio
1515 浏览量