AndroidObb文件编程中使用详解

AndroidObb文件编程中使用详解

Obb文件是Google提供的将占存储空间较大的图片资源影音资源等制作成的压缩文件包,Obb文件可以在上架App时同时上传。当用户下载App时,Obb文件会随之下载,但是也会有不下载的情况,需要自行处理。

1.制作Obb文件

使用Jobb制作Obb文件在Android SDK中, %ANDROID——HOME/tools%中,在tools/bin下有jobb

命令:

jobb -d [目录名称的完整路径] -o [输出目标文件的完整路径] -pn [软件包名] -pv [包版本]

EG:
源文件目录 D:contents 目标文件夹: D:\obb\output.obb 软件包名 com.my.test 包版本 1

jobb -d D:\contents -o D:\obb\output.obb -pn com.my.test -pv 1

  • 注意:
    • jobb -d,-o 需要指定完整路径。如果指定相对路径,%ANDROID_HOME%/tools/将作为相对路径
    • JOBB工具如果不能输出有一定容量的.obb的文件的话,出现错误提示

2.在代码中加入下载和读入Obb文件的逻辑

2.1 下载DownloaderLibrary需要的包

Google提供了一个DownloaderLibrary来下载Obb文件。想使用DownloaderLibrary,现在在Android SDK Manager(Tools > Android > SDK Manager)中下载以下两个包:

  • Google Play Licenseing Library package
  • Google Play APK Expansion Library package

2.2 将Google Play License Library 与 Google Play Downloader Library导入到项目中

  • <sdk>/extras/google/market_licensing中存放的library对应为GooglePlayLicenseLibrary,将其作为Module导入到项目中
  • <sdk>/extras/google/market_apk_expansion中存放的downloader_library对应为DownloaderLibrary,将其作为module导入到项目中。
注意:

downloader_library在导入时,需要删除downloader_library/project.properties中的android.library.reference.1=../market_licensing
。当downloader_library导入之后,再将GooglePlayLicenseLibrary作为依赖项,加在downloader_library中。

3 在需要检查Obb文件的地方加入相关逻辑

以在MainActivity中判断为例:

3.1 声明权限

<manifest ...>
    <!-- Required to access Google Play Licensing -->
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />

    <!-- Required to download files from Google Play -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- Required to keep CPU alive while downloading files
        (NOT to keep screen awake) -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- Required to poll the state of the network connection
        and respond to changes -->
    <uses-permission
        android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Required to check whether Wi-Fi is enabled -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    <!-- Required to read and write the expansion files on shared storage -->
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

3.2 实现下载服务

  • 自定义下载服务继承自DownloaderService

    “`java
    public class SampleDownloaderService extends DownloaderService {
    // You must use the public key belonging to your publisher account
    public static final String BASE64_PUBLIC_KEY = “YourLVLKey”;
    // You should also modify this salt
    public static final byte[] SALT = new byte[] { 1, 42, -12, -1, 54, 98,
    -100, -12, 43, 2, -8, -4, 9, 5, -106, -107, -33, 45, -1, 84
    };

    @Override
    public String getPublicKey() {
    return BASE64_PUBLIC_KEY;
    }

    @Override
    public byte[] getSALT() {
    return SALT;
    }

    @Override
    public String getAlarmReceiverClassName() {
    return SampleAlarmReceiver.class.getName();
    }
    }


* 在Manifest文件中声明服务

  ```java
<application ...>
    <service android:name=".SampleDownloaderService" />
    ...
</application>

3.3 实现AlarmReceiver

  • 定义AlarmReceiver继承自BroadcastReceiver

    “`java
    public class SampleAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    try {
    DownloaderClientMarshaller.startDownloadServiceIfRequired(context,
    intent, SampleDownloaderService.class);
    } catch (NameNotFoundException e) {
    e.printStackTrace();
    }
    }
    }


* 在Manifest文件中声明receiver

  ```java
  <application ...>
    <receiver android:name=".SampleAlarmReceiver" />
    ...
</application>
  ```

### 3.4 判断Obb文件是否已经存在
* 封住装Obb文件信息

  ```java
  private static class XAPKFile {
        public final boolean mIsMain;
        public final int mFileVersion;
        public final long mFileSize;

        XAPKFile(boolean isMain, int fileVersion, long fileSize) {
            mIsMain = isMain;
            mFileVersion = fileVersion;
            mFileSize = fileSize;
        }
    }
  ```

* 定义Obb文件

  ```java
private static final XAPKFile[] xAPKS = {
            new XAPKFile(
                    true, // true signifies a main file
                    3, // the version of the APK that the file was uploaded
                       // against
                    687801613L // the length of the file in bytes
            ),
            new XAPKFile(
                    false, // false signifies a patch file
                    4, // the version of the APK that the patch file was uploaded
                       // against
                    512860L // the length of the patch file in bytes
            )            
    };
  • 判断Obb文件是否存在

    “`java
    boolean expansionFilesDelivered() {
    for (XAPKFile xf : xAPKS) {
    String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsBase,
    xf.mFileVersion);
    if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false))
    return false;
    }
    return true;
    }


### 3.5 下载Obb文件

```java
// Check if expansion files are available before going any further
    if (!expansionFilesDelivered()) {
        // Build an Intent to start this activity from the Notification
        Intent notifierIntent = new Intent(this, MainActivity.getClass());
        notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                                Intent.FLAG_ACTIVITY_CLEAR_TOP);
        ...
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        // Start the download service (if required)
        int startResult =
            DownloaderClientMarshaller.startDownloadServiceIfRequired(this,
                        pendingIntent, SampleDownloaderService.class);
        // If download has started, initialize this activity to show
        // download progress
        if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
            // This is where you do set up to display the download
            // progress (next step)
            ...
            return;
        } // If the download wasn't necessary, fall through to start the app
    }
    startApp(); // Expansion files are available, start the app




<div class="se-preview-section-delimiter"></div>

3.6 如果加入Activity状态改变逻辑

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

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




<div class="se-preview-section-delimiter"></div>

3.7 接收下载进度

  • 定义IDwonloaderService

    private IDownloaderService mRemoteService;
    ...
    @Override
    public void onServiceConnected(Messenger m) {
    mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
    mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
    }
  • 接收下载进度
    Activity需要实现IDownloaderClient接口

    “`java
    onDownloadProgress(DownloadProgressInfo progress) {
    //todo you can update your progress view
    }


* 接收下载状态  
Activity需要实现IDownloaderClient接口

  ```java
onDownloadStateChanged(int newState) {
    //todo you can judge whether the obb download service is ok or other states
}

参考链接


### 3.7 接收下载进度

* 定义IDwonloaderService

  ```java
  private IDownloaderService mRemoteService;
...
@Override
public void onServiceConnected(Messenger m) {
    mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
    mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
}
  ```

* 接收下载进度  
Activity需要实现IDownloaderClient接口

  ```java
onDownloadProgress(DownloadProgressInfo progress) {
    //todo you can update your progress view
}
  • 接收下载状态
    Activity需要实现IDownloaderClient接口

    onDownloadStateChanged(int newState) {
    //todo you can judge whether the obb download service is ok or other states
    }

参考链接
参考源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值