2012年7月27日 星期五

How to play sound file in Objective C


NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:@"t5"  ofType:@"wav"];
    NSError *error;
    
    AVAudioPlayer  player=  [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:&error];
    
    [player setDelegate:self];
    
    [player prepareToPlay];
    
    [player play];

2012年7月25日 星期三

LeadBolt mobile advertising

Recently I try to use this mobile advertising networks, good CPM.

it provide banner ad, ad wall, notification ad, short ad in one sdk.

but it just work on English language country/area.

http://leadbolt.com/developers_signup.php?ref=10027093

Android app --- Call to SpongeBob

My First Semi-Game app "Call to SpongeBob"


It turn your mobile phone into a child's toy phone, they can use this app to call SpongeBob, Patrick, Squidward, Krabs, Plankton and Sandy.

Like a toy phone, it provide beautiful key tone for your children,
Piano tones, and amazing Bird tones.

* this is just a game, don't worry, it will not make a real phone call.


https://play.google.com/store/apps/details?id=com.vimeok.spongebob






new app released (Asian boy's pop bands MV collection)


https://play.google.com/store/apps/details?id=vimeok.mediaapp.musictv.m




Top 20 Asian/Korean Boy pop-band music video collection, including--
SHINee,
Super Junior,
2AM,
Boyfriend,
2PM,
X-5,
BEAST,
BIG BANG,
CNBlue,
F.CUZ,
FT-Island,
ZE:A,
Infinite,
MBLAQ,
SS501,
U-Kiss,
TVXQ東方神起,
蘇打綠,
信樂團,
五月天



2012年7月23日 星期一

Nokia Lumia 900 台灣開賣---阿是誰要買啦??!!

"在2012 CES Nokia展出Lumia 900, 並獲選為2012年度CES最佳手機, 這隻搭載Windows Phone 7.5的商務趨向智慧型手機正式在台灣開賣了."


昨天才寫 Titan 空機只要9000元, 現在這支Lumia 一樣的硬體規格, 空機要18900, 加上又是末代的不能升級到 Windows8 的 WindowsPhone 7.5, 真的懷疑, 到底誰要買啊..


雖然我之前也很想買這支啦, 但如果半年前來, 我大概會買, 現在喔, 真要, 買 HTC Titan就好啊.
幾乎一樣的硬體規格
9900對18900,

你會買誰啊??

2012年7月22日 星期日

HTC Titan 只要9900

掉真快, 當初空機買 16900 的, 不過我還滿喜歡這隻手機的, 雖然app 沒有 android 多, 不過使用上還滿好用的.



HTC Titan 泰坦智慧機

‧CPU 1.5GHz處理器
‧4.7吋 WVGA觸控螢幕
‧16GB ROM /512 RAM
‧內建800萬畫素相機
‧HTC Sense& Mango中文版
‧F2.2光圈 28mm 廣角/ BSI
‧5連拍/超簡單全景模式
‧支援Tango 網路視訊電話
‧首款Mango HTC Watch 線上影片服務
‧支援HTC Locations 位置服務
‧支援下載Xbox LIVE game  

網路價 $9900

2012年7月21日 星期六

Android: how to set ListView background, ImageButton background as transparent!!

Sometimes we need a transparent background in Listview and imagebutton,

How to set it in XML?

Here is the answer:

in ImageButton

add this line

android:background="@android:color/transparent"

be noticed that when background of a ImageButton was set to transparent, it will fit the size of it's image.


And in ListView, add this

android:cacheColorHint="#00000000"





2nd app is almost ready.





Asian Pop Male Bands app, is almost ready.
include 17 Korean bands--
Shinee
Super Junior
2AM
2PM
Boyfriend
FT-Island
Big Bang
Beast
X-5
ZE:A
CNBlue
Infinite
F.Cuz
SS501
MBLAQ
U-Kiss
TVXQ
three Taiwanese bands--
五月天
蘇打綠
信樂團


2012年7月18日 星期三

How to decompress an zip file with full folder structure


如何用 java 解壓一個 zip 檔




previously, I write an example about how to zip a folder and keep it original folder structure, 


but how to extract a zip file in java and keep it's original structure?

here is a code snippet--


org.apache.commons.compress.archivers.zip.ZipFile zf = new org.apache.commons.compress.archivers.zip.ZipFile(zipFile);
FileInputStream fis = new FileInputStream(zipFile);
ZipInputStream inputStream = new ZipInputStream(fis);

// Loop through all the files and folders
int exttactCount = 0;
progressDialog.setMax(fileCount);
for (ZipEntry entry = inputStream.getNextEntry(); entry != null; entry = inputStream.getNextEntry()) {
String innerFileName = GlobalConfig.getAlbumFolder() + entry.getName();
File innerFile = new File(innerFileName);
if (innerFile.exists()) {
innerFile.delete();
}

// Check if it is a folder
if (entry.isDirectory()) {
// Its a folder, create that folder
innerFile.mkdirs();
} else {
// Create a file output stream
FileOutputStream outputStream = new FileOutputStream(innerFileName);
final int BUFFER = 2048;

// Buffer the ouput to the file
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream, BUFFER);

// Write the contents
int count = 0;
byte[] data = new byte[BUFFER];
while ((count = inputStream.read(data, 0, BUFFER)) != -1) {
bufferedOutputStream.write(data, 0, count);
}

bufferedOutputStream.flush();
bufferedOutputStream.close();

}

inputStream.closeEntry();

}
inputStream.close();

ps: I really like to use apache common library.

problem in android "Click a button to play sound."

Android Sound Pool example

in android if you want to play a sound when user click a button, the code is like following,

MediaPlayer mp;


Button btn1= (Button) findViewById(R.id.button1);

btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mp= MediaPlayer.create(this, R.raw.sound1);
                                mp.start();
}
});


but there are two issues--


1, when user click the button continually, it will cause an null point exception.
2, the sound delay a bit while when I click the button.

to solve this issue, we need to use another solution --> SoundPool



package com.vimeok.soundpoolexample;

import java.util.HashMap;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;


public class SoundManager {

static private SoundManager _instance;
private static SoundPool mSoundPool;
private static HashMap<Integer, Integer> mSoundPoolMap;
private static AudioManager  mAudioManager;
private static Context mContext;

private SoundManager()
{
}

/**
* Requests the instance of the Sound Manager and creates it
* if it does not exist.
*
* @return Returns the single instance of the SoundManager
*/
static synchronized public SoundManager getInstance()
{
   if (_instance == null)
     _instance = new SoundManager();
   return _instance;
}

/**
* Initialises the storage for the sounds
*
* @param theContext The Application context
*/
public static  void initSounds(Context theContext)
{
mContext = theContext;
    mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
    mSoundPoolMap = new HashMap<Integer, Integer>();
    mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);  
}

/**
* Add a new Sound to the SoundPool
*
* @param Index - The Sound Index for Retrieval
* @param SoundID - The Android ID for the Sound asset.
*/
public static void addSound(int Index,int SoundID)
{
mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
}

/**
* Loads the various sound assets
* Currently hardcoded but could easily be changed to be flexible.
*/
public static void loadSounds()
{
mSoundPoolMap.put(1, mSoundPool.load(mContext, R.raw.t0, 1));
mSoundPoolMap.put(2, mSoundPool.load(mContext, R.raw.t1, 1));
mSoundPoolMap.put(3, mSoundPool.load(mContext, R.raw.t2, 1));
mSoundPoolMap.put(4, mSoundPool.load(mContext, R.raw.t3, 1));
mSoundPoolMap.put(5, mSoundPool.load(mContext, R.raw.t4, 1));
mSoundPoolMap.put(6, mSoundPool.load(mContext, R.raw.t5, 1));
mSoundPoolMap.put(7, mSoundPool.load(mContext, R.raw.t6, 1));
mSoundPoolMap.put(8, mSoundPool.load(mContext, R.raw.t7, 1));
mSoundPoolMap.put(9, mSoundPool.load(mContext, R.raw.t8, 1));
mSoundPoolMap.put(10, mSoundPool.load(mContext, R.raw.t9, 1));
mSoundPoolMap.put(11, mSoundPool.load(mContext, R.raw.t11, 1));
mSoundPoolMap.put(12, mSoundPool.load(mContext, R.raw.t12, 1));

}

/**
* Plays a Sound
*
* @param index - The Index of the Sound to be played
* @param speed - The Speed to play not, not currently used but included for compatibility
*/
public static void playSound(int index,float speed)
{
    float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, speed);
}

/**
* Stop a Sound
* @param index - index of the sound to be stopped
*/
public static void stopSound(int index)
{
mSoundPool.stop(mSoundPoolMap.get(index));
}

public static void cleanup()
{
mSoundPool.release();
mSoundPool = null;
   mSoundPoolMap.clear();
   mAudioManager.unloadSoundEffects();
   _instance = null;
 
}
}

then in your main activity,
...
...
...

SoundManager.getInstance();
SoundManager.initSounds(this);
SoundManager.loadSounds();


btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
                                //playsound
SoundManager.playSound(1, 1);
}
});
...
...
...





Leica X2



Leica 在柏林的發表會中做了幾乎是全產品線的更新,除了奇特概念的黑白相機 M Monochrome 外,X1 的後繼機種 X2 也同時發表。X2 外型上與 X1 並無太大的變化,鏡頭也是使用相同的 Elmarit 24mm f/2.8 ASPH 。X2 使用了 16.5MP APS-C CMOS 感光元件(X1 為 12.2MP)、2.7" 23 萬像素 LCD 螢幕。換算等效焦距約為 35mm,對於抓拍以及 Street snap 都是非常適合的,官方也表示 X2 的對焦系統比起 X1 會更為靈敏與準確。
而此次 X2 另一亮點就是配件的多元化,除了機頂熱靴可外接 Leica SF 24D 和 SF 58 閃光燈外。還有外接電子取景器來因應光線太強所造成的 LCD 取景困難,由圖片也可以看到 X2 另外有前握把與光學取景器的配件。配合 X2 其直覺式的操作下對於拍攝上可以更快速適應並得心應手,但可惜的是與 X1 相同依然沒有錄影功能。

Leica X2 規格簡介
  • 16.5MP APS-C CMOS 感光元件(有效像素 16.2MP)
  • 2.7" 23 萬像素 LCD 螢幕
  • 鏡頭為 Elmarit 24mm f/2.8 ASPH(等效焦距約 35mm)
  • ISO 感光值 ISO100-ISO12500、連拍速度每秒 3 or 5fps
  • 支援 RAW 檔拍攝、HDMI輸出
  • 無錄製影片功能
  • 尺寸大小:124 x 69 x 52 mm、重量 450g
  • 儲存格式:SD/SDHC

2012年7月17日 星期二

How to get Youtube MP4 video using java?



import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class Parser {

private static String vid="c2ovrKzRezw";
private static String url="http://www.youtube.com/get_video_info?video_id="+vid;//xzWJvDTfWyc";

static String pattern3="video/mp4";
public static void main(String args[]){
try {
String result= getMessageFromUrl(url);
//System.err.println(result);
String p_result=java.net.URLDecoder.decode(java.net.URLDecoder.decode(result, "UTF-8"),"UTF-8");
//結果太長了, 沒研究是否可以用正規表示式處理, 先用暴力方法解決
  // if somebody know how to use reg press to parse the result, please let me know.
// currently, I just hard code to parse mp4 url
int last=p_result.lastIndexOf("type=video/mp4");
String s2= p_result.substring(0,last+15);
int lasthttp= s2.lastIndexOf("http://");
String mp4Url=s2.substring(lasthttp, s2.length()-1);
System.err.println(mp4Url);
//ok, now save it to disk
File f= new File("d:\\"+vid+".mp4");
org.apache.commons.io.FileUtils.copyURLToFile(new URL(mp4Url),f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static String getMessageFromUrl(String msgUrl) throws IOException {
URL url = new URL(msgUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream()));
String inputLine;
StringBuffer sb = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
return sb.toString();
}

}

that means you can also save youtube video in your android app.
but 18+ video can't be download, it may need to integrate with youtube api to download 18+ video.



蒜泥白肉


蒜泥白肉
食材:
三層肉一塊(150克)、蒜頭10顆、小黃瓜1條、銀芽50克
調味料:
醬油膏、烏醋、味醂
做法:
1.五花肉去皮,肉塊對剖切半,滾水鍋中加入米酒,放入五花肉塊以小火燜煮泡熟。
2.調醬汁:醬油膏50克+水25克+味醂25克+蒜頭10顆,入調理機中打泥過濾,再加少許醬油、紅油、烏醋和香油調味。
3.將濾出的蒜渣放入水鍋中一起燜煮。
4.小黃瓜切絲泡冷水;銀芽汆燙泡冷水,瀝乾水分鋪於盤底。
5.煮好的五花肉拉大薄片排盤,將醬汁澆淋於上即可。
ps. 帶皮的無花不錯, 不用去皮, 燙好後, 放到冰塊堆裡滾一下, 皮就超Q

Why I have to create an adsense account?

I do not know why I need an Adsense account to get pay, if I want to sell app in android market.

I create this adsense account just use to sell app, so, if you google adsense team read this post, please don't not reject due to not so much contents in this blog.

少女時代&韓國少女團體 MV app

今天上線的第一個app









在WindowPhone 7 中, 開啟 Youtube 影片最簡單的方法.

當然你也可以用 WebBrowserTask  來開.
private void openYouTube(String vid)
 {

            WebBrowserTask task = new WebBrowserTask();
            String uri = "http://www.youtube.com/embed/" + vid + "?autoplay=1&hd=1";
            task.Uri = new Uri(uri);
            task.Show();
}

但用 webview user 就知道是youtube 的影片, 感覺不好..

最好的方法是可以用WindowPhone 的 MediaPlayer 來開啟影片,
要達到這樣的功能對剛開始寫 WindowPhone, C# 的我來說, 有點困難, 後來找到一個好東西

MyToolKit
"MyToolkit is a collection of useful classes for WinRT, Windows Phone, Silverlight and WPF. These classes have been developed or collected by Rico Suter. "
網址在這邊..
http://mytoolkit.codeplex.com/

只要這樣
MyToolkit.Multimedia.YouTube.Play(videoId, YouTubeQuality.Quality480P, null);

就可以用 MediaPlayer 放影片了, 不過18+的影片需要認證, 可能要透過整合 Google API 才能撥, 一般的影片都沒問題.
連在 andoird 用 mediaplayer 因有版權問題不能放的影片, 在 WindowsPhone 7 的 MediaPlayer 一樣可以放, 強....

其實我還滿喜歡 WindowPhone 的, 不過用的人少, 好用的 app 也不多.

以下畫面是我的 WindowPhone App, "MusicTube++"
http://www.windowsphone.com/zh-TW/apps/4ce8e82b-5000-4af1-870b-7e06e1bd4fd8




Save URL jpg to file using Objective C in GNUStep

#import <Foundation/Foundation.h>
#import <Foundation/NSUrl.h>

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog (@"hello world");
NSURL *url = [NSURL URLWithString:@"url contains myconetnt"];
NSError *theNetworkError;
    NSString *content = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&theNetworkError];
    NSInteger len= [content length];
    //NSLog(@"%@, contains %i characters",content, len);
    NSString *content2= [content substringToIndex:(len-3)];
    NSString *content3=[content2 stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"%@",content3);
    NSString *myImage = @"http://www.iphonedevsdk.com/forum/images/appads/blueprint.jpg";
NSString *tempImagemUrl = [myImage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *url1 = [NSURL URLWithString:tempImagemUrl];
NSData *mydata = [NSData dataWithContentsOfURL:url1];
NSString *fileName=@"test.jpg";
    BOOL b=[mydata writeToFile:fileName atomically:true];
[pool drain];
return 0;
}

Where is admob test device id??

當使用admob 時, 文件上會建議設定 test device, 但是 test device id 倒底在哪??

ads:testDevices="TEST_EMULATOR, DEVICE_ID"

一開以為是畫面上的 device, 打進去後也沒有用


還來才知道, 原來 Device 會出現在 LogCat 中, 如下圖










加上後, 就會出現測試廣告, 用來測試再多都不用怕出問題了.


An android AsyncTask class to download image from url


it is easy to store web image to local sd card by using apaceh common io...

class initCatalogAsync extends AsyncTask<String, String, String>{
    @Override
        protected void onPreExecute() {
            showDialog(0);
        }
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
for(int i=0; i< videoList.size(); i++){
VideoObj vo= (VideoObj)videoList.get(i);

String thumbsUrl=GlobalConfig.YOUTUBE_THUMBS_URL+vo.getVid()+"/"+GlobalConfig.THUMBS_ID;

File f= new File(GlobalConfig.THUMBS_FOLDER+vo.getVid()+".jpg");
if(!f.exists()){
try {
if(GlobalConfig.DEBUG){
Log.w(TAG,thumbsUrl);
}
FileUtils.copyURLToFile(new URL(thumbsUrl),f);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
@Override
        protected void onProgressUpdate(String... progress) {
            super.onProgressUpdate(progress);
         
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
         
            setListData();
            progressDialog.dismiss();

        }
    }

read/write text file from/into app private storage


public void writeFileData(String filename, String message){
if(GlobalConfig.DEBUG){
Log.w(TAG,"Write file:"+message);
}
        try{
            FileOutputStream fout= openFileOutput(filename, MODE_PRIVATE);
            byte[] b= message.getBytes("UTF-8");
            fout.write(b);
            fout.close();
        }catch(Exception e){
            e.printStackTrace();
        }

    }
    public void readFileData(String filename){
   
        String result="";
     
        try{
            FileInputStream fin= openFileInput(filename);
            int length= fin.available();
            byte[] b= new byte[length];
            fin.read(b);
            result= EncodingUtils.getString(b, "UTF-8");
            if(GlobalConfig.DEBUG){
    Log.w(TAG,"read file:"+result);
    }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

First App released

First App
Music Video of Asian Hottest Girls Bands
was released

https://play.google.com/store/apps/details?id=vimeok.mediaapp.musictv

2012年7月11日 星期三

iOS, Android, WindowsPhone 開發的不同點.

就最基礎的說

Windows Phone 秉持一貫 MS 的做風, 畫面元件擺好, 直接點元件的 Event, 就開始寫程式.

Android, 雖然畫面和code 是分開, 但是用findViewById 取得元件後, 直接元件的 event, 對習慣 java 的人來說, 也算直覺.

iOS, Objective C, 一開始畫面和 code 沒有任何關係, 有畫面後, 還要額外寫一個Class 來代表這個畫面, 然後在這個 class 裏要定義畫面的元件(IBOutlet), 和event (IBAction), 然後再拉線, 把畫面的物件, 物件的行為和剛剛定義的class 裡的 IBOutlet, IBAction 連起來.

2012年7月2日 星期一

How to compress(zip) a folder and keep original folder structure using java

如何用 java 壓縮(zip)一個目錄
How to compress(zip) a folder and keep original folder structure  using java

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Enumeration;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;

/**
 * Utility to Zip and Unzip nested directories recursively.
 * @author 
 */
public class ZipUtil {

    /**
     * Creates a zip file at the specified path with the contents of the specified directory.
     * NB:
     *
     * @param directoryPath The path of the directory where the archive will be created. eg. c:/temp
     * @param zipPath The full path of the archive to create. eg. c:/temp/archive.zip
     * @throws IOException If anything goes wrong
     */
    public static void createZip(String directoryPath, String zipPath) throws IOException {
        FileOutputStream fOut = null;
        BufferedOutputStream bOut = null;
        ZipArchiveOutputStream tOut = null;

        try {
            fOut = new FileOutputStream(new File(zipPath));
            bOut = new BufferedOutputStream(fOut);
            tOut = new ZipArchiveOutputStream(bOut);
            addFileToZip(tOut, directoryPath, "");
        } finally {
            tOut.finish();
            tOut.close();
            bOut.close();
            fOut.close();
        }

    }

    /**
     * Creates a zip entry for the path specified with a name built from the base passed in and the file/directory
     * name. If the path is a directory, a recursive call is made such that the full directory is added to the zip.
     *
     * @param zOut The zip file's output stream
     * @param path The filesystem path of the file/directory being added
     * @param base The base prefix to for the name of the zip file entry
     *
     * @throws IOException If anything goes wrong
     */
    private static void addFileToZip(ZipArchiveOutputStream zOut, String path, String base) throws IOException {
        File f = new File(path);
        String entryName = base + f.getName();
        ZipArchiveEntry zipEntry = new ZipArchiveEntry(f, entryName);
        
        zOut.putArchiveEntry(zipEntry);
        System.err.println(f.getAbsolutePath());
        if (f.isFile()) {
        if(f.getName().indexOf("7z")>0){
        IOUtils.copy(new FileInputStream(f), zOut);
        zOut.closeArchiveEntry();
        }
        } else {
            zOut.closeArchiveEntry();
            File[] children = f.listFiles();

            if (children != null) {
                for (File child : children) {
                    addFileToZip(zOut, child.getAbsolutePath(), entryName + "/");
                }
            }
        }
    }

    /**
     * Extract zip file at the specified destination path. 
     * NB:archive must consist of a single root folder containing everything else
     * 
     * @param archivePath path to zip file
     * @param destinationPath path to extract zip file to. Created if it doesn't exist.
     */
    public static void extractZip(String archivePath, String destinationPath) {
        File archiveFile = new File(archivePath);
        File unzipDestFolder = null;

        try {
            unzipDestFolder = new File(destinationPath);
            String[] zipRootFolder = new String[]{null};
            unzipFolder(archiveFile, archiveFile.length(), unzipDestFolder, zipRootFolder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Unzips a zip file into the given destination directory.
     *
     * The archive file MUST have a unique "root" folder. This root folder is 
     * skipped when unarchiving.
     * 
     * @return true if folder is unzipped correctly.
     */
    @SuppressWarnings("unchecked")
    private static boolean unzipFolder(File archiveFile,
            long compressedSize,
            File zipDestinationFolder,
            String[] outputZipRootFolder) {

        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(archiveFile);
            byte[] buf = new byte[65536];

            Enumeration entries = zipFile.getEntries();
            while (entries.hasMoreElements()) {
                ZipArchiveEntry zipEntry = (ZipArchiveEntry)entries.nextElement();
                String name = zipEntry.getName();
                name = name.replace('\\', '/');
                int i = name.indexOf('/');
                if (i ==0) {
                        outputZipRootFolder[0] = name.substring(0, i);
                    //}
                    name = name.substring(i + 1);
                }

                File destinationFile = new File(zipDestinationFolder, name);
                if (name.endsWith("/")) {
                    if (!destinationFile.isDirectory() && !destinationFile.mkdirs()) {
                        log("Error creating temp directory:" + destinationFile.getPath());
                        return false;
                    }
                    continue;
                } else if (name.indexOf('/') != -1) {
                    // Create the the parent directory if it doesn't exist
                    File parentFolder = destinationFile.getParentFile();
                    if (!parentFolder.isDirectory()) {
                        if (!parentFolder.mkdirs()) {
                            log("Error creating temp directory:" + parentFolder.getPath());
                            return false;
                        }
                    }
                }

                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(destinationFile);
                    int n;
                    InputStream entryContent = zipFile.getInputStream(zipEntry);
                    while ((n = entryContent.read(buf)) != -1) {
                        if (n > 0) {
                            fos.write(buf, 0, n);
                        }
                    }
                } finally {
                    if (fos != null) {
                        fos.close();
                    }
                }
            }
            return true;

        } catch (IOException e) {
            log("Unzip failed:" + e.getMessage());
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                    log("Error closing zip file");
                }
            }
        }

        return false;
    }

    private static void log(String msg) {
        System.out.println(msg);
    }

    /**
     * Method for testing zipping and unzipping.
     * @param args 
     */
    public static void main(String[] args) throws IOException {
        createZip("/temp/Dada", "/temp/Dada.zip");
        //extractZip("c:/temp/99/output2.zip", "c:/temp/99/1");
    }
}