관리 메뉴

드럼치는 프로그래머

[안드로이드] 원격지(Server)에 있는 APK 파일의 다운과 설치 본문

★─Programing/☆─Android

[안드로이드] 원격지(Server)에 있는 APK 파일의 다운과 설치

드럼치는한동이 2017. 5. 24. 11:10
 Android Market에서 다운 받을 App을 찾아서 다운을 받게되면 알아서 다운을 받고 다운로드가 끝나면 간단한 사용자의 동의 후에 App을 설치한다. 

  이것처럼 App을 설치하기 위해선 어떻게 해야할까?
  
  아래의 주소에 유투브에 올라온 것을 보면 WebLink를 누르면 Apk파일을 다운받고 이를 실행하는 것을 볼 수있다.


  
  위의 경우에는 사용자에게 Market에서 받는 apk가 아니기 때문에 이것저것 물어본다. 이를 없애고 바로 다운을 받고 다운이 완료되면 알아서 설치 페이지로 이동시키는 방법을 찾아봤다.

  먼저 테스트로 만든 App의 구조를 보겠다.

 

가장 처음 실행되는 ApkInstaller_StartActivity에는 별다른 내용없이 ApkInstaller_DownActivity로 연결시켜주는 버튼만 존재한다.

 


  Download 버튼을 누르게 되면 ApkInstaller_DownActivity가 띄워지게 된다.
  이 액티비티는 onCreate()되면 바로 웹서버에 있는 파일을 다운받고, 다운이 완료되면 바로 Apk 설치 페이지로 연결된다.


 

  바로 url로 지정된 곳으로 가서 파일을 다운 받고 스마트폰의 sdcard에 저장한다.


  가장 먼저 이 테스트를 할 때에도 다 해놓고 왜 안될까 4시간이나 고민하게 만든 퍼미션...

  <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> 
 
  이 퍼미션을 추가 안해서 하루종일 구글링을 하는 불미스러운 일이...
  무튼 퍼미션으로 해당 퍼미션을 주고 인터넷을 이용하기 때문에 Internet에 대한 퍼미션도 추가 해주면 된다.

  실제로 사용한 퍼미션들.
---------------------------------------------------------------------------------------------------------------  
<uses-permission android:name="android.permission.INSTALL_PACKAGES" /> 
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
</uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
-----------------------------------------------------------------------------------------------------------------
  

ApkInstaller_DownActivity Source.
-----------------------------------------------------------------------------------------------------------------
public void download_WebLink()
{
try
{   
Log.e("DOWNLOAD", "start");
    URL url = new URL("http://j2enty.tistory.com/attachment/cfile24.uf@154AFA254CC9242B3CF889.apk");   
  
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();   
    urlConnection.setDoOutput(true);   
    urlConnection.connect();
    Log.e("DOWNLOAD", "Connect");
  
    File SDCardRoot = Environment.getExternalStorageDirectory();   
    File file = new File(SDCardRoot,"Geocoder_Test.apk");  
    FileOutputStream fileOutput = new FileOutputStream(file);
    Log.e("DOWNLOAD", "fileoutput");
  
    InputStream inputStream = urlConnection.getInputStream();   
    int totalSize = urlConnection.getContentLength();   
    int downloadedSize = 0;   
  
    byte[] buffer = new byte[1024];   
    int bufferLength = 0; 
    while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
    {   
        fileOutput.write(buffer, 0, bufferLength);   
        downloadedSize += bufferLength;
        //mProgressBar.setProgress(downloadedSize);
        Log.e("DOWNLOAD", "saving...");
    }   
    fileOutput.close();   
  
} catch (MalformedURLException e) 
{   
    e.printStackTrace();   
} catch (IOException e) 
{   
    e.printStackTrace();   
Log.e("DOWNLOAD", "end");
Log.e("DOWNLOAD", "InstallAPK Method Called");
installAPK();
}
public void installAPK()
{
Log.e("InstallApk", "Start");
File apkFile = new File("/sdcard/Geocoder_Test.apk");
Uri apkUri = Uri.fromFile(apkFile);
        
Intent webLinkIntent = new Intent(Intent.ACTION_VIEW);
webLinkIntent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
startActivity(webLinkIntent);
}

-----------------------------------------------------------------------------------------------------------------


   URL url = new URL("http://j2enty.tistory.com/attachment/cfile24.uf@154AFA254CC9242B3CF889.apk");   
  
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();   
   urlConnection.setDoOutput(true);   
   urlConnection.connect();
  

  다운 받을 주소를 지정하고 urlConnection을 이용해서 해당 url에 접속을 한다.


   File SDCardRoot = Environment.getExternalStorageDirectory();   
   File file = new File(SDCardRoot,"Geocoder_Test.apk");   //파일이름 임시로 지정
   FileOutputStream fileOutput = new FileOutputStream(file);
   Log.e("DOWNLOAD", "fileoutput");
 
   InputStream inputStream = urlConnection.getInputStream();   
   int totalSize = urlConnection.getContentLength();   
   int downloadedSize = 0;   
 
   byte[] buffer = new byte[1024];   
   int bufferLength = 0; 
   while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
   {   
       fileOutput.write(buffer, 0, bufferLength);   
       downloadedSize += bufferLength;
       //mProgressBar.setProgress(downloadedSize);
       Log.e("DOWNLOAD", "saving...");
   };   

  SDCard에 저장을 할 때 저장할 이름을 임시로 정해서 저장했다.
  File입출력을 이용해서 SDcard에 Apk 파일을 저장한다.

  이 때 notification에 이 상황을 등록하고 프로그레스바를 이용해서 다운로드의 상태나 다운로드가 완료되었을 때  해당 노티를 클릭했을 때의 이벤트도 처리할 수 있다. 

 
  파일이 제대로 저장이 되고 나서 InstallApk가 호출이 된다.

   File apkFile = new File("/sdcard/Geocoder_Test.apk");
   Uri apkUri = Uri.fromFile(apkFile);
   Intent webLinkIntent = new Intent(Intent.ACTION_VIEW);
   webLinkIntent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
   startActivity(webLinkIntent);
 
  저장된 Apk파일의 이름을 지정하고 인텐트에 해당 apkFile경로를 함께 담아서 ACTION_VIEW intent를 날리면  App 설치 화면으로 이동된다.

 

 
 테스트할 App으로 Soundtutorial을 올림;;
 무튼 Apk파일을 읽어서 해당 액티비티를 띄워주고 여기서 Intall 버튼을 누르게 되면 App을 설치하게 된다.

 


  

 설치가 되고 있는 중....

  

 


  설치가 무사히 마쳐지면 App 설치가 완료되었다는 화면이 뜨게 된다. 
Open 버튼을 클릭해서 설치가 잘 되었는지 확인해보면.

 

 


잘 설치가 되어서 이상없이 작동한다.


  이 테스트는 WebServer에 있는 Apk파일을 다운받고 바로 실행이 되는가 안되는가에 대한 것이였다.
  WebServer가 아닌 경우에도 가능할 것으로 생각되며 Apk파일을 설치해주는 기능을 구현해야 되는 것이아니라 Android에 이미 제공되기 때문에 그것만 잘 사용하면 가능 할 것으로 판단된다. 실제로 install 말고도 unintall도 가능한 것을 확인하였다.(언인스톨도 퍼미션 따로있음)



출처: http://j2enty.tistory.com/entry/Android-원격지Server에-있는-APK-파일의-다운과-설치 [무늬만 개발자 블로그.]

 

Comments