0%

下面的代码可以解压包含目录的ZIP文件.需要先去http://ant.apache.org/ivy/download.cgi下载 Apache Ant,并导入其中的ant.jar.

package com.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

public class T
{
    /*
     * 下载Apache Ant http://ant.apache.org/ivy/download.cgi 导入其中的ant.jar
     */
    public static void main(String[] args) throws IOException
    {
        // TODO Auto-generated method stub
        ZipFile zf = new ZipFile("D:/adf.zip");
        // ZIP文件
        String outDir = "D:/";
        // 输出路径
        Enumeration entries = zf.getEntries();
        while (entries.hasMoreElements())
        {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            System.out.println(entry.getName());
            File f = new File(outDir + entry.getName());
            if (entry.isDirectory())
            {
                continue;
            }
            File parent = f.getParentFile();
            if (!parent.exists())
            {
                parent.mkdirs();
                //这里就会创建该文件所有的上级目录,所以上面isDirectory()不执行,直接continue
            }
            InputStream is = zf.getInputStream(entry);
            FileOutputStream fop = new FileOutputStream(outDir + entry.getName());
            int len = 0;
            byte[] bs = new byte[1024];
            while ((len = is.read(bs, 0, 1024)) > 0)
            {
                fop.write(bs, 0, len);
            }
            is.close();
            fop.close();

        }
    }

}

最近掌上优酷的老用户说不能播放,那个是用网上公开的API和KEY写的,估计是优酷把那个KEY给封了(优酷没土豆大方,KEY不是普通人能申请得到的).因为优酷之前给各大市场发律师信,要求封杀掌上优酷,所以这里只做技术研究,掌上优酷还是不会再更新. 下面的代码是参考http://3shi.net/analyze-youku-video-address/ 写的,没有采用优酷的API,但是最近优酷又稍稍改了,原文的有些部分已经不适用,取到的地址不能再播放. 这段代码会优先取MP4格式的视频,没有MP4格式才取FLV格式.需要使用org.json

package com.test;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Main
{

    public static void main(String[] args) throws Exception
    {
        String id="XMzE3OTQ0Nzk2";
        String s = Common.getHtml("http://v.youku.com/player/getPlayList/VideoIDS/"+id);
        JSONObject jsobj = new JSONObject(s);
        JSONArray jsonarr = jsobj.getJSONArray("data");
        JSONObject obj1 = jsonarr.getJSONObject(0);
        double seed = obj1.getDouble("seed");
        JSONObject obj2 = obj1.getJSONObject("streamfileids");
        String mp4id = null;
        String flvid = null;
        String format = null;
        try
        {
            mp4id = obj2.getString("mp4");
            format = "mp4";
        } catch (JSONException e)
        {
            System.out.println("没有MP4格式");
            try
            {
                flvid = obj2.getString("flv");
                format = "flv";
            } catch (JSONException e1)
            {
                System.out.println("没有FLV格式");
                return;
            }
        }

        String realfileid = null;
        if (format.equals("mp4"))
        {
            realfileid = getFileID(mp4id, seed);
        } else
        {
            realfileid = getFileID(flvid, seed);
        }
        String idLeft = realfileid.substring(0, 8);
        String idRight = realfileid.substring(10);

        String sid = genSid();
        JSONObject obj3 = obj1.getJSONObject("segs");
        JSONArray mp4arr = obj3.getJSONArray(format);
        for (int i = 0; i < mp4arr.length(); i++)
        {
            JSONObject o = mp4arr.getJSONObject(i);
            String k = o.getString("k");
            String url = "http://f.youku.com/player/getFlvPath/sid/" + sid + "_" + String.format("%1$02X", i) + "/st/" + format
                    + "/fileid/" + idLeft + String.format("%1$02X", i) + idRight + "?K=" + k;
            System.out.println(url);
        }

    }

    private static String getFileID(String fileid, double seed)
    {
        String mixed = getFileIDMixString(seed);
        String[] ids = fileid.split("\\*");
        StringBuilder realId = new StringBuilder();
        int idx;
        for (int i = 0; i < ids.length; i++)
        {
            idx = Integer.parseInt(ids[i]);
            realId.append(mixed.charAt(idx));
        }
        return realId.toString();
    }

    public static String genSid()
    {
        int i1 = (int) (1000 + Math.floor(Math.random() * 999));
        int i2 = (int) (1000 + Math.floor(Math.random() * 9000));
        return System.currentTimeMillis() + "" + i1 + "" + i2;
    }

    private static String getFileIDMixString(double seed)
    {
        StringBuilder mixed = new StringBuilder();
        StringBuilder source = new StringBuilder("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890");
        int index, len = source.length();
        for (int i = 0; i < len; ++i)
        {
            seed = (seed * 211 + 30031) % 65536;
            index = (int) Math.floor(seed / 65536 * source.length());
            mixed.append(source.charAt(index));
            source.deleteCharAt(index);
        }
        return mixed.toString();
    }

}

Object o=true;
boolean b=Boolean.parseBoolean(o.toString());

之前一直都把耗时操作放在新线程里处理,包括添加修改ListView的Item,处理完了再用handler发个EmptyMessage,执行listAdapter.notifyDataSetChanged(),但我发现用这种方法经常会出现java.lang.IllegalStateException:The content of the adapter has changed but ListView did not receive a notification异常.即使在notifyDataSetChanged()前把listview隐藏。 其实可以通过把数据传给handler,添加删除清空什么的操作都让handler来处理,这样就不会出错。 传送数据是用Bundle,用过Intent应该很熟悉,不解释:

package com.pocketdigi.test3;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class main extends Activity {
    /** Called when the activity is first created. */
    TextView tv;
    Button btn;
    Handler handler;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tv=(TextView)findViewById(R.id.tv);
        btn=(Button)findViewById(R.id.btn);
        handler=new Handler(){

            @Override
            public void handleMessage(Message msg)
            {
                // TODO Auto-generated method stub
                super.handleMessage(msg);

                switch(msg.what)
                {
                case 1:
                    Bundle bundle=msg.getData();
                    System.out.println(bundle.get("add"));
                    break;
                }
            }
            
        };
        btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Message msg = handler.obtainMessage();
                msg.what=1;
                Bundle bundle = new Bundle();
                bundle.putString("add", "sdfasdfasf");
                msg.setData(bundle);
                handler.sendMessage(msg);
//				handler.sendEmptyMessage(0);
            }});
    }
}

一般在Java中,方法的参数都是以px为单位的,但是因为Android分辨率很多,如果用px作单位,无法作自动匹配,所以我们必须把px转换为dp.

 DisplayMetrics dm = getResources().getDisplayMetrics();
int dp=100;
int px=(int)(dp*dm.density);

px就是dp值乘以相应的density,宽度为320px的屏幕,density为1,宽为480px的屏幕,density为1.5

    public static String decodeUnicode(String dataStr) {  

        final StringBuffer buffer = new StringBuffer();  
        Pattern p=Pattern.compile("\\\\u([\\S]{4})([^\\\\]*)");
        Matcher match=p.matcher(dataStr);
        while(match.find())
        {
            char letter = (char) Integer.parseInt(match.group(1), 16);
            buffer.append(new Character(letter).toString());
            buffer.append(match.group(2));
        }
        
        return buffer.toString();  
    } 
    //针对某网站,只转中文而不转数字写的,可以直接把其中的数字返回
    //如果只有中文,不要append group(2)就可以,当然,不改也是没有问题的

用下面的方法关闭Activity间切换时动画效果,有个副作用,就是欲打开的Activity必须是新开,没有在内存中,所以每次startActivity后,需要把自己finish掉,不能加FLAG_ACTIVITY_REORDER_TO_FRONT。

Intent intent = new Intent(this, Target.class);
startActivity(intent);
finish();
overridePendingTransition(0, 0);
//无动画

如果直接用rm 来删,会提示Argument list too long 用下面的方法删: ls |xargs rm ls与|之间有空格。回车后慢慢等吧。