react-native android 更新提示,获取权限,自动下载apk

import {
    AsyncStorage, FlatList, Image, StatusBar, TouchableOpacity, View, Dimensions,ToastAndroid,
    ActivityIndicator, Platform, ProgressBarAndroid, Text, PixelRatio,ImageBackground,BackHandler,
    NativeModules,Modal,PermissionsAndroid,
} from "react-native";
import React from "react";

class HomeScreen extends React.PureComponent {
   


  

    componentDidMount() {
      if (Platform.OS === 'android') {
        this._version();
      }
   }


constructor(props) {
        super(props);
        this.state = {
            sourceData : []
            isLoading: false,
            animating: false,
            //网络请求状态
            error: false,
            errorInfo: "",
            isUpdateModalVisable:false,
        }
    }

render() {
        return (
            
                

this._flatList = flatList}
                        style={{backgroundColor:'#fff'}}
                        renderItem={this._renderItem}
                        keyExtractor={ this._keyExtractor }
                        refreshing={false}
                        numColumns ={3}
                        data={this.state.sourceData}>
                    
                     {
                            this.setState({
                                isUpdateModalVisable: false
                            });
                        }}
                    >
                        {this._renderUpdateModal()}
                    
                


               
            
        );
    }



_version(){
      
      // let version = 2;
      // if(version){
      //   NativeModules.VersionModule.getVersionInfo((result) => {
      //     if(result){
      //       let o = JSON.parse(result);
      //       if(o){
      //         let versionCode = o.versionCode;
      //         if(versionCode){
      //           if(version>versionCode){
                  
      //             this.setState({
      //               isNeedUpdate:true,
      //             })
      //           }
      //         }
      //       }
            
      //     }
      //   })
      // }

 
      let url = 'http';
      fetch(url)
      .then((response) => response.json())
      .then((responseData) => {
        let resultMsg = responseData.resultMsg;
        let resultCode = responseData.resultCode;


        
        if(resultCode===200){
          let object = responseData.object;
          if(object){
            let version = object.version;
            if(version){
              NativeModules.VersionModule.getVersionInfo((result) => {
                if(result){
                  let o = JSON.parse(result);
                  if(o){
                    let versionCode = o.versionCode;
                    if(versionCode){
                      if(version>versionCode){
                        this.setState({
                          isUpdateModalVisable:true,
                        })
                        
                      }
                    }
                  }
                  
                }
              })
            }
           
          }
           

        }else{
          // this.setState({
          //     error: true,
          // });
        }
      }).catch((error) => {

      });
    }

    _renderUpdateModal(){

      return(


        

        
            
                 {this.setState({isUpdateModalVisable:false})}}
                    style={{
                        position: 'absolute', left: 10,
                        height: 40, flexDirection: 'row',
                        justifyContent: 'center', alignItems: 'center', marginLeft: 5
                    }}>
                    close
                
                Tip
            

             this.textInput = ref}
                style={{
                     marginLeft: 15,marginRight:15,
                    height: 120, color: '#333333', fontSize: 15,
                    borderWidth: 1, borderColor: '#E8EEF0', backgroundColor: '#ffffff', borderRadius: 4,
                    paddingLeft: 15, paddingRight: 15, paddingTop: 10
                }}
                >New version detected, update now?

                



            
                 {
                      
                      this.checkPermission();


                    }}
                    style={{
                        paddingTop:8,paddingBottom:8,paddingLeft:12,paddingRight:12,
                        justifyContent: 'center', alignItems: 'center',
                        backgroundColor: "#1097D5", borderRadius: 4
                    }}>
                    update
                
            
            
         );
    }


    checkPermission() {
      this.setState({isUpdateModalVisable:false});
      try {
          //返回Promise类型
          const granted = PermissionsAndroid.check(
              PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
          )
          granted.then((data)=>{
              //alert(data)
              if(data){
                NativeModules.VersionModule.update();
              }else{
                this.requestReadPermission();
              }
          }).catch((err)=>{
              //this.show(err.toString())
          })
      } catch (err) {
          //this.show(err.toString())
      }
  }

  async requestReadPermission() {
    try {
        //返回string类型
        const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
            // {
            //     //第一次请求拒绝后提示用户你为什么要这个权限
            //     'title': 'Need to storage permissions ',
            //     'message': 'Please agree with storage permissions '
            // }
        )
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
            //this.show("你已获取了读写权限")
            NativeModules.VersionModule.update();
        } else {
            //this.show("获取读写权限失败")
            alert('Failed to get storage permission')
        }
    } catch (err) {
        //this.show(err.toString())
        alert(err.toString())
    }
}

}



VersionModule.java


import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;

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

import org.json.JSONException;
import org.json.JSONObject;

public class VersionModule extends ReactContextBaseJavaModule {

    private Context context;

    public VersionModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.context = reactContext;
    }

    @Override
    public String getName() {
        return "VersionModule";
    }

    @ReactMethod
    public void update() {
        if (context != null) {
            Intent intent = new Intent(context, UpdateService.class);
            context.startService(intent);
        }
    }


    public static int getVersionCode(Context mContext) {
        if (mContext != null) {
            try {
                return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
            } catch (PackageManager.NameNotFoundException ignored) {
            }
        }
        return 0;
    }

    public static String getVersionName(Context mContext) {
        if (mContext != null) {
            try {
                return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
            } catch (PackageManager.NameNotFoundException ignored) {
            }
        }

        return "";
    }

    @ReactMethod
    public void getVersionInfo(final Callback callback) {
        JSONObject versionInfo = new JSONObject();
        try {
            versionInfo.put("versionCode", getVersionCode(context));
            versionInfo.put("versionName", getVersionName(context));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        callback.invoke(versionInfo.toString());
    }
}

VersionPackage.java

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

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


public class VersionPackage implements ReactPackage {

    public VersionPackage() {}

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

    public List> createJSModules() {
        return Collections.emptyList();
    }

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

在MainApplication.java中注册


@Override
    protected List getPackages() {
      return Arrays.asList(
          new MainReactPackage(),
          new VersionPackage()
      );
    }

UpdateService.java


import android.Manifest;
import android.app.DownloadManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ServiceCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.webkit.MimeTypeMap;
import android.widget.Toast;


import java.io.File;


public class UpdateService extends Service {


    /**
     * 安卓系统下载类
     **/
    private DownloadManager manager;
    /**
     * 接收下载完的广播
     **/
    private DownloadCompleteReceiver receiver;
    private String downloadurl;
    private String DOWNLOADPATH = Environment.DIRECTORY_DOWNLOADS;
    private String apkName = "download.apk";

    /**
     * 初始化下载器
     **/
    private void initDownManager() {
        manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        receiver = new DownloadCompleteReceiver();
        //设置下载地址
        DownloadManager.Request down = new DownloadManager.Request(Uri.parse(downloadurl));
        // 设置允许使用的网络类型,这里是移动网络和wifi都可以
        down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
                | DownloadManager.Request.NETWORK_WIFI);
        down.setAllowedOverRoaming(false);
        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
        String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(downloadurl));
        down.setMimeType(mimeString);
        // 下载时,通知栏显示途中
        down.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        // 显示下载界面
        down.setVisibleInDownloadsUi(true);
        // 设置下载后文件存放的位置
        down.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
        down.setTitle(this.getResources().getString(R.string.app_name));
        // 将下载请求放入队列
        manager.enqueue(down);
        //注册下载广播
        registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        //downloadurl = intent.getStringExtra("url");
        downloadurl = "http://127.0.0.1/download.apk";
        File file = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                , apkName);
        if (file.exists()) {
            file.delete();
        }
        try {
            // 调用下载
            initDownManager();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "download fail initDownManager", Toast.LENGTH_SHORT).show();
        }
        return Service.START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    @Override
    public void onDestroy() {
        if (receiver != null)
            // 注销下载广播
            unregisterReceiver(receiver);
        super.onDestroy();
    }

    // 接受下载完成后的intent
    class DownloadCompleteReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {

            //判断是否下载完成的广播
            if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
                //获取下载的文件id
                long downId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                if ( manager.getUriForDownloadedFile(downId) != null ) {
                    //自动安装apk
                    //installAPK(manager.getUriForDownloadedFile(downId), context);
                    //File file = new File(DOWNLOADPATH+ apkName);
                    install(context);
                    //installAPK(context);
                } else {
                    Toast.makeText(context, "download fail", Toast.LENGTH_SHORT).show();
                }
                //停止服务并关闭广播
                UpdateService.this.stopSelf();
            }
        }



        /**
         * 通过隐式意图调用系统安装程序安装APK
         */
        public  void install(Context context) {
            File file = new File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                    , apkName);

            if(file.exists()){
                Intent intent = new Intent(Intent.ACTION_VIEW);
                // 由于没有在Activity环境下启动Activity,设置下面的标签
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) { //判读版本是否在7.0以上
                    //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
                    Uri apkUri =
                            MyFileProvider.getUriForFile(context, context.getPackageName()+".fileprovider", file);
                    //添加这一句表示对目标应用临时授权该Uri所代表的文件
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
                }else{
                    intent.setDataAndType(Uri.fromFile(file),
                            "application/vnd.android.package-archive");
                }
                context.startActivity(intent);
            }else {
                Toast.makeText(context, "update error", Toast.LENGTH_SHORT).show();
            }

        }
    }
}

MyFileProvider.java


import android.support.v4.content.FileProvider;

public class MyFileProvider extends FileProvider {
}

file_provider_paths.xml





    
    
    
    
    

AndroidManifest.xml




    

        
            
        



你可能感兴趣的:(react-native android 更新提示,获取权限,自动下载apk)