그러냐

apk 에서 다른 apk 실행하기 본문

android

apk 에서 다른 apk 실행하기

관절분리 2016. 1. 28. 11:06
반응형

출처 : http://nandol.com/621


실행할 apk

- package : com.nandol.install
- apk : Install.apk

설치할 apk

- package : com.nandol.test
- apk : Test.apk

1. Export project to unsigned application package

Eclipse의 package explorer에서 Test 프로젝트를 마우스 우클릭하고 "Android Tools > Export Unsigned Application Package..." 를 선택하여 Local folder로 apk를 저장합니다.

2. Create keystore

unsigned된 apk는 이 방법으로 설치가 되지 않으므로, sign을 하기 위한 keystore를 생성합니다. (최초 1회) cmd창에서 아래와 같이 실행합니다.

keytool -genkey -v -keystore com.nandol.test.Test.keystore -alias nandol -keyalg RSA -validity 10000

3. Sign

cmd창에서 아래와 같이 실행합니다.

jarsigner -verbose -keystore com.nandol.test.Test.keystore Test.apk nandol

4. Import Test.apk to Install.apk's asset

위에서 sign한 Test.apk를 Install 프로젝트의 asset으로 import합니다.

5. Coding

아래와 같이 구현합니다. install() method는 asset의 Test.apk를 InputStream으로 불러서 /data/data/[패키지명]/files로 저장한 후, "application/vnd.android.package-archive"를 이용하여 apk 설치화면을 불러냅니다.

    private final static String TEST_APK = "Test.apk";
    private final static String TEST_PACKAGE = "com.nandol.test";
    private final static int TEST_VERSION_CODE = 1;
    
    private void install() {        
        try {            
            InputStream is = getAssets().open(TEST_APK);
            FileOutputStream fos = openFileOutput(TEST_APK, Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
            byte[] buffer = new byte[1024];
            int byteRead = 0;
            
            while ((byteRead = is.read(buffer)) != -1) {
                fos.write(buffer, 0, byteRead);
            }
            
            fos.close();
            
            File apk = getFileStreamPath(TEST_APK);
            Uri uri = Uri.fromFile(apk);
            
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


Test.apk가 이미 설치되어 있는지 확인하고, 설치되어 있다면 새로 설치할 version이 보다 new인 경우에만 설치하도록 하려면 아래와 같이 추가합니다.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        if(TEST_VERSION_CODE > getVersionCode()) {
            install();
        }        
    }

    public int getVersionCode() {
        int versionCode = 0;
        try {
            versionCode = getPackageManager().getPackageInfo(TEST_PACKAGE, 0).versionCode;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

 

반응형