cocos2d-x 读取android手机sd卡中的资源(android http下载zip资源、解压)

   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()

附图一张,图中的两小人就是上面的两个方法加进去的。





就到这里吧


有什么不对的地方请指正,谢谢!



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值