Android 反应本机:安装加载的apk

Android 反应本机:安装加载的apk,android,react-native,Android,React Native,我正在用react native开发自动更新模块。对于android版本,应用程序应该下载新版本的apk并安装它。可以使用react native fs下载apk,但如何安装apk? 或者更一般地说,如何在react本机应用程序中运行外部文件?否。在一般情况下不能这样做(在根设备上可能会这样) 这是谷歌市场(或供应商市场)的任务。当你将新版本的应用推向市场时,它应该是开箱即用的,当然用户可以选择自动更新 但是,您可以启动安装对话框,请参见: 要下载文件,应用程序可以使用模块 使用显式数据类型打开

我正在用react native开发自动更新模块。对于android版本,应用程序应该下载新版本的apk并安装它。可以使用react native fs下载apk,但如何安装apk?
或者更一般地说,如何在react本机应用程序中运行外部文件?

否。在一般情况下不能这样做(在根设备上可能会这样)

这是谷歌市场(或供应商市场)的任务。当你将新版本的应用推向市场时,它应该是开箱即用的,当然用户可以选择自动更新

但是,您可以启动安装对话框,请参见:

要下载文件,应用程序可以使用模块


使用显式数据类型打开Intent
应用程序/vnd.android.package archive
可以使用。

我知道时间已经过去了,但是@vovkasm答案已经过时很长时间了。你可以用它实现你想要的 这就是我在我的应用程序中所做的-从url下载.apk,然后在下载完成后自动运行安装,更新应用程序的新版本。 它同时提供:下载和打开文件。 请记住,对于android 8+来说,这需要对清单中的
REQUEST\u INSTALL\u PACKAGES
具有额外的签名权限,但所有操作都正常

下载.apk后打开具有操作视图意图的.apk的简单示例:

RNFetchBlob.android.actionViewIntent(
      resource.path(), //path where the file is downloaded
      "application/vnd.android.package-archive",
    )
正如@vovkasm所写的,仍然可以使用
react native fs
下载文件,但不确定reading.apk tho

我注意到,
react native fs
不处理任何连接错误和下载进度,这在
rn fetch blob
上不起作用,但另一方面,
rn fetch blob
支持下载管理器,而
react native fs
不支持。。。您可以根据需要随时混合这两种材料:)

是的,您可以这样做

1-创建Updater.js根目录,并将文件ProviderAuthority编辑为
您的软件包名称+。provider

        import {Alert} from 'react-native';
        import * as UpdateAPK from 'rn-update-apk';
        
        export default (onStart, onComp) => {
          const update = new UpdateAPK.UpdateAPK({
            iosAppId: '1104809018',
            apkVersionUrl: 'https://example.com/apk/test-version.json',
//Must have test version json file and apk file to the remote server. You can find the contents of the Json file in the repo on the link and examine it.
            fileProviderAuthority: 'com.lorien.provider',
        
            needUpdateApp: (needUpdate) => {
              needUpdate(true);
        
            },
        
            forceUpdateApp: () => {
              console.log('forceUpdateApp callback called');
            },
        
            notNeedUpdateApp: () => {
              console.log('notNeedUpdateApp callback called');
            },
        
            downloadApkStart: () => {
              console.log('downloadApkStart callback called');
            },
        
            downloadApkProgress: (progress) => {
              console.log(`downloadApkProgress callback called - ${progress}%...`);
              onStart(progress);
            },
        
            downloadApkEnd: () => {
              console.log('downloadApkEnd callback called');
              onComp();
            },
            onError: (err) => {
              console.log('onError callback called', err);
              Alert.alert('There was an error', err.message);
            },
          });
        
              update.checkUpdate();
            };
    
2-添加库和添加文件

    npm install rn-update-apk 
(You may need to replace it if you get an error. Find the library in react_modules and change this line as import change tandroidx.core.content.FileProvider)
    npm install react-native-fs
    npm install react-native-exit-app
    npm install react-native-simple-dialogs
    
    Add files
    
    go android>app>src>main>res
    create a folder named xml
    
    and create a js file named filepaths.xml in xml folder like this:
    
        <?xml version="1.0" encoding="utf-8"?>
        <paths xmlns:android="http://schemas.android.com/apk/res/android">
          <cache-path name="cache" path="/" /> 
        </paths>
    

你看过代码推送框架吗?这是一个在react本机应用程序上进行自动更新的工具。如果你的最终目标是做自动更新,也许这个工具可以帮助你。是的,但我认为它只是更新JS包。我想安装新版本的应用程序,所以本机代码也更新了。谢谢你的回答。我只想启动安装对话框。你能通过链接来解释更多关于打开意图的内容吗?我从来没有对apk类型这样做过,但我认为应该简单到:linking.openUrl('file://path-to-apk.apk然后(…).catch(…)我测试
Linking.openUrl('file://path-to-apk.apk)
但它不起作用。它不是用安装程序打开apk,只是想打开它。在android中,可以将application/vnd.android.package-archive作为参数发送到intent,如何在react native中执行此操作?好的,所以您需要编写一些本机代码,或者使用已经存在的第三方软件包。快速搜索建议:谢谢,现在我可以使用application/vnd.android.package-archive。现在我遇到了一个错误:解析包时出现了一个问题,您知道吗?
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.lorien"
      xmlns:tools="http://schemas.android.com/tools">
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    
        <application
          android:name=".MainApplication"
          android:label="@string/app_name"
          android:icon="@mipmap/ic_launcher"
          android:roundIcon="@mipmap/ic_launcher_round"
          android:allowBackup="false"
          android:usesCleartextTraffic="true"
          android:theme="@style/AppTheme">
          <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
          </activity>
          <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
          <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <!-- you might need the tools:replace thing to workaround rn-fetch-blob or other definitions of provider -->
            <!-- just make sure if you "replace" here that you include all the paths you are replacing *plus* the cache path we use -->
            <meta-data tools:replace="android:resource"
              android:name="android.support.FILE_PROVIDER_PATHS"
              android:resource="@xml/filepaths" />
          </provider>
        </application>
    
    </manifest>
    
        import { Dialog } from 'react-native-simple-dialogs';
        import RNExitApp from 'react-native-exit-app';
        import Updater from '../Updater';
        import { ActivityIndicator, Alert } from 'react-native';
          constructor(props) {
            super(props);
            this.state = {
              progressVisibility: false,
              downloadVisibility: false,
              downloadBar: "",
            }
          }
          componentDidMount() {
            console.disableYellowBox = true;
            const self = this;
        
            function onStart(progress) {
              self.setState({downloadVisibility: true})
              self.setState({downloadBar: progress})
            }
        
            function onComp() {
              self.setState({downloadVisibility: false})
              Alert.alert('Dikkat!','Gelen güncellemeyi yüklemeden işlem yapamazsınız. Yükleme işlemini başlatmadıysanız, uygulamayı kapatıp açarak tekrar deneyiniz.',[{ text: "Kapat", onPress: () => RNExitApp.exitApp() }])
            }
            Updater(onStart, onComp);
          }