編輯:Android開發實例
第一篇實現一個簡單的代理服務器與Android的MediaPlayer結合(僅支持Http Get),可以通過代理服務器來轉發MediaPlayer的Request以及傳輸服務器的Response,但是還不能支持Seek,這次提高篇支持了Seek。代理服務器可以增強MediaPlayer對復雜的Http情況的適應,可以播放帶防盜鏈的媒體文件,邊播邊存,還可以對大體積的媒體文件(如視頻)進行多線程預加載,達到快速播放的效果。
本文代碼運行在模擬器上,使用Microsoft Network Monitor 3.4來抓包,通過抓包可以發現seek的操作會重新連接服務器,並在Http Get請求中加入Range 字段,所以代理服務器每次監聽到MediaPlayer的request都需要新建socket與遠程服務器連接。
本文的代碼可以到http://download.csdn.net/detail/hellogv/4332362下載,本文程序運行效果如圖:
接下來貼出核心代碼HttpGetProxy.java:
- public class HttpGetProxy {
- final static private String TAG = "HttpGetProxy";
- final static private String LOCAL_IP_ADDRESS = "127.0.0.1";
- final static private int HTTP_PORT = 80;
- private int local_ip_port;
- private ServerSocket localServer = null;
- private Socket localSocket = null;
- private Socket remoteSocket = null;
- private String remoteHost;
- private InputStream in_remoteSocket;
- private OutputStream out_remoteSocket;
- private InputStream in_localSocket;
- private OutputStream out_localSocket;
- private SocketAddress address;
- private interface OnFinishListener {
- void onFinishListener();
- }
- /**
- * 初始化代理服務器
- * @param localport 代理服務器監聽的端口
- */
- public HttpGetProxy(int localport) {
- local_ip_port=localport;
- try {
- localServer = new ServerSocket(localport, 1,
- InetAddress.getByName(LOCAL_IP_ADDRESS));
- } catch (UnknownHostException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- /**
- * 結束時,清除所有資源
- */
- private OnFinishListener finishListener = new OnFinishListener() {
- @Override
- public void onFinishListener() {
- System.out.println("..........release all..........");
- Log.e(TAG, "..........release all..........");
- try {
- in_localSocket.close();
- out_remoteSocket.close();
- in_remoteSocket.close();
- out_localSocket.close();
- localSocket.close();
- remoteSocket.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- };
- /**
- * 把網絡URL轉為本地URL,127.0.0.1替換網絡域名
- * @param url 網絡URL
- * @return 本地URL
- */
- public String getLocalURL(String url){
- String result = null;
- URI originalURI=URI.create(url);
- remoteHost=originalURI.getHost();
- if(originalURI.getPort()!=-1){//URL帶Port
- address = new InetSocketAddress(remoteHost,
- originalURI.getPort());//使用默認端口
- result=url.replace(remoteHost+":"+originalURI.getPort(),
- LOCAL_IP_ADDRESS+":"+local_ip_port);
- }
- else{//URL不帶Port
- address = new InetSocketAddress(remoteHost,
- HTTP_PORT);//使用80端口
- result=url.replace(remoteHost,LOCAL_IP_ADDRESS+":"+local_ip_port);
- }
- return result;
- }
- /**
- * 啟動代理服務器
- * @throws IOException
- */
- public void startProxy() throws IOException {
- new Thread() {
- public void run() {
- int bytes_read;
- byte[] local_request = new byte[1024];
- byte[] remote_reply = new byte[1024];
- while (true) {
- try {
- //--------------------------------------
- //監聽MediaPlayer的請求,MediaPlayer->代理服務器
- //--------------------------------------
- localSocket = localServer.accept();
- Log.e(TAG, "..........localSocket connected..........");
- in_localSocket = localSocket.getInputStream();
- out_localSocket = localSocket.getOutputStream();
- Log.e(TAG, "..........init local Socket I/O..........");
- String buffer = "";//保存MediaPlayer的HTTP請求
- while ((bytes_read = in_localSocket.read(local_request)) != -1) {
- String str = new String(local_request);
- Log.e("localSocket---->", str);
- buffer = buffer + str;
- if (buffer.contains("GET")
- && buffer.contains("\r\n\r\n")) {
- // ---把request中的本地ip改為遠程ip---//
- buffer = buffer.replace(LOCAL_IP_ADDRESS,remoteHost);
- break;
- }
- }
- Log.e(TAG, "..........local finish receive..........");
- //--------------------------------------
- //把MediaPlayer的請求發到網絡服務器,代理服務器->網絡服務器
- //--------------------------------------
- remoteSocket = new Socket();
- remoteSocket.connect(address);
- Log.e(TAG,"..........remote Server connected..........");
- in_remoteSocket = remoteSocket.getInputStream();
- out_remoteSocket = remoteSocket.getOutputStream();
- out_remoteSocket.write(buffer.getBytes());//發送MediaPlayer的請求
- out_remoteSocket.flush();
- //------------------------------------------------------
- //把網絡服務器的反饋發到MediaPlayer,網絡服務器->代理服務器->MediaPlayer
- //------------------------------------------------------
- Log.e(TAG,"..........remote start to receive..........");
- while ((bytes_read = in_remoteSocket.read(remote_reply)) != -1) {
- out_localSocket.write(remote_reply, 0, bytes_read);
- out_localSocket.flush();
- }
- Log.e(TAG, "..........over..........");
- finishListener.onFinishListener();//釋放資源
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }.start();
- }
- }
如上一節中所講的那樣創建了ApiDemo工程後,我們就可以進行每個示例代碼的分
需求:默認為00:00:00,點擊開始按鈕時清零後開始計時,出現如10:28:34。點擊停止的時候停止計時。問題:使用Calendar DateFormat的方法
本文實例講述了Android編程實現二級下拉菜單及快速搜索的方法。分享給大家供大家參考,具體如下: 一、我們要做什麼? 上面有個搜索框,下面是一個二級下拉菜單。
多開發者不知道ListView列表控件的快速滾動滑塊是如何啟用的,這裡Android開發網告訴大家,輔助滾動滑塊只需要一行代碼就可以搞定,如果你使用XML布局