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
'Program Tip' 카테고리의 다른 글
사용자 이름과 암호를 제공하지 않고 공유 폴더에 액세스하는 방법 (0) | 2020.12.10 |
---|---|
여러 표현식에서 ng-click을 사용하는 방법은 무엇입니까? (0) | 2020.12.10 |
PHP에서 try-catch의 성능 (0) | 2020.12.10 |
사용자 정의 유형으로 std :: set, 중복이 없는지 확인하는 방법 (0) | 2020.12.10 |
헤더 파일의 변수 선언 (0) | 2020.12.10 |