2014. 4. 8. 14:40 안드로이드

안드로이드 50메가가 넘어가는 파일 다운로드 


생각 없이 쭉 따라 하면 됩니다.

확장 파일은 안드로이드 콘솔에다 업로드 하는데 .. 누구는 압축을 안한 압축파일을 하라고해서 그렇게 하니 됐습니다. 

알집에 보니 압축률 없이 압축하는 방법이 있습니다.

안드로이드에서 샘플이 제공되고 있습니다. 

D:\adt-bundle-windows-x86_64\sdk\extras\google\play_apk_expansion\downloader_sample

파일이 저장되면 아래의 경로에 저장 됩니다.

 Environment.getExternalStorageDirectory() + "/Android/obb/" + thePackageName + "/main."

+ Def.EXTENSION_FILE_VERSION + "." + thePackageName + ".obb";



시작합니다.

아래의 두개의 프로젝트를 import한다 

D:\adt-bundle-windows-x86_64\sdk\extras\google\play_apk_expansion\downloader_library

D:\adt-bundle-windows-x86_64\sdk\extras\google\play_apk_expansion\zip_file

downloader_library여기서 에러 나는데 library라이센스를 다시 정해 주면된다 


라이센스는 D:\adt-bundle-windows-x86_64\sdk\extras\google\play_licensing 여기 있습니다.


downloader_library,zip_file 둘을 작업 중인 프로젝트에서 프로젝트>안드로이드>library에 add한다 



AndroidManifest.xml

         <service

            android:name="com.home.test.s1.ExpansionFile.ExpansionFileDownloaderService"/>

        <receiver

            android:name="com.home.test.s1.ExpansionFile.ExpansionFileAlarmReceiver" />


이건 그냥 내가 쓴건데 이중에 뭐가 필요한건지 모르겠네 ...

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />

    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />




두개의 파일


ExpansionFileAlarmReceiver.java

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.pm.PackageManager.NameNotFoundException;

import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;

public class ExpansionFileAlarmReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

// TODO Auto-generated method stub

try {

DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent,

ExpansionFileDownloaderService.class);

} catch (NameNotFoundException e) {


}

}

}


ExpansionFileDownloaderService.java
import com.google.android.vending.expansion.downloader.impl.DownloaderService;
public class ExpansionFileDownloaderService extends DownloaderService {
//렌덤 숫자 20개 (byte) 아무렇게나 바이트 숫자 넣으세요
private static final byte[] SALT = new byte[]{
0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};
@Override
public String getAlarmReceiverClassName() {
// TODO Auto-generated method stub
return ExpansionFileDownloaderService.class.getName();
}
@Override
public String getPublicKey() {
// TODO Auto-generated method stub
    //이건 MIIBIjANBgkq...... 요래 시작하는 긴거 알지요 ? 안드로이드 콘솔에서 해당 앱눌러서 publickey
return getResources().getString(R.string.base64EncodedPublicKey);
}
@Override
public byte[] getSALT() {
// TODO Auto-generated method stub
return SALT;
}
}


요건 activity에서 기록하는것 
 Def.EXTENSION_FILE_VERSION 이건 확장 파일을 콘솔에 올렸을때의 앱버젼이다


public class IntroLogoActivity extends SActivity implements IDownloaderClient {
.
.
.
.

String mainFileName = Helpers.getExpansionAPKFileName(this, true, Def.EXTENSION_FILE_VERSION);
Log.e(Constants.TAG, "CRC does not match for entry: ");

if (!Helpers.doesFileExist(this, mainFileName,
Integer.parseInt(getResources().getString(R.string.extendfilesize)), false)) {

mExtensionFrame.setVisibility(View.VISIBLE);
Intent launcher = getIntent();
Intent fromNotification = new Intent(this, getClass());
fromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
fromNotification.setAction(launcher.getAction());
if (launcher.getCategories() != null) {
for (String cat : launcher.getCategories()) {
fromNotification.addCategory(cat);
}
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, 279912, fromNotification,
PendingIntent.FLAG_UPDATE_CURRENT);
try {
// Start the download
int result = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, pendingIntent,
ExpansionFileDownloaderService.class);
Log.i("AA", "DownloaderClientMarshaller result => " + result);
if (DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED != result) {
// implement Downloading UI.
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
ExpansionFileDownloaderService.class);
ToastS.makeText(mToast, this, "파일을 다운로드 중입니다.");
}
} catch (NameNotFoundException e) {
Log.e("apk-expansion-files", "NameNotFoundException occurred. " + e.getMessage(), e);
}
} else {
CallNext();
}

.
.
.
.

@Override
protected void onResume() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(this);
}
super.onResume();
}
@Override
protected void onStop() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.disconnect(this);
}
super.onStop();
}



@Override
public void onDownloadProgress(DownloadProgressInfo progress) {
// TODO Auto-generated method stub
//다운로드 진행 상황 보여줄려고 하는 ui입니다 입맞에 맞게 작성하시면됩니다 .
//일단 값들은 찍어 보세요 
progress.mOverallTotal = progress.mOverallTotal;
mExtenstionProgress.setMax((int) (progress.mOverallTotal >> 8));
mExtenstionProgress.setProgress((int) (progress.mOverallProgress >> 8));
mExtensionCur.setText(Long.toString(progress.mOverallProgress * 100 / progress.mOverallTotal) + "%");
mExtensionMax.setText(Helpers.getDownloadProgressString(progress.mOverallProgress, progress.mOverallTotal));
}

@Override
public void onDownloadStateChanged(int newState) {
// TODO Auto-generated method stub
Log.i("AA", "in onDownloadStateChanged, newState=" + newState);
boolean showDashboard = true;

boolean fAppFinish = false;
//상황에 맞게 작업들을 넣어줘야합니다.
switch (newState) {
case STATE_COMPLETED:// The download was finished
showDashboard = false;
CallNext();
break;
case STATE_IDLE:
Log.i("AA", "in onDownloadStateChanged, STATE_IDLE");
break;
case STATE_FETCHING_URL:
showDashboard = true;
Log.i("AA", "in onDownloadStateChanged, STATE_FETCHING_URL");
break;
case STATE_CONNECTING:
showDashboard = true;
Log.i("AA", "in onDownloadStateChanged, STATE_CONNECTING");
break;
case STATE_DOWNLOADING:
showDashboard = true;
Log.i("AA", "in onDownloadStateChanged, STATE_DOWNLOADING");
break;
case STATE_PAUSED_NETWORK_UNAVAILABLE:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_NETWORK_UNAVAILABLE");
break;
case STATE_PAUSED_BY_REQUEST:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_BY_REQUEST");
break;
case STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION");
break;
case STATE_PAUSED_NEED_CELLULAR_PERMISSION:
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_NEED_CELLULAR_PERMISSION");
break;
case STATE_PAUSED_WIFI_DISABLED:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_WIFI_DISABLED");
break;
case STATE_PAUSED_NEED_WIFI:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_NEED_WIFI");
break;
case STATE_PAUSED_ROAMING:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_ROAMING");
break;
case STATE_PAUSED_NETWORK_SETUP_FAILURE:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_NETWORK_SETUP_FAILURE");
break;
case STATE_PAUSED_SDCARD_UNAVAILABLE:
Log.i("AA", "in onDownloadStateChanged, STATE_PAUSED_SDCARD_UNAVAILABLE");
break;
case STATE_FAILED_UNLICENSED:
ToastS.makeText(mToast, this, "라이센스 검사에 실패 했습니다.\n앱을 종료합니다.");
fAppFinish = true;
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_FAILED_UNLICENSED");
break;
case STATE_FAILED_FETCHING_URL:
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_FAILED_FETCHING_URL");
break;
case STATE_FAILED_SDCARD_FULL:
ToastS.makeText(mToast, this, "저장 공간이 부족합니다.");
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_FAILED_SDCARD_FULL");
break;
case STATE_FAILED_CANCELED:
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_FAILED_CANCELED");
break;
case STATE_FAILED:
showDashboard = false;
Log.i("AA", "in onDownloadStateChanged, STATE_FAILED");
break;
}
int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE;
if (mExtensionFrame.getVisibility() != newDashboardVisibility) {
mExtensionFrame.setVisibility(newDashboardVisibility);
}

if (fAppFinish) {
finish();
}

}

@Override
public void onServiceConnected(Messenger m) {
// TODO Auto-generated method stub
Log.i("AA", "Download started...");
mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);

mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());

}


.
.
.
요건 파일 가져오는거 2가지 방법
public AssetFileDescriptor getAssetFileDescriptor(String filePath) {
PackageManager manager = this.getPackageManager();
PackageInfo info;
try {
info = manager.getPackageInfo(this.getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
return null;
}
String thePackageName = this.getPackageName();
// int thePackageVer = info.versionCode;

String zipFilePath = Environment.getExternalStorageDirectory() + "/Android/obb/" + thePackageName + "/main."
+ Def.EXTENSION_FILE_VERSION + "." + thePackageName + ".obb";
ZipResourceFile expansionFile = null;
AssetFileDescriptor afd = null;
try {
expansionFile = new ZipResourceFile(zipFilePath);

afd = expansionFile.getAssetFileDescriptor(filePath);
} catch (IOException e) {
e.printStackTrace();
}
return afd;
}

public InputStream getAssetFileInputStream(String filePath) {

PackageManager manager = this.getPackageManager();
PackageInfo info;
try {
info = manager.getPackageInfo(this.getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
return null;
}
String thePackageName = this.getPackageName();
// int thePackageVer = info.versionCode;

String zipFilePath = Environment.getExternalStorageDirectory() + "/Android/obb/" + thePackageName + "/main."
+ Def.EXTENSION_FILE_VERSION + "." + thePackageName + ".obb";
ZipResourceFile expansionFile = null;
InputStream is = null;
try {
expansionFile = new ZipResourceFile(zipFilePath);
is = expansionFile.getInputStream(filePath);

} catch (IOException e) {
e.printStackTrace();
}
return is;
}



라이센스 에러 나고 페치 url 실패 나고 하는데요 
확장 파일 버젼 잘 맞추고 사이닝된 apk파일과 콘솔에 올린 버젼이 같으면 됩니다.

일단은 저는 알파테스트로 apk를 올리고 거기다 확장 파일 올리고 
다음 부터는 싸이닝된 apk파일 만들어서 폰에 넣고 설치하고를 반복 하면서 테스트 했습니다.

그런데 확장 파일콘솔에 올리고 난뒤에 디버깅으로 앱 설치해도 확장 파일 다운로드가 되네요 디버깅이 더 쉬워 졌어요


처음에 콘솔에 올리고 언제 업데이트 되서 테스트 하나 막막했음 ....


'안드로이드' 카테고리의 다른 글

cardslib  (0) 2014.04.30
안드로이드 소스 다운로드  (0) 2014.04.16
안드로이드 화학기호 수학기호의 승 표시  (0) 2014.02.27
구글 영수증 코드 확인 하는 방법  (0) 2014.02.12
ANDROID LISTVIEW GET HEIGHT  (0) 2014.01.15
posted by 욱이다