使用阿里云OSS免费实现APP远程更新

注册阿里云(新用户免费试用3个月)

试用 OSS存储

在这里插入图片描述

进入控制台

Bucket列表新建自定义Bucket

在这里插入图片描述

上传文件至Bucket中

在这里插入图片描述

获取文件的网络地址

在这里插入图片描述

设置为公共读写

在项目中添加阿里云sdk

在这里插入图片描述

创建accessKey

在这里插入图片描述

展示网络图片


```java
 imageUrls.add("https://up.oss-cn-hangzhou.aliyuncs.com/APP/banner.png");
     

private void setBannerImageS(){
        for (String imageUrl : imageUrls) {
            Glide.with(requireActivity())
                    .asBitmap()
                    .load(imageUrl)
                    //缓存
//                    .diskCacheStrategy(DiskCacheStrategy.NONE)
//                    .skipMemoryCache(true)
                    .placeholder(R.mipmap.banner3)
                    .into(new CustomTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                            // 加载成功
                            loadedBitmaps.add(resource);
                            loadedCount++;
                            checkLoadComplete(); // 检查是否所有图片都已加载
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {
                            // 清除资源时调用,可以不做处理
                        }

                        @Override
                        public void onLoadFailed(@Nullable Drawable errorDrawable) {
                            super.onLoadFailed(errorDrawable);
                            // 加载失败
                            Log.e("Glide", "图片加载失败: " + imageUrl);
                            loadedCount++;
                            checkLoadComplete();//检查是否所有图片都已加载
                        }
                    });

        }
    }

    private void checkLoadComplete() {
        if (loadedCount == imageUrls.size()) {
            // 所有图片加载完成
            if (loadedBitmaps.size() > 0) {
                // 至少有一张图片加载成功,使用加载成功的图片
                binding.banner.setAdapter(new BannerBitmapAdapter(loadedBitmaps))
                        .setIndicator(new CircleIndicator(getActivity()))
                        .setIndicatorSpace(6)
                        .setIndicatorGravity(IndicatorConfig.Direction.CENTER)
                        .setLoopTime(6000)
                        .setOnBannerListener((data, position) -> {
                            // 图片点击事件
                        }).start();
            } else {
                // 所有图片都加载失败,使用默认图片
                binding.banner.setAdapter(new BannerImageAdapter(imagesUrl))
                        .setIndicator(new CircleIndicator(getActivity()))
                        .setIndicatorSpace(6)
                        .setIndicatorGravity(IndicatorConfig.Direction.CENTER)
                        .setLoopTime(6000)
                        .setOnBannerListener((data, position) -> {
                            // 图片点击事件
                        }).start();
            }
        }
    }

用于远程升级APP


    String ak = "ak";
    String sk = "sk";

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";

    OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(ak, sk);
 private void init() {
        ossClient = new OSSClient(requireActivity().getApplicationContext(), endpoint, credentialProvider);

        GetObjectRequest get = new GetObjectRequest("senappup", "APP/app.apk");

        ossClient.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                // 使用 ExecutorService 代替 AsyncTask 进行文件处理
                ExecutorService executor = Executors.newSingleThreadExecutor();
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        File file = downloadAndSaveFile(result);
                        if (file != null) {
                            // 在主线程安装 APK
                            installApk(requireActivity().getApplicationContext(), file.getAbsolutePath());
                        } else {
                            // 在主线程显示错误信息
                            requireActivity().runOnUiThread(() -> Toaster.showShort("下载或写入文件失败"));
                        }
                    }
                });
            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientException, ServiceException serviceException) {
                // 在主线程显示错误信息
                requireActivity().runOnUiThread(() -> {
                    if (clientException != null) {
                        Toaster.showShort("网络请求失败:" + clientException.toString());
                        Log.e("TAG", "onFailure ClientException:" + clientException.toString());
                    }
                    if (serviceException != null) {
                        Toaster.showShort("OSS 服务错误:" + serviceException.toString());
                        Log.e("TAG", "onFailure ServiceException:" + serviceException.toString());
                    }
                });
            }
        });
    }

    private File downloadAndSaveFile(GetObjectResult result) {
        long length = result.getContentLength();
        if (length > 0) {
            byte[] buffer = new byte[(int) length];
            int readCount = 0;
            try {
                while (readCount < length) {
                    int read = result.getObjectContent().read(buffer, readCount, (int) length - readCount);
                    if (read == -1) break; // 检查是否读取到文件末尾
                    readCount += read;
                }
            } catch (IOException e) {
                OSSLog.logInfo(e.toString());
                return null; // 返回 null 表示写入失败
            } finally {
                try {
                    result.getObjectContent().close(); // 确保关闭输入流
                } catch (IOException e) {
                    OSSLog.logInfo(e.toString());
                }
            }

            try {
                String fileName = "your_app.apk";
                File file = new File(requireActivity().getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), fileName);
                FileOutputStream fout = new FileOutputStream(file);
                fout.write(buffer);
                fout.close();
                return file; // 返回 File 对象
            } catch (Exception e) {
                OSSLog.logInfo(e.toString());
                return null; // 返回 null 表示写入失败
            }
        }
        return null; // 返回 null 表示文件长度为 0
    }

    /**
     * 安装apk
     */
    private static void installApk(Context mContext, String fileName) {
        Log.d("SelfUpdate", fileName);
        File apk = new File(fileName);
        try {
            // 这里有文件流的读写,需要处理一下异常
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                //如果SDK版本>=24,即:Build.VERSION.SDK_INT >= 24
                String packageName = mContext.getApplicationContext().getPackageName();
                String authority = new StringBuilder(packageName).append(".fileprovider").toString();
                Uri uri = FileProvider.getUriForFile(mContext, authority, apk);
                intent.setDataAndType(uri, "application/vnd.android.package-archive");
            } else {
                Uri uri = Uri.fromFile(apk);
                intent.setDataAndType(uri, "application/vnd.android.package-archive");
            }
            Log.d("SelfUpdate", "installApk");
            mContext.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            // 安装的时候会进行版本自动检测,更新版本小于已有版本,是会走当前异常的,注意!
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值