Program Tip

Intent.VIEW_ACTION이있는 Android 설치 APK가 파일 공급자와 작동하지 않음

programtip 2020. 12. 10. 21:04
반응형

Intent.VIEW_ACTION이있는 Android 설치 APK가 파일 공급자와 작동하지 않음


내 앱에는 APK를 다운로드하고 다운로드가 완료되면 Intent.VIEW_ACTION이 앱을 열고 사용자가 다운로드 한 APK를 설치하도록하는 자동 업데이트 기능이 있습니다.

         Uri uri = Uri.parse("file://" + destination);
         Intent install = new Intent(Intent.ACTION_VIEW);
        install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        install.setDataAndType(uri,
            manager.getMimeTypeForDownloadedFile(downloadId));
        activity.startActivity(install);

이것은 모든 장치에서 잘 작동합니다 <24

이제 Android 24에서는 더 이상 file : ///로 인 텐트를 시작할 수 없으며 인터넷 검색을 한 후 A File Provider를 사용하는 것이 좋습니다.

새 코드 :

Intent install = new Intent(Intent.ACTION_VIEW);
    install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Uri apkUri = FileProvider.getUriForFile(AutoUpdate.this,
        BuildConfig.APPLICATION_ID + ".provider", file);
    install.setDataAndType(apkUri,
        manager.getMimeTypeForDownloadedFile(downloadId));
    activity.startActivity(install);

이제 activity.startActivity (install); 오류를 던진다

인 텐트를 처리 할 활동이 없습니다. {act = android.intent.action.VIEW dat = content : //com.xxxx.xx.provider/MyFolder/Download/MyApkFile.apk typ = application / vnd.android.package-archive flg = 0x4000000}

Android 7 (24)에서 APK 뷰어를 열 수있는 방법이 있습니까?


많은 시도 끝에 FileProvider를 사용하여 Nougat에서 오류가 발생하기 전에 Android 버전으로 설치 인 텐트를 만드는 것과 같이 Nougat보다 낮은 항목에 대해 다른 인 텐트를 만들어이 문제를 해결할 수있었습니다.

ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSTALL_PACKAGE dat=content://XXX.apk flg=0x1 }

Android Nougat에서 일반 Uri를 사용하는 동안 다음 오류가 발생합니다.

FileUriExposedException: file:///XXX.apk exposed beyond app through Intent.getData()

에뮬레이터의 Android N과 Android M을 실행하는 전화로 나를 위해 일하는 내 솔루션.

File toInstall = new File(appDirectory, appName + ".apk");
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Uri apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".fileprovider", toInstall);
    intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
    intent.setData(apkUri);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
    Uri apkUri = Uri.fromFile(toInstall);
    intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
activity.startActivity(intent);

Android Nougat 7.1 업데이트 :

또한 매니페스트에 REQUEST_INSTALL_PACKAGES 권한을 추가해야합니다. Api 레벨 23 (Android 6.0 Marshmallow)에서 사용할 수 있으며 레벨 25 (Android 7.1 Nougat)에서 필요합니다.

최신 정보:

설치하려는 파일이 외부 저장소에있는 경우 외부 저장소에 대한 읽기 및 쓰기 권한을 요청해야합니다. 또한 Android Nougat 이상에 대해 올바른 FileProvider를 설정합니다.

먼저 전화 canReadWriteExternal()하지 않은 경우 아래 에 전화하여 쓰기 권한이 있는지 확인하십시오 requestPermission().

private static final int REQUEST_WRITE_PERMISSION = 786;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED)
        Toast.makeText(this, "Permission granted", Toast.LENGTH_LONG).show();
}

private void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}

private boolean canReadWriteExternal() {
    return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
}

다음은 외부 저장소의 다운로드 폴더에 대한 파일 공급자의 예입니다. AndroidManifest.xml :

<application ... >
    ...

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>
</application>

resources / xml / filepaths.xml :

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

.apk를 설치하는 동안 "패키지를 구문 분석하는 데 문제가 있습니다."와 같은 오류가 발생하는 경우 읽기 / 쓰기 권한을 요청하지 않았거나 설치하려는 파일이 존재하지 않거나 손상되었을 수 있습니다.


이것이 문제 일 수 있습니다.

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

귀하의 예에서는

install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

install은 의도의 이름입니다.


start activity를 호출 할 때이 문제가 발생했습니다. 현재 활동을 일시 중지 한 후 갑자기 돌아와 onResume을 호출했습니다. 아무 일도 없었던 것처럼. 내 문제는 매니페스트 의이 권한이었습니다.

 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

almost no one mentioned that. so remember this. in sdk >= 24 you need to use provider because it needs an intent starting with file:/// below sdk 24 you should give uri starting with content:/// so that's why we need file provider for sdk 24 and above. I don't think I need to write any codes for this as @just_user has written correct answer.


You should note that for API < 24 you need to use:

        setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")

instead of setting data and type separately:

data = Uri.fromFile(apkFile)
    type = "application/vnd.android.package-archive"

otherwise, you will get ActivityNotFoundException

참고URL : https://stackoverflow.com/questions/39147608/android-install-apk-with-intent-view-action-not-working-with-file-provider

반응형