coocs2dx 整包更新 android DownloadManager下载和安装

吉岳
2023-12-01

最近在弄android整包下载,使用到Downloadmanager 

下载和安装,新手尝试,欢迎大家指正。

关于 FileProvider 百度一下很简单。

public class ApkDownloadMgr {

//下载器

private DownloadManager m_dMgr;

private Context m_context;

private long m_downloadID = 0;

private String apkName ="";

private String apkPath = "";

private String file_name = "download_id";

private boolean hasRegister = false;  


private final String GW_LINK = "http://xxx.com"; //下载失败直接打开移动官网


private int returnType_1 = 1; //浏览器下载 

private int returnType_2 = 2; //app内下载 或者 删除文件成功重新下载

private int returnType_3 = 3; //已下载成功,直接安装

private int returnType_4 = 4; //删除文件失败


public static final Uri CONTENT_URI = Uri.parse("content://downloads/my_downloads");  

private DownLoadChangeObserver downloadObserver;

private Activity m_activity;

private String saveName = ""; //保存到文件到下载文件名字 

private enum CheckType{

CHECK_BEFOR_DOWN,

CHECK_AFTER_DOWN

};


public ApkDownloadMgr(Context context,Activity activity)

{

this.m_context = context;

m_activity = activity;


}


private boolean canDownloadState(Context ctx) {

        try {

            int state = ctx.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");

            if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED

                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER

                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {

                return false;

            }

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

        return true;

    }


//下载apk

public int downloadApk(String url,String name)

{

//创建下载任务

//创建下载任务

if( !canDownloadState(m_context)) { // 不可用 

//浏览器下载


return returnType_1;

}

apkName = name;

      //获取DownloadManager

        m_dMgr = (DownloadManager) m_context.getSystemService(Context.DOWNLOAD_SERVICE);

//File file = new File(m_context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),name);

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), apkName);

if(file.exists()) {  //判断文件是否存在 

System.out.println("文件存在 "+file.getName());


if(readSaveFile()){//判断下载任务记录是否存在 

//判断任务id的状态 

checkStatus(CheckType.CHECK_BEFOR_DOWN);

//installAPK();

return returnType_3;

}else{

//删除下载的文件 

if(!file.delete())

{

return returnType_4;

}

}

}


        Request request = new Request(Uri.parse(url));

        //移动网络情况下是否允许漫游

        request.setAllowedOverRoaming(false);

        //在通知栏中显示,默认就是显示的 隐藏通知栏

        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);

        request.setTitle(name);

        request.setVisibleInDownloadsUi(true);

        request.allowScanningByMediaScanner();

       

        String path = Environment.getExternalStorageDirectory().getAbsolutePath();

        //设置下载的路径

        //request.setDestinationInExternalPublicDir(path , name);

       

        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);

       

        apkPath = Environment.DIRECTORY_DOWNLOADS+"/"+name;

        System.out.println(" 文件路径 "+apkPath);

        System.out.println("  Environment.DIRECTORY_DOWNLOADS "+ Environment.DIRECTORY_DOWNLOADS);

        

        //将下载请求加入下载队列,加入下载队列后会给该任务返回一个long型的id,通过该id可以取消任务,重启任务、获取下载的文件等等

        m_downloadID= m_dMgr.enqueue(request);

        

        writeDownloadId(m_downloadID,name);  //下载开始后保存下载id;

      //在通知栏显示下载进度

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

            request.allowScanningByMediaScanner();

            //request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

        }

        //注册广播接收者,监听下载状态 

        m_context.registerReceiver(receiver,

                new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

        downloadObserver = new DownLoadChangeObserver(null);

        

        m_context.getContentResolver().registerContentObserver(CONTENT_URI, true, downloadObserver);

        

        hasRegister = true;

        return returnType_2;

}


/*

* 应该保存任务id 和 对应但文件名

* 目前只保存了任务id 

*/

private void writeDownloadId(long did,String name){

try{

FileOutputStream fout = m_context.openFileOutput(file_name, Context.MODE_PRIVATE); //保存到data/data/包名/files/ (可写目录)

    Log.i(" msg ", String.valueOf(did));

    System.out.println(did);

    String strTemp = String.valueOf(did)+","+name;

    byte [] bytes = strTemp.getBytes(); 

    fout.write(bytes); 

    fout.flush();

    fout.close(); 

    Log.d("msg", " -- write download_id succe ");

}catch(Exception e){ 

e.printStackTrace();

Log.d("msg", " -- write download_id falied ");

    } 

}


private boolean readSaveFile() {

        FileInputStream inputStream;

        try {

        File  file = new File(m_context.getFilesDir().getAbsolutePath(),file_name);

        if(!file.exists()) 

        {

        System.out.println(file_name +" no file read failed ");

        return false;

        }

            inputStream = m_context.openFileInput(file_name);

            byte temp[] = new byte[1024];

            StringBuilder sb = new StringBuilder("");

            int len = 0;

            while ((len = inputStream.read(temp)) > 0){

                sb.append(new String(temp, 0, len));

            }

            Log.d("msg", "readSaveFile: " + sb.toString());

            String fileStr = sb.toString();

            if(fileStr != ""){

            String[] strs = fileStr.split(",");

            m_downloadID = Long.parseLong(strs[0]);

            saveName = strs[1];

            }

            inputStream.close();

            return true;

        } catch (Exception e) {

            e.printStackTrace();

        }

        return false;

    }

private BroadcastReceiver receiver = new BroadcastReceiver() {


@Override

public void onReceive(Context arg0, Intent arg1) {


checkStatus(CheckType.CHECK_AFTER_DOWN);

}

};


//检查下载状态

    private void checkStatus(CheckType checkStatus) {

        Query query = new Query();

        //通过下载的id查找

        query.setFilterById(m_downloadID);

        System.out.println(" create c ");

        Cursor c = m_dMgr.query(query);

        System.out.println(" create c 2");

        if (c == null ) 

        System.out.println("下载任务不存在 ");

        if (c!=null && c.moveToFirst()) {

            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

            System.out.println(" --- status "+status);

            switch (status) {

                 //下载暂停

                case DownloadManager.STATUS_PAUSED:

                if (checkStatus == CheckType.CHECK_BEFOR_DOWN) {

//如果是创建新任务之前检测任务状态 任务暂停状态直接跳转浏览器

                AppActivity.openWebURL(GW_LINK); //跳转浏览器

}

                    break;

                //下载延迟

                case DownloadManager.STATUS_PENDING:

                

                    break;

                //正在下载

                case DownloadManager.STATUS_RUNNING:

                System.out.println("---- start running --");

                if (checkStatus == CheckType.CHECK_BEFOR_DOWN) {

                Log.d("-- check status", " 新任务 前检测");

//如果是创建新任务之前检测任务状态 添加广播监听

                m_context.registerReceiver(receiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

                        downloadObserver = new DownLoadChangeObserver(null);

                        

                        m_context.getContentResolver().registerContentObserver(CONTENT_URI, true, downloadObserver);

                        

                        hasRegister = true;

}

                    break;

                //下载完成

                case DownloadManager.STATUS_SUCCESSFUL:

                System.out.println("---- start download --");

                    //下载完成安装APK

                //isGoging=false;

                    

                    installAPK(c);

                    break;

                //下载失败

                case DownloadManager.STATUS_FAILED:

                //isGoging=false;

                Toast.makeText(m_context, "下载失败", Toast.LENGTH_SHORT).show();

                if(hasRegister){

                    m_context.unregisterReceiver(receiver);

                    	m_context.getContentResolver().unregisterContentObserver(downloadObserver);

                    }

                AppActivity.openWebURL(GW_LINK); //跳转浏览器

                    break;

            }

        }

        c.close();

    }


  //下载到本地后执行安装

    private void installAPK(Cursor c) {

    

    //if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)

    if(Build.VERSION.SDK_INT >= 24)

    {

    System.out.println("--- install apk on 7.0 --");

    System.out.println(" apkpath "+apkPath);

//    File file= new File(apkPath);

    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), apkName);

    	System.out.println("--- install apk 1  --");

     

    Uri apkUri = FileProvider.getUriForFile(m_context, "com.xxx.fileprovider", file);//在AndroidManifest中的android:authorities值

            System.out.println("--- install apk 2  --");

            Intent install = new Intent(Intent.ACTION_VIEW);

//            install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            //添加这一句表示对目标应用临时授权该Uri所代表的文件

            install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            install.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            install.setDataAndType(apkUri, "application/vnd.android.package-archive");

            System.out.println("--- install apk 3  --");

            m_context.startActivity(install);

            if(hasRegister){

            m_context.unregisterReceiver(receiver);

            m_context.getContentResolver().unregisterContentObserver(downloadObserver);

            }

            System.out.println("--- install apk on 7.0 end --");

    }else {

    //获取下载文件的Uri

    if(m_dMgr == null) m_dMgr = (DownloadManager) m_context.getSystemService(Context.DOWNLOAD_SERVICE);

          Uri downloadFileUri = m_dMgr.getUriForDownloadedFile(m_downloadID);

          if (downloadFileUri != null) {

              Intent intent= new Intent(Intent.ACTION_VIEW);

              intent.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");

              //以下trycatch 是为处理 Error receiving broadcast Intent { act=android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.kamron.pogoiv (has extras) } 这个错误

              //三星 5c pro会发生此异常

  try {

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

m_context.startActivity(intent);

System.out.println(" --正常逻辑 安装完成");

  } catch (ActivityNotFoundException e) {

  e.printStackTrace();

String filePath= c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));

Intent installIntent = new Intent(Intent.ACTION_VIEW);

            installIntent.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");

            installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            m_context.startActivity(installIntent);

            System.out.println(" --try catch 安装完成");

  }

if(hasRegister){

              m_context.unregisterReceiver(receiver);

              m_context.getContentResolver().unregisterContentObserver(downloadObserver);

              }

          }

    }

    }

    

    private class DownLoadChangeObserver extends ContentObserver{

public DownLoadChangeObserver(Handler handler) {

super(handler);


}


@Override

public void onChange(boolean selfChange) {

queryDownloadStatus();

}

    

    }

    //只查询进度

    private void queryDownloadStatus() {     

        DownloadManager.Query query = new DownloadManager.Query();     

        query.setFilterById(m_downloadID);     

        Cursor c = m_dMgr.query(query);     

        if(c!=null&&c.moveToFirst()) {     

            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));        

            switch(status) {     

            case DownloadManager.STATUS_PAUSED:     

                Log.v("tag", "STATUS_PAUSED");    

            case DownloadManager.STATUS_PENDING:     

                Log.v("tag", "STATUS_PENDING");    

            case DownloadManager.STATUS_RUNNING:     

                Log.v("tag", "STATUS_RUNNING");    

                /**

                 * 计算下载下载率;

                 */

                int totalSize = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

                int currentSize = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));

                final int progress = (int) (((float) currentSize) / ((float) totalSize) * 100);

                System.out.println(" -----percent  "+progress);

                ((AppActivity)m_activity).runOnGLThread(new Runnable() {


@Override

public void run() {

int ret = Cocos2dxLuaJavaBridge.callLuaGlobalFunctionWithString("receiveUpdateProgress", progress+"");

Log.d(" --- runable  ", " ret  "+ret);

}

});

                break;     

            case DownloadManager.STATUS_SUCCESSFUL:     

                //完成    

                Log.v("tag", "383 下载完成");    

//              dowanloadmanager.remove(lastDownloadId);  

                ((AppActivity)m_activity).runOnGLThread(new Runnable() {


@Override

public void run() {

int ret = Cocos2dxLuaJavaBridge.callLuaGlobalFunctionWithString("receiveUpdateProgress", "100");

Log.d(" --- runable  ", " ret  "+ret);

}

});

                break;     

            case DownloadManager.STATUS_FAILED:     

                //清除已下载的内容,重新下载    

                Log.v("tag", "STATUS_FAILED");        

                break;     

            }     

        }    

    } 
}

 类似资料: