• GooglePlay


    前言

      Google Play应用商店在上传限制100MB大小,超过该大小的应用必须将超过部分以扩展文件的形式进行上传处理。 总共可上传2个扩展文件,每个最大文件可为2GB,同时obb文件格式可自选。

    官网地址:http://developer.android.com/google/play/expansion-files.html

    准备

      1、在sdk Manager中下载对应的支持库,play_licensing及play_apk_expansion如下:

        

      2、生成需要的obb文件,并在上传apk包的同时选择上传扩展文件。

        obb文件生成可参考jobb工具生成(官网推荐), http://developer.android.com/tools/help/jobb.html

        也可以直接用参考stackoverflow上Sanket Kachhela的回答(个人推荐):http://stackoverflow.com/questions/14495483/read-content-from-apk-expansion-file-from-obb-file#answer-18953778,直接利用zip压缩工具选择存储模式。

      3、如果上述采用zip压缩的话,这里就还需要unzip准备,利用zipHelper直接解压下载包并正常使用。

        参考stackoverflow上Bhavesh Hirpara的回答:http://stackoverflow.com/questions/14495483/read-content-from-apk-expansion-file-from-obb-file#answer-15150977

      

    链接库配置

      1、在eclipse打开需要的库工程,如下:

        

      2、如果downloader_library出现错误 AESObfuscator cannot be resolved 则说明Eclipse没有选择自动编辑,勾选下project->build automatically即可。

      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>

      2、从~sdkplay_apk_expansiondownloader_sample项目复制srccomexampleexpansiondownloader下的sample文件到游戏目录下,并对应修改包名的引用等。

        a、将onCreate下的判断obb文件存在的注释处理添加如下:

                    // otherwise, download not needed so we fall through to
                    // starting the movie
                    validateXAPKZipFiles();

        b、修改  validateXAPKZipFiles 方法,去除验证,直接添加解压方法到对应的游戏下载目录。

        // 解压到游戏下载目录
        private void upzipApkExFile(){
            try {
                
                ZipResourceFile expansionFile = APKExpansionSupport
                        .getAPKExpansionZipFile(this, VERSION_CODE, 0);
    
                ZipEntryRO[] zip = expansionFile.getAllEntries(); 
                 Log.i("upzipApkExFile", "mZipFileName : " + zip[0].mZipFileName); 
                 String path  = getApplicationContext().getFilesDir().getAbsolutePath();
                File file = new File(path + "");
                ZipHelper.unzip(zip[0].mZipFileName, file);
                
                if (file.exists()) {
                    Log.e("", "unzipped : " + file.getAbsolutePath());
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        } 
       /**
         * Go through each of the Expansion APK files and open each as a zip file.
         * Calculate the CRC for each file and return false if any fail to match.
         * 
         * @return true if XAPKZipFile is successful
         */
        void validateXAPKZipFiles() { 
            upzipApkExFile();
            Intent myIntent = new Intent(this, AppActivity.class); //跳转到游戏Activity
            startActivity(myIntent);
            this.finish();
        }

        c、修改SampleDownloaderService文件下的BASE64_PUBLIC_KEY。将其改成对应的Google Play上申请的应用的Key。

     3、添加对应下载接受服务监听。

    <application ...>
        <service android:name="com.test123.expansion.downloader.SampleDownloaderService" />
        <receiver android:name="com.test123.expansion.downloader.SampleAlarmReceiver" />
        ...
    </application>

      4、主游戏AppActivity处理。在启动的Activity中进行判断,如果已经下载并解压了文件则进入游戏,否则跳转到下载的Activity。

        protected void onCreate(final Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            String path  = getApplicationContext().getFilesDir().getAbsolutePath();
            File boolfile = new File(path + "/downloaded");
            if(!boolfile.exists())
            {
                Intent myIntent = new Intent(this, SampleDownloaderActivity.class);
                startActivity(myIntent);
                this.finish();
                return;
            }
    
            Log.i("upzipApkExFile", "already unziped!!");
      }

      

    Cocos2dx处理

      为了让下载的扩展文件直接应用到游戏中,我们要稍微修改下cocos2dx引擎的读取文件处理。

    首先,找到引擎目录下cocos2dcocosplatformCCFileUtils.cpp文件。

    其次,对方法进行如下修改,使其先在getWritablePath目录下需找文件。

    std::string FileUtils::fullPathForFilename(const std::string &filename) const
    {
        if (filename.empty())
        {
            return "";
        }
    
        if (isAbsolutePath(filename))
        {
            return filename;
        }
    
        // Already Cached ?
        auto cacheIter = _fullPathCache.find(filename);
        if(cacheIter != _fullPathCache.end())
        {
            return cacheIter->second;
        }
    
        // Get the new file name.
        const std::string newFilename( getNewFilename(filename) );
    
        std::string fullpathWritablePath = getWritablePath() + newFilename;
        if (isFileExistInternal(fullpathWritablePath))
        {
            if (fullpathWritablePath.length() > 0)
            {
                // Using the filename passed in as key.
                //_fullPathCache.insert(std::make_pair(filename, fullpathWritablePath));
                _fullPathCache[filename] = fullpathWritablePath;
                return fullpathWritablePath;
            }
        }
    
    
    
        std::string fullpath;
        for (const auto& searchIt : _searchPathArray)
        {
            for (const auto& resolutionIt : _searchResolutionsOrderArray)
            {
                fullpath = this->getPathForFilename(newFilename, resolutionIt, searchIt);
    
                if (fullpath.length() > 0)
                {
                    // Using the filename passed in as key.
                    _fullPathCache.insert(std::make_pair(filename, fullpath));
                    return fullpath;
                }
    
            }
        }
    
        if(isPopupNotify()){
            CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", filename.c_str());
        }
    
        // The file wasn't found, return empty string.
        return "";
    }

    而这里getWritablePath获取的目录正是我们之前解压obb文件的目录getApplicationContext().getFilesDir().getAbsolutePath()。

    因此,到这里就可以在游戏中跟使用在assert中文件一样使用obb解压出来的文件了。

  • 相关阅读:
    Spring restful
    LDAP & Implementation
    Restful levels and Hateoas
    事务隔离的级别
    servlet injection analysis
    session and cookie
    write RE validation
    hello2 source analysis
    匿名函数和递归函数
    生成器和迭代器,列表推导式
  • 原文地址:https://www.cnblogs.com/stratrail/p/5195238.html
Copyright © 2020-2023  润新知