• Adroid Studio app远程升级


     手机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 {
                        //这里就是权限打开之后自己要操作的逻辑
    
                    }
                }
            }
        }
    }
    .Net Core
  • 相关阅读:
    <庆余年>
    JUC-12.3-线程的调度
    JUC-12.1-线程池介绍
    JUC-12.2-线程池使用
    JUC-11-线程八锁
    JUC-10-ReadWriteLock读写锁
    JUC-9-线程按序交替
    JUC-8-lock和Condition使用
    JUC-7-lock接口
    xcode单词及回调
  • 原文地址:https://www.cnblogs.com/zpy1993-09/p/15500039.html
Copyright © 2020-2023  润新知