[Android] Silent Install APK

👻·2022년 7월 28일
0

Android

목록 보기
6/11
post-thumbnail

📌 개요

현재 사용중이던 Android OS 버전은 v7.0 이였다.

프로그램 실행 시 패치 파일이 있다면 자동으로 패치파일을 다운로드 후
다운로드 받은 APK 파일을 Install 하는 방식이였다.

문제는 Install을 IPackageInstallObserver를 사용해서 하고있었는데
v9.0(SDK Build 28) 이상부터는 동작하지 않았다.

검색(Silent Install)하다 보니 마음에 드는게 잘 없었다.

그나마 지금 내가 처한 상황과 비슷한 사람이 있었어서 참고했다.

PackageInstaller를 사용했다. 방식자체는 크게 어렵지 않았다.


📌 개발환경

AndroidStudio
Java 8
Build.Version.SDK 28
Android OS Version 9.0


📌 해결방안

https://stackoverflow.com/questions/56129939/restriction-of-targeting-api-28-on-ipackageinstallobserver-and-ipackagedeleteobs

public class InstallPackage {
    public static final String TAG = "InstallPackage";
    private PackageInstaller packageInstaller = null;
    private PackageInstaller.Session session = null;
    private PackageInstaller.SessionParams sessionParams = null;
    private int sessionId = 0;

    private InputStream is = null;
    private OutputStream os = null;

    public InstallPackage(PackageInstaller packageInstaller) {
        //getApplicationContext().getPackageManager().getPackageInstaller();
        this.packageInstaller = packageInstaller;
    }

    public boolean installPackage(Context context, File file) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
                sessionId = packageInstaller.createSession(sessionParams);
                session = packageInstaller.openSession(sessionId);

                long sizeBytes = 0;
                if(file.isFile()) {
                    sizeBytes = file.length();
                }

                is = new FileInputStream(file.getPath());
                os = session.openWrite("ProjectName!", 0, sizeBytes);

                long total = 0;
                byte[] buffer = new byte[65536];

                int len;

                do {
                    len = is.read(buffer);
                    if(len != -1) {
                        total += len;
                        os.write(buffer, 0, len);
                    }
                } while (len != -1);

                session.fsync(os);
                is.close();
                os.close();
                is = null;
                os = null;

                session.commit(createIntentSender(context, sessionId));
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeStream();
        }

        return false;
    }

    private IntentSender createIntentSender(Context context, int sessionId) {
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                context,
                sessionId,
                new Intent("Installation Complete"),
                0
        );

        return pendingIntent.getIntentSender();
    }

    private void closeStream() {
        try {
            if(is != null) {
                is.close();
                is = null;
            }

            if(os != null) {
                os.close();
                os = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

적용 후 정상작동 확인!
설치 다 되고나서 자동으로 실행하게 해놨는데
자꾸 딜레이가 생긴다 ㅠ
원래도 이 기기 자체가 그런 문제가 있었다고 하시는데
나중에 시간될 때 알아보기로 했다😊

하다가
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification
에러발생.. 채널이뭐야.. 다음포스트에서..


android
silent install apk
auto install apk


profile
Software Developer

0개의 댓글