보통 안드로이드 app 개발 후 apk 파일을 배포하기 위해서는 구글 플레이 스토어를 사용하지요.
하지만 기업 모바일의 경우 (B2E) 사내 사용자를 위한 app 을 자체 시스템 또는 웹페이지를 통해서
배포하는 경우가 많습니다.
그러면 웹페이지를 통한 apk 파일 배포는 어떻게 하는지 살펴보겠습니다.
우선 웹서버가 있어야겠죠. 웹서버는 apache, nginx 를 해도 되고 윈도우 서버인 경우 IIS 를 사용하면 됩니다.
(참고글 : 웹서버의 종류 및 설치 방법)
그러면 웹서버 설치가 끝나셨으면 이제 apk 파일을 배포해 봅시다.
<a태그> 를 이용하여 다운로드하는 방법
이 방법은 간단합니다. 웹서버에 다운로드 페이지 하나 만들어서
<a href="appname.apk" type="application/vnd.android.package-archive">App 다운로드</a>
를 달아주시면 됩니다. 이 방법의 단점은 사용자가 위 링크를 터치했을 때 다운로드가 진행되지만 자동 설치까지는
되지 않습니다. 즉, 사용자가 다운로드 완료되었다는 알림을 선택하고 설치화면으로 이동하여 설치를 하여야 합니다.
여기서 사용자 폰 설정에서는 "알 수 없는 소스 설치" 가 체크되어 있어야 하죠.
그리고 주의해야할 점은 웹서버 설정 중에 apk 를 application/vnd.android.package-archive 로 설정했는지 체크해봐야
합니다. 위에 이미 type을 지정하긴 했지만 빼먹을 수 있으니 체크하는게 좋겠죠?
리눅스에서는 /etc/mime.types 파일을 편집한후 application/vnd.android.package-archive apk 를 추가하고 웹서버
재기동을 하면 됩니다.
(참고) 안드로이드 네이티브 소스로 웹서버에 있는 파일을 다운로드 하는 방법
앱 자체에 다운로드 버튼을 두고 사용자가 그 버튼을 눌렀을 때 웹서버에 있는 파일을 다운로드 하는 방법입니다.
안드로이드 프로그래밍 정복'(한빛미디어) (Page. 780) - 김상형님 저서의 예제소스 또는 다음 소스를 참고하시면 됩니다.
MainActivity.java
- public class MainActivity extends Activity implements OnClickListener {
- /** Called when the activity is first created. */
- String File_Name = "확장자를 포함한 파일명";
- String File_extend = "확장자명";
- String fileURL = "웹서버 쪽 파일이 있는 경로"; // URL
- String Save_Path;
- String Save_folder = "/mydown";
- ProgressBar loadingBar;
- DownloadThread dThread;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Button btn = (Button) findViewById(R.id.downbtn);
- btn.setOnClickListener(this);
- loadingBar = (ProgressBar) findViewById(R.id.Loading);
- // 다운로드 경로를 외장메모리 사용자 지정 폴더로 함.
- String ext = Environment.getExternalStorageState();
- if (ext.equals(Environment.MEDIA_MOUNTED)) {
- Save_Path = Environment.getExternalStorageDirectory()
- .getAbsolutePath() + Save_folder;
- }
- }
- @Override
- public void onClick(View view) {
- // TODO Auto-generated method stub
- if (view.getId() == R.id.downbtn) {
- File dir = new File(Save_Path);
- // 폴더가 존재하지 않을 경우 폴더를 만듦
- if (!dir.exists()) {
- dir.mkdir();
- }
- // 다운로드 폴더에 동일한 파일명이 존재하는지 확인해서
- // 없으면 다운받고 있으면 해당 파일 실행시킴.
- if (new File(Save_Path + "/" + File_Name).exists() == false) {
- loadingBar.setVisibility(View.VISIBLE);
- dThread = new DownloadThread(fileURL + "/" + File_Name,
- Save_Path + "/" + File_Name);
- dThread.start();
- } else {
- showDownloadFile();
- }
- }
- }
- // 다운로드 쓰레드로 돌림..
- class DownloadThread extends Thread {
- String ServerUrl;
- String LocalPath;
- DownloadThread(String serverPath, String localPath) {
- ServerUrl = serverPath;
- LocalPath = localPath;
- }
- @Override
- public void run() {
- URL imgurl;
- int Read;
- try {
- imgurl = new URL(ServerUrl);
- HttpURLConnection conn = (HttpURLConnection) imgurl
- .openConnection();
- int len = conn.getContentLength();
- byte[] tmpByte = new byte[len];
- InputStream is = conn.getInputStream();
- File file = new File(LocalPath);
- FileOutputStream fos = new FileOutputStream(file);
- for (;;) {
- Read = is.read(tmpByte);
- if (Read <= 0) {
- break;
- }
- fos.write(tmpByte, 0, Read);
- }
- is.close();
- fos.close();
- conn.disconnect();
- } catch (MalformedURLException e) {
- Log.e("ERROR1", e.getMessage());
- } catch (IOException e) {
- Log.e("ERROR2", e.getMessage());
- e.printStackTrace();
- }
- mAfterDown.sendEmptyMessage(0);
- }
- }
- Handler mAfterDown = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- loadingBar.setVisibility(View.GONE);
- // 파일 다운로드 종료 후 다운받은 파일을 실행시킨다.
- showDownloadFile();
- }
- };
- private void showDownloadFile() {
- Intent intent = new Intent();
- intent.setAction(android.content.Intent.ACTION_VIEW);
- File file = new File(Save_Path + "/" + File_Name);
- // 파일 확장자 별로 mime type 지정해 준다.
- if (File_extend.equals("mp3")) {
- intent.setDataAndType(Uri.fromFile(file), "audio/*");
- } else if (File_extend.equals("mp4")) {
- intent.setDataAndType(Uri.fromFile(file), "vidio/*");
- } else if (File_extend.equals("jpg") || File_extend.equals("jpeg")
- || File_extend.equals("JPG") || File_extend.equals("gif")
- || File_extend.equals("png") || File_extend.equals("bmp")) {
- intent.setDataAndType(Uri.fromFile(file), "image/*");
- } else if (File_extend.equals("txt")) {
- intent.setDataAndType(Uri.fromFile(file), "text/*");
- } else if (File_extend.equals("doc") || File_extend.equals("docx")) {
- intent.setDataAndType(Uri.fromFile(file), "application/msword");
- } else if (File_extend.equals("xls") || File_extend.equals("xlsx")) {
- intent.setDataAndType(Uri.fromFile(file),
- "application/vnd.ms-excel");
- } else if (File_extend.equals("ppt") || File_extend.equals("pptx")) {
- intent.setDataAndType(Uri.fromFile(file),
- "application/vnd.ms-powerpoint");
- } else if (File_extend.equals("pdf")) {
- intent.setDataAndType(Uri.fromFile(file), "application/pdf");
- }
- startActivity(intent);
- }
- }
퍼미션 설정 (androidmanifest.xml)
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.INTERNET"/>
레이아웃 (layout.xml)
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
- <ProgressBar
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/Loading"
- android:layout_width="30dip"
- android:layout_height="30dip"
- android:visibility="gone"/>
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="다운로드"
- android:id="@+id/downbtn" />
- </LinearLayout>
* 출처 : http://motpool.tistory.com/35
다음 참고글 : 앱 업데이트 방법 (1. 구글 플레이스토어 등록 후 업데이트 방법, 2. 별도 내 서버에서 버전관리하는 방법)
'Dev Talks > Mobile App Dev' 카테고리의 다른 글
[Firebase를 활용한 App 개발] #2 Firebase 프로젝트 생성 (0) | 2017.01.08 |
---|---|
[Firebase를 활용한 App 개발] #1 안드로이드 스튜디오 설치 (mac 기준) (0) | 2017.01.08 |
[Hybrid] jQuery Mobile 페이지 전환 방법 (0) | 2015.03.12 |
jQuery Mobile HTML 기본 구조 (0) | 2015.03.11 |
댓글