android apk update 기능 구현

냠냠·2022년 5월 10일
0

android

목록 보기
1/5

android 에서 url을 통해 apk를 cache 폴더에 다운로드 후 appstore를 통하지 않고 업데이트를 하는 기능을 구현하였다. 아래 기술된 내용은 cache 폴더에서 apk 파일을 읽어와 업데이트를 하는 방법에 대한 것이다.

세팅

  • 업데이트를 실행할 app과 읽어올 apk 파일의 앱 서명 키가 같아야한다. apk는 release 모드로 빌드되었으며 업데이트를 실행할 app은 android studio 에서 debug 모드로 실행되었다. 따라서 build.gradle 에서 debug 모드 앱 서명 키를 release 빌드에 사용되는 키로 지정했다.
android {
	signingConfigs {
    	release {
            storePassword 'password'
            keyAlias 'password'
            keyPassword 'password'
            storeFile file('./key/signing_key.jks')
        }
        debug {
            storePassword 'password'
            keyAlias 'password'
            keyPassword 'password'
            storeFile file('./key/signing_key.jks')
        }
    }
}
  • res/xml/path.xml 생성 후 provider path 설정
<paths>
	<cache-path name="cache" path="."/>
</paths>
  • manifest에 권한 및 provider 추가
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <application>
    	<provider
       		android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
               android:name="android.support.FILE_PROVIDER_PATHS"
               android:resource="@xml/path" />
           </provider>
    </application>

구현

  • 알 수 없는 출처의 앱 설치 권한 확인 (아래 코드가 없어도 권한 없이 설치를 시도하면 메시지와 함께 권한 획득 화면으로 넘어간다)
if(!packageManager.canRequestPackageInstalls()){
	val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
    intent.data = Uri.parse(String.format("package:%s", packageName))
    startActivity(intent)
}
  • apk 파일을 읽어와 설치 화면을 띄움
    private fun executeFile(
    	context: Context,
        file: File
    ) {
        try {
            val intent = Intent(Intent.ACTION_VIEW)

            val uri = FileProvider.getUriForFile(context, context.applicationContext.packageName + ".provider", file)
            intent.setDataAndType(uri, "application/vnd.android.package-archive")
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
            context.startActivity(intent)

        } catch (e: Exception) {
            println("executeFile(): ${e.message}")
        }
    }

0개의 댓글