李堇 2023-05-08 11:33 采纳率: 52.8%
浏览 41
已结题

android设备出现更新apk失败问题

应用程序检测到版本不一致时会跳更新页面,让用户点击更新操作,但是有些机器总是出现下载对话框是进度条不动,然后自动关闭进度条的现象。代码中使用简单的下载,代码如下:

public class UpdateService {

    private static OkHttpClient okHttpClient;

    public static void download(final String fileName,String url, final UpdateCallback callback) {
        Request request = new Request.Builder()
                .addHeader("Accept-Encoding", "identity")
                .url(url).build();

        if (okHttpClient == null) {
            okHttpClient = new OkHttpClient();
        }

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callback.onFailure();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.body() == null) {
                    callback.onFailure();
                    return;
                }

                File filePath = new File(CommonConstants.DOWNLOAD_PATH);
                if (!filePath.exists()) {
                    filePath.mkdirs();
                }

                long contentLength = response.body().contentLength();
                byte[] buffer = new byte[1024];
                File file = new File(filePath.getCanonicalPath(), fileName);
                try (InputStream is = response.body().byteStream();
                     FileOutputStream fos = new FileOutputStream(file)) {
                     //Log.d("保存路径:" , file.getAbsolutePath());

                    int length;
                    long sum = 0;
                    while ((length = is.read(buffer)) != -1) {
                        fos.write(buffer, 0, length);
                        sum += length;
                        int progress = (int) (sum * 1.0f / contentLength * 100);
                        callback.onProgress(progress);
                    }
                    fos.flush();

                    callback.onSuccess();
                } catch (Exception e) {
                    callback.onFailure();
                }
            }
        });
    }

    public interface UpdateCallback {

        void onSuccess();

        void onProgress(int progress);

        void onFailure();
    }

}


业务中检测到不一致时执行如下代码:

UpdateService.download(fileName,apkUpdateUrl, new UpdateService.UpdateCallback() {
            @Override
            public void onSuccess() {
                dialog.dismiss();
                if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    return;
                }

                File file = new File(CommonConstants.DOWNLOAD_PATH + fileName);
                try {
                   //下载成功好调用安装
                    installApk(file);
                } catch (Exception e) {
                    Log.e("获取打开方式错误", e.getMessage());
                }
            }

            @Override
            public void onProgress(int progress) {
                dialog.setProgress(progress);
            }

            @Override
            public void onFailure() {
                dialog.dismiss();
            }
        });

  • 写回答

4条回答 默认 最新

  • 极客智能体-在线 2023-05-11 16:44
    关注

    以下答案由GPT-3.5大模型与博主波罗歌共同编写:
    这种情况可能是由于网络问题导致下载失败。你可以在下载的过程中添加一些额外的处理来排除一些可能的问题。

    1. 检查网络连接状态:由于下载涉及到网络,所以应该首先检查设备的网络连接状态。可以使用ConnectivityManager类来获取设备的网络状态信息。

    2. 设置下载超时:设定下载的超时时间,防止在下载文件时网络连接被中断而下载失败。

    修改网络请求代码如下:

    public static void download(final String fileName, String url, final UpdateCallback callback) {
        Request request = new Request.Builder()
            .addHeader("Accept-Encoding", "identity")
            .url(url)
            .build();
    
        if (okHttpClient == null) {
            okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .build();
        }
    
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callback.onFailure();
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.body() == null) {
                    callback.onFailure();
                    return;
                }
    
                File filePath = new File(CommonConstants.DOWNLOAD_PATH);
                if (!filePath.exists()) {
                    filePath.mkdirs();
                }
    
                long contentLength = response.body().contentLength();
                byte[] buffer = new byte[1024];
                File file = new File(filePath.getCanonicalPath(), fileName);
                try (InputStream is = response.body().byteStream();
                     FileOutputStream fos = new FileOutputStream(file)) {
                     
                    int length;
                    long sum = 0;
                    while ((length = is.read(buffer)) != -1) {
                        fos.write(buffer, 0, length);
                        sum += length;
                        int progress = (int) (sum * 1.0f / contentLength * 100);
                        callback.onProgress(progress);
                    }
                    fos.flush();
    
                    callback.onSuccess();
                } catch (Exception e) {
                    callback.onFailure();
                }
            }
        });
    }
    
    1. 添加下载失败重试机制:在下载过程中,如果下载失败了,可以再次尝试下载。可以添加一个计数器,在下载失败时递增,当达到一定次数时,提示用户下载失败。

    修改下载过程中的回调方法如下:

    @Override
    public void onFailure(Call call, IOException e) {
        if (retryCount < MAX_RETRY_COUNT) {
            // 继续尝试下载,重试次数+1
            retryCount++;
            download(fileName, url, callback);
        } else {
            callback.onFailure();
        }
    }
    

    完整的更新代码如下:

    public class UpdateService {
        private static final int MAX_RETRY_COUNT = 3; // 最大重试次数
        private static OkHttpClient okHttpClient;
    
        public static void download(final String fileName, String url, final UpdateCallback callback) {
            Request request = new Request.Builder()
                .addHeader("Accept-Encoding", "identity")
                .url(url)
                .build();
    
            if (okHttpClient == null) {
                okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .build();
            }
    
            okHttpClient.newCall(request).enqueue(new Callback() {
                private int retryCount = 0;
    
                @Override
                public void onFailure(Call call, IOException e) {
                    if (retryCount < MAX_RETRY_COUNT) {
                        // 继续尝试下载,重试次数+1
                        retryCount++;
                        download(fileName, url, callback);
                    } else {
                        callback.onFailure();
                    }
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.body() == null) {
                        callback.onFailure();
                        return;
                    }
    
                    File filePath = new File(CommonConstants.DOWNLOAD_PATH);
                    if (!filePath.exists()) {
                        filePath.mkdirs();
                    }
    
                    long contentLength = response.body().contentLength();
                    byte[] buffer = new byte[1024];
                    File file = new File(filePath.getCanonicalPath(), fileName);
                    try (InputStream is = response.body().byteStream();
                         FileOutputStream fos = new FileOutputStream(file)) {
    
                        int length;
                        long sum = 0;
                        while ((length = is.read(buffer)) != -1) {
                            fos.write(buffer, 0, length);
                            sum += length;
                            int progress = (int) (sum * 1.0f / contentLength * 100);
                            callback.onProgress(progress);
                        }
                        fos.flush();
    
                        callback.onSuccess();
                    } catch (Exception e) {
                        callback.onFailure();
                    }
                }
            });
        }
    
        public interface UpdateCallback {
    
            void onSuccess();
    
            void onProgress(int progress);
    
            void onFailure();
        }
        
        // 其他方法
    }
    

    如果我的回答解决了您的问题,请采纳!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 5月19日
  • 已采纳回答 5月11日
  • 创建了问题 5月8日

悬赏问题

  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化