Java 从应用程序内打开APK文件以进行自动应用程序更新-FileProvider Android-Firebase Storage

Java 从应用程序内打开APK文件以进行自动应用程序更新-FileProvider Android-Firebase Storage,java,android,firebase,firebase-storage,android-fileprovider,Java,Android,Firebase,Firebase Storage,Android Fileprovider,我正在尝试检查FirebaseStorage bucket是否有新的APK文件,如果有新版本,请下载该文件,然后打开该文件以自动启动安装。下载文件很容易,但我似乎无法让FileProvider打开文件?我正在将文件下载到外部存储器中,特别是用户的下载文件夹中。我试图用一个意图打开它,虽然没有抛出错误,但没有打开任何东西,而且肯定没有更新发生 这里是更新函数。您可能会忽略其中的大部分内容,直到我尝试打开文件的中间部分,其余部分只是从Firebase下载,工作正常 public void check

我正在尝试检查FirebaseStorage bucket是否有新的APK文件,如果有新版本,请下载该文件,然后打开该文件以自动启动安装。下载文件很容易,但我似乎无法让FileProvider打开文件?我正在将文件下载到外部存储器中,特别是用户的下载文件夹中。我试图用一个意图打开它,虽然没有抛出错误,但没有打开任何东西,而且肯定没有更新发生

这里是更新函数。您可能会忽略其中的大部分内容,直到我尝试打开文件的中间部分,其余部分只是从Firebase下载,工作正常

public void checkForAppUpdate() {
    ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    Network activeNetwork = cm.getActiveNetwork();
    boolean isConnected = activeNetwork != null;
    if (isConnected) {


        StorageReference reference = firebaseStorage.getReference().getRoot().child("Apk-Release");
        File rootpathtemp = new File(Environment.getExternalStorageDirectory().getParent(),"");
        final File rootpath = new File(rootpathtemp.getParent(),"/self/primary/Download/");
        if(!rootpath.exists()){
            rootpath.mkdirs();
        }
        System.out.println(settings.this.getExternalFilesDir(null));
        reference.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
            @Override
            public void onSuccess(ListResult listResult) {
                for(final StorageReference item : listResult.getItems()){
                    if(Integer.parseInt(item.getName().replace("_","").replace("ver","").replace(".apk","")) > BuildConfig.VERSION_CODE){
                        final File localfile = new File(rootpath,item.getName());
                        item.getFile(localfile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
                            @Override
                            public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                                Intent i = new Intent();
                                i.setAction(Intent.ACTION_VIEW);
                                System.out.println(localfile.getAbsolutePath());
                                System.out.println(rootpath.getAbsolutePath());
                                Uri data = getUriForFile(settings.this, settings.this.getApplicationContext().getPackageName() + ".provider",localfile);
                                i.setDataAndType(data,"application/vnd.android.package-archive");
                                i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                settings.this.getApplicationContext().startActivity(i);
                            }
                        });
                        break;
                    }
                }
            }
        });

    }
}
public void checkForAppUpdate(){
ConnectivityManager cm=(ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_服务);
Network-activeNetwork=cm.getActiveNetwork();
布尔值isConnected=activeNetwork!=null;
如果(未连接){
StorageReference=firebaseStorage.getReference().getRoot().child(“Apk发布”);
File rootpathtemp=新文件(Environment.getExternalStorageDirectory().getParent(),“”);
最终文件rootpath=新文件(rootpathtemp.getParent(),“/self/primary/Download/”;
如果(!rootpath.exists()){
rootpath.mkdirs();
}
System.out.println(settings.this.getExternalFilesDir(null));
reference.listAll().addOnSuccessListener(新的OnSuccessListener()){
@凌驾
成功时公开作废(ListResult ListResult){
对于(最终存储引用项:listResult.getItems()){
if(Integer.parseInt(item.getName().replace(“\u“,”).replace(“.apk“,”))>BuildConfig.VERSION\u代码){
final File localfile=新文件(rootpath,item.getName());
item.getFile(localfile).addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时公共无效(FileDownloadTask.TaskSnapshot TaskSnapshot){
意图i=新意图();
i、 设置动作(意图、动作和视图);
System.out.println(localfile.getAbsolutePath());
System.out.println(rootpath.getAbsolutePath());
Uri data=getUriForFile(settings.this,settings.this.getApplicationContext().getPackageName()+“.provider”,localfile);
i、 setDataAndType(数据,“application/vnd.android.package归档”);
i、 addFlags(意图、标志、授予、读取、URI、权限);
i、 设置标志(意图、标志、活动、新任务);
settings.this.getApplicationContext().startActivity(i);
}
});
打破
}
}
}
});
}
}
我已将提供程序添加到清单中

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

我已经在/res/xml中包含了provider\u路径xml文档

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="external_files"
        path="./../../self/primary/Download"
        />
</paths>

这是我正在测试的设备的内部存储器。。这就是我对存储位置的期望。它似乎正在正确的位置下载文件。

文件(Environment.getExternalStorageDirectory().getParent(),“”)
获取父级,然后授予父级。为什么?那是行不通的。您在使用哪个路径?
文件(rootpathtemp.getParent(),“/self/primary/Download/”)。
这将成为一个奇怪的不存在路径。请告诉完整路径.So Environment.getExternalStoragedirectory()返回不存在或不可访问的\storage\emulated\0。下载文件夹似乎位于\storage\self/primary/Download中,所以我试图将其放入用户的下载文件夹中,这似乎有效。我必须承认这是我第一次使用外部存储和文件提供商。下载文件夹是/storage/emulated/0/download。