React-Native 实现安卓下载软件

巩才捷
2023-12-01

Android原生代码

CommonConstants.java

package com.ifoxsmartfactory;

import android.os.Environment;

import java.io.File;

public class CommonConstants {
    private static final String DEMO_PATH = Environment.getExternalStorageDirectory() + "/download" + File.separator;
    public static final String DOWNLOAD_PATH = DEMO_PATH + File.separator + "download" + File.separator;
}

UpdateService.java

import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class UpdateService {

    private static OkHttpClient okHttpClient;

    public static void download(final String url, final String fileName, final UpdateCallback callback) {
        Log.e("url==", url + "");
        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();
                }
                Log.e("filePath:", filePath + "");

                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.e("保存路径:", 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) {
                    Log.e("error:",e.getMessage());
                    callback.onFailure();
                }
            }
        });
    }

    public interface UpdateCallback {

        void onSuccess();

        void onProgress(int progress);

        void onFailure();
    }
}

AppDownLoad.java

import android.content.Intent;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class AppDownLoad extends ReactContextBaseJavaModule {
    @NonNull
    @Override
    public String getName() {
        return "AppDownLoad";
    }
    private static ReactApplicationContext reactContext;
    public AppDownLoad(ReactApplicationContext context){
        super(context);
        reactContext=context;
    }
    @ReactMethod
    public void downloading(String url,String updateInfo){
        Intent intent = new Intent(reactContext, DownLoadActivity.class);
        intent.putExtra("url",url);
        intent.putExtra("updateInfo",updateInfo);
        // 由于没有在Activity环境下启动Activity,设置下面的标签
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        reactContext.startActivity(intent);
    }
}

DownLoadActivity.java

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import java.io.File;

public class DownLoadActivity extends Activity {
    private Context context;
    private AlertDialog mDialog;
    public DownLoadActivity() {
    }

    public DownLoadActivity(Context context) {
        this.context = context;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent=getIntent();
        String url=intent.getStringExtra("url");
        String updateInfo=intent.getStringExtra("updateInfo");
        Log.e("url:",url);
        Log.e("updateInfo:",updateInfo);
        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setCancelable(true);
        dialog.setTitle("正在下载");
        dialog.setMessage(updateInfo+"");
        dialog.setProgress(0);
        dialog.setMax(100);
        dialog.show();
        UpdateService.download(url,updateInfo, new UpdateService.UpdateCallback() {
            @Override
            public void onSuccess() {
                dialog.dismiss();
                Log.e("onSuccess:","success");
                if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    dialog.dismiss();
                    return;
                }
                File file = new File(CommonConstants.DOWNLOAD_PATH + updateInfo);
                try {
                    Log.e("安装文件目录:", file + "");
                    installApk(file);
                } catch (Exception e) {
                    Log.e("获取打开方式错误", e + "");
                    finish();
                }
            }

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

            @Override
            public void onFailure() {
                Log.e("onFailure:","true");
                dialog.dismiss();
                finish();
            }
        });
    }
    private void installApk(File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri fileUri;

        //Android7.0以上
        if (Build.VERSION.SDK_INT >= 24) {
            fileUri = FileProvider.getUriForFile(this,
                    BuildConfig.APPLICATION_ID + "" + ".fileprovider", file);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            fileUri = Uri.fromFile(file);
        }
        intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
        startActivity(intent);
        finish();
    }
}

DownloadApkPackage.java

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.ReactApplicationContext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DownloadApkPackage implements ReactPackage {

    @Override
    public List createNativeModules(ReactApplicationContext reactContext) {
        List modules = new ArrayList<>();
        modules.add(new AppDownLoad(reactContext));
        return modules;
    }

    // @Override
    public List createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

RN代码

AppDownLoad.js

import { NativeModules } from 'react-native';
export default NativeModules.AppDownLoad;

在RN代码中引用

DownloadApk.downloading(appDownloadUrl, appPackage);

 类似资料: