cocos2d-x版本 2.0.4
cocos2d-x做android游戏在线更新资源。
费话不多说,直接上代码:
下载和解压是用android端java实现:
- /**
- *
- * @return
- * 100 没有sd卡
- * 1 下载过程中出错
- * 2 解压过程中出错
- * 3 删除过程中出错
- */
- public static int download()
- {
- //检查sd卡
- if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
- {
- return 100;
- }
- //下载保存
- try
- {
- saveToFile("http://192.168.0.14/data/Data.zip", Environment.getExternalStorageDirectory()+"/data.zip");
- }
- catch (IOException e)
- {
- e.printStackTrace();
- return 1;
- }
- //解压
- File zipFile = new File(Environment.getExternalStorageDirectory()+"/data.zip");
- try
- {
- upZipFile(zipFile,Environment.getExternalStorageDirectory()+"/xydata/data/");
- }
- catch (ZipException e)
- {
- e.printStackTrace();
- return 2;
- }
- catch (IOException e)
- {
- e.printStackTrace();
- return 2;
- }
- //删除zip
- try
- {
- deleteFile(zipFile);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- return 3;
- }
- return 0;
- }
- private static int BUFFER_SIZE = 8096; //缓冲区大小
- /**
- * 将HTTP资源另存为文件
- *
- * @param destUrl String
- * @param fileName String
- * @throws Exception
- */
- public static void saveToFile(String destUrl, String fileName) throws IOException
- {
- FileOutputStream fos = null;
- BufferedInputStream bis = null;
- HttpURLConnection httpUrl = null;
- URL url = null;
- byte[] buf = new byte[BUFFER_SIZE];
- int size = 0;
- // 建立链接
- url = new URL(destUrl);
- httpUrl = (HttpURLConnection) url.openConnection();
- // 连接指定的资源
- httpUrl.connect();
- // 获取网络输入流
- bis = new BufferedInputStream(httpUrl.getInputStream());
- // 建立文件
- fos = new FileOutputStream(fileName);
- System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + fileName + "]");
- // 保存文件
- while ((size = bis.read(buf)) != -1)
- {
- fos.write(buf, 0, size);
- }
- fos.close();
- bis.close();
- httpUrl.disconnect();
- }
- /**
- * 解压缩一个文件
- *
- * @param zipFile 要解压的压缩文件
- * @param folderPath 解压缩的目标目录
- * @throws IOException 当解压缩过程出错时抛出
- */
- public static void upZipFile(File zipFile, String folderPath) throws ZipException, IOException
- {
- File desDir = new File(folderPath);
- if (!desDir.exists())
- {
- desDir.mkdirs();
- }
- ZipFile zf = new ZipFile(zipFile);
- for (Enumeration<?> entries = zf.entries(); entries.hasMoreElements();)
- {
- ZipEntry entry = ((ZipEntry) entries.nextElement());
- InputStream in = zf.getInputStream(entry);
- String str = folderPath + File.separator + entry.getName();
- str = new String(str.getBytes("8859_1"), "GB2312");
- File desFile = new File(str);
- if (!desFile.exists())
- {
- File fileParentDir = desFile.getParentFile();
- if (!fileParentDir.exists())
- {
- fileParentDir.mkdirs();
- }
- desFile.createNewFile();
- }
- OutputStream out = new FileOutputStream(desFile);
- byte buffer[] = new byte[1024];
- int realLength;
- while ((realLength = in.read(buffer)) > 0)
- {
- out.write(buffer, 0, realLength);
- }
- in.close();
- out.close();
- }
- }
- //将SD卡文件删除
- public static void deleteFile(File file)
- {
- if (file.exists())
- {
- if (file.isFile())
- {
- file.delete();
- }
- // 如果它是一个目录
- else if (file.isDirectory())
- {
- // 声明目录下所有的文件 files[];
- File files[] = file.listFiles();
- for (int i = 0; i < files.length; i++)
- { // 遍历目录下所有的文件
- deleteFile(files[i]); // 把每个文件 用这个方法进行迭代
- }
- }
- file.delete();
- }
- }
流程就是先把zip包下载到sd卡中,再解压到指定目录,解压完成后zip就没了删之。
在c++里检测版本,在需要更新时通过jni调用download()方法,这里的方法都写成static的,纯是为了jni调用时省点事。
要是不会用通过jni在c++和java之间相互调用可以度娘、google,也可以参考cocos2dx\platform\android\jni目录下Java开头的几个类和samples\HelloCpp\proj.android\src\org\cocos2dx\lib里边的java文件结合着看看就明白了。
还要在AndroidManifest.xml中加sd卡中写文件和访问网络的权限如下:
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.INTERNET"/>
现在sd卡的资源有了,下面解决调用问题,方法有2也直接上代码:
- //方法1
- unsigned long filesize;
- CCImage image;
- char* buffer = (char *)CCFileUtils::sharedFileUtils()->getFileData("/mnt/sdcard/to3/icon.png", "rb", &filesize);
- if(image.initWithImageData((void*)buffer, filesize, CCImage::kFmtPng))
- {
- CCTexture2D *texture = new CCTexture2D();
- texture->initWithImage(&image);
- if( texture )
- {
- CCSprite *sprite = CCSprite::createWithTexture(texture);
- if (sprite)
- {
- CCLog("111sprite != null");
- this->addChild(sprite);
- sprite->setPosition(ccp(200, 100));
- }
- else
- {
- CCLog("111sprite == null");
- }
- }
- }
- //方法2
- bool flag = image.initWithImageFile("/mnt/sdcard/to3/icon.png", CCImage::kFmtPng);
- if (flag)
- {
- CCTexture2D *texture2D = new CCTexture2D();
- texture2D->initWithImage(&image);
- CCSprite *sprite = CCSprite::createWithTexture(texture2D);
- if (sprite)
- {
- CCLog("222sprite != null");
- this->addChild(sprite);
- sprite->setPosition(ccp(100, 100));
- }
- else
- {
- CCLog("222sprite == null");
- }
- }
方法1不只可以读图片,其他的 xml之类的文件也可以读,方法2只是读图片的。
/mnt/sdcard是sd卡的根目录,这里用于测试是写死的,由于手机厂商不同,这个路径也会不同,要通过jni(又是jni)获取Environment.getExternalStorageDirectory()
附图一张,图中的两小人就是上面的两个方法加进去的。
就到这里吧
有什么不对的地方请指正,谢谢!