package com.bigdo.service; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicHeader; import com.bigdo.app.R; import com.bigdo.common.BDSQLiteHelper; import com.bigdo.common.RConfig; import com.bigdo.common.VideoDownHelper; import com.bigdo.util.MD5; import com.bigdo.util.Pub; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Binder; import android.os.Environment; import android.os.IBinder; import android.util.Log; import android.widget.RelativeLayout; import android.widget.RemoteViews; import android.widget.TextView; public class DownloadService extends Service { NotificationManager notification_m; Notification notification; DownloadVideo download; private final IBinder result = new LocalBinder(); DownBroadcastReceiver downBroadcast = null; public static final String ACTION = "com.bigdo.service.DownloadService"; public class LocalBinder extends Binder { public DownloadService getService() { return DownloadService.this; } } @Override public IBinder onBind(Intent arg0) { return result; } @Override public void onCreate() { super.onCreate(); this.setForeground(true); startDown(); startDownBroadcast(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); startDown(); startDownBroadcast(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { startDown(); startDownBroadcast(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); stopDown(); stopVideoBroadcast(); } private void startDownBroadcast() { if (downBroadcast == null) { downBroadcast = new DownBroadcastReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(DownloadService.ACTION); registerReceiver(downBroadcast, filter); Log.e("downBroadcast", "start"); } } private void stopVideoBroadcast() { if (downBroadcast != null) { try { unregisterReceiver(downBroadcast); } catch (Exception e) { } downBroadcast = null; Log.e("downBroadcast", "stop"); } } public class DownBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent arg1) { String action = arg1.getAction(); if (action.equals(DownloadService.ACTION)) { if (download != null) { download.unLock(); } } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { if (isConnected()) { if (download != null) { download.unLock(); } } } } } public boolean isConnected() { ConnectivityManager mConnectivityManager = (ConnectivityManager) this .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mWiFiNetworkInfo = mConnectivityManager .getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (mWiFiNetworkInfo != null) { if (!mWiFiNetworkInfo.isAvailable()) { NetworkInfo mMobileNetworkInfo = mConnectivityManager .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if (mWiFiNetworkInfo != null) { return mMobileNetworkInfo.isAvailable() && mMobileNetworkInfo.isConnected(); } } else { return true; } } return false; } private void stopDown() { if (download != null) { download.interrupt(); } download = null; } private void startDown() { if (download == null) { download = new DownloadVideo(); download.start(); } else { download.unLock(); } } private class DownloadVideo extends Thread { private Object lockObj = new Object(); private String baseDir = "", baseUrl = ""; @Override public void run() { super.run(); download(); } public void unLock() { try { synchronized (lockObj) { lockObj.notifyAll(); } } catch (Exception e1) { } } public void lock() { try { synchronized (lockObj) { lockObj.wait(1000 * 60); } } catch (Exception e1) { } } private void download() { BDSQLiteHelper sqlobj = null; String status = Environment.getExternalStorageState(); if (status.equals(Environment.MEDIA_MOUNTED)) { baseDir = Environment.getExternalStorageDirectory() + RConfig.Video_Dir; baseUrl = RConfig.getBaseUrl(DownloadService.this); DownInfo pre_down = null; while (!this.isInterrupted()) { if (isConnected()) { DownInfo down = look(); if (down != null) { if (pre_down != null && pre_down.idtype == down.idtype && pre_down.idvideo == down.idvideo) { pre_down = null; lock(); } doDown(down); pre_down = down; continue; } pre_down = null; } lock(); pre_down = null; } } } private void doDown(DownInfo down) { BDSQLiteHelper sqlobj = null; String _f = VideoDownHelper.cacheFileName(down.idtype, down.idvideo, down.downurl); String l_f = _f + ".r.t"; String l_f_f = _f + ".r"; int lv = 0; try { startDown(down.idvideo, down.title); File dir = new File(baseDir); if (!dir.exists()) { dir.mkdirs(); } File dff = new File(dir, l_f_f); if (dff.exists()) { updateDown(down); downFinish(down.idvideo); return; } File df = new File(dir, l_f); long slg = 0, tc = 0; if (df.exists()) { slg = df.length() - 180; } if (slg < 0) { slg = 0; } String url = ""; String downurl = down.downurl; int hi = downurl.indexOf("http://"); if (hi >= 0) { url = downurl; } else { hi = downurl.indexOf("/"); if (hi == 0) { hi++; downurl = downurl.substring(hi); } downurl = baseUrl + downurl; } url = Pub.handleDownVideoUrl(downurl); try { Log.e("doDown", url); } catch (Exception e) { } HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(url); if (slg > 0) { try { HttpClient client_test = new DefaultHttpClient(); HttpGet request_test = new HttpGet(url); HttpResponse response_test = client_test .execute(request_test); int code = response_test.getStatusLine() .getStatusCode(); if (code == 200) { tc = response_test.getEntity().getContentLength(); } request_test.abort(); } catch (Exception e) { } if (tc > 0 && slg >= tc) { copyFile(l_f, l_f_f); updateDown(down); downFinish(down.idvideo); return; } } // 设置下载的数据位置XX字节到结尾 Header header_size = new BasicHeader("Range", "bytes=" + slg + "-"); request.addHeader(header_size); HttpResponse response = client.execute(request); int code = response.getStatusLine().getStatusCode(); long fc = 0; if (code == 200 || code == 206) { InputStream in = null; FileOutputStream out = null; try { HttpEntity respEnt = response.getEntity(); if (respEnt.isStreaming()) { if (tc <= 0) { tc = respEnt.getContentLength(); } in = respEnt.getContent(); if (slg > 0) { // in.skip(slg); out = new FileOutputStream(df, true); } else { out = new FileOutputStream(df); } byte[] buf = new byte[2 * 1024]; fc = slg; if (fc > 0) { lv = (int) ((fc / tc) * 100); if (fc >= tc) { lv = 100; copyFile(l_f, l_f_f); updateDown(down); downFinish(down.idvideo); return; } downing(down.idvideo, lv); } int lg = 0, flv = 0, sumlv = 0; long lt = 0; boolean frist = true; try { while ((lg = in.read(buf)) > 0) { if (slg <= 0 && frist) { byte[] pre_data = "123456789987654321123456789987654321" .getBytes(); for (int j = 0; j < 5; j++) { out.write(pre_data); } out.flush(); frist = false; } out.write(buf, 0, lg); out.flush(); fc += lg; lv = (int) ((fc * 1.0000 / tc) * 100); if (lv > 100) { lv = 100; } sumlv = Math.abs(flv - lv); if (Math.abs((lt - System .currentTimeMillis())) >= 400 || sumlv >= 3 || lv >= 100) { downing(down.idvideo, lv); flv = lv; lt = System.currentTimeMillis(); } } } catch (Exception e) { downError(down.idvideo, "视频下载中断,已完成 " + lv + "%"); } if (fc >= tc) { copyFile(l_f, l_f_f); downFinish(down.idvideo); updateDown(down); } buf = null; } } catch (Exception ex) { downError(down.idvideo, "视频下载出错,已完成 " + lv + "%"); } finally { try { if (out != null) { out.close(); } } catch (Exception e) { } out = null; try { if (in != null) { in.close(); } } catch (Exception e) { } in = null; } } else if (code >= 400 && code < 500) { downError(down.idvideo, "视频不存在 或 连接失效."); delDown(down); downFile404(l_f, l_f_f); } else { downError(down.idvideo, "视频下载失败,已完成 " + lv + "%"); // delDown(down); } } catch (Exception ex) { downError(down.idvideo, "视频下载出错,已完成 " + lv + "%"); // delDown(down); // downFile404(l_f, l_f_f); } } private void downFile404(String t, String f) { try { File tf = new File(baseDir, t); File tff = new File(baseDir, f); tf.delete(); tff.delete(); } catch (Exception e) { } } private void copyFile(String t, String f) { File tf = new File(baseDir, t); File tff = new File(baseDir, f); if (!tf.renameTo(tff)) { try { if (tf.exists()) { FileInputStream in = new FileInputStream(tf); FileOutputStream out = new FileOutputStream(tff); byte[] buf = new byte[4 * 1024]; while ((in.read(buf)) > 0) { out.write(buf); out.flush(); } buf = null; out.close(); in.close(); tf.delete(); } } catch (Exception e) { } } try { tf.delete(); } catch (Exception e) { } } } private DownInfo look() { BDSQLiteHelper sqlobj = null; DownInfo down = null; SQLiteDatabase sqlobj_r = null; Cursor cu = null; try { sqlobj = new BDSQLiteHelper(DownloadService.this); sqlobj_r = sqlobj.getReadableDatabase(); String sql = "select * from download where idtype > 0 and idvideo > 0 and isfinish = 0 order by idown asc limit 0,1"; cu = sqlobj_r.rawQuery(sql, null); while (cu.moveToNext()) { int idown = cu.getInt(cu.getColumnIndex("idown")); int idvideo = cu.getInt(cu.getColumnIndex("idvideo")); int idtype = cu.getInt(cu.getColumnIndex("idtype")); String title = cu.getString(cu.getColumnIndex("title")); String downurl = cu.getString(cu.getColumnIndex("downurl")); if (title != null && !title.equals("") && downurl != null && !downurl.equals("")) { down = new DownInfo(); down.idown = idown; down.idvideo = idvideo; down.idtype = idtype; down.title = title; down.downurl = downurl; } break; } } catch (Exception e) { Log.e("look", e.getMessage()); } try { if (cu != null) { cu.close(); cu = null; } } catch (Exception ex) { } try { if (sqlobj_r != null) { sqlobj_r.close(); sqlobj_r = null; } } catch (Exception ex) { } try { if (sqlobj != null) { sqlobj.close(); sqlobj = null; } } catch (Exception ex) { } return down; } private void delDown(DownInfo down) { BDSQLiteHelper sqlobj = null; SQLiteDatabase sqlobj_w = null; try { sqlobj = new BDSQLiteHelper(DownloadService.this); sqlobj_w = sqlobj.getWritableDatabase(); sqlobj_w.delete("download", "idtype = ? and idvideo = ?", new String[] { down.idtype + "", down.idvideo + "" }); } catch (Exception e) { } try { if (sqlobj_w != null) { sqlobj_w.close(); sqlobj_w = null; } } catch (Exception ex) { } try { if (sqlobj != null) { sqlobj.close(); sqlobj = null; } } catch (Exception ex) { } } private void updateDown(DownInfo down) { BDSQLiteHelper sqlobj = null; SQLiteDatabase sqlobj_w = null; try { sqlobj = new BDSQLiteHelper(DownloadService.this); sqlobj_w = sqlobj.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put("isfinish", 1); sqlobj_w.update("download", cv, "idtype = ? and idvideo = ? ", new String[] { down.idtype + "", down.idvideo + "" }); } catch (Exception e) { } try { if (sqlobj_w != null) { sqlobj_w.close(); sqlobj_w = null; } } catch (Exception ex) { } try { if (sqlobj != null) { sqlobj.close(); sqlobj = null; } } catch (Exception ex) { } } private void initNotification(int idNotify) { if (notification_m == null) { notification_m = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } notification = new Notification(R.drawable.ra_downing, "下载", System.currentTimeMillis()); notification.flags = Notification.FLAG_AUTO_CANCEL;// //Notification.FLAG_ONGOING_EVENT // | Notification.FLAG_AUTO_CANCEL; // host.setTextViewText(R.id.ra_downloadfile_filename, fileName // + lastSuffix); notification.contentView = new RemoteViews(getPackageName(), R.layout.activity_downloadfile); Intent i = new Intent(); PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0); notification.contentIntent = pi; // notification.setLatestEventInfo(context, "", "", contentIntent); if (idNotify > Integer.MAX_VALUE) { idNotify = 1200; } notification_m.notify(idNotify, notification); } private void startDown(int idNotify, String title) { initNotification(idNotify); notification.icon = R.drawable.ra_downing; notification.contentView.setViewVisibility(R.id.ra_downloadfile_finish, TextView.GONE); notification.contentView.setViewVisibility( R.id.ra_downloadfile_progress, RelativeLayout.VISIBLE); notification.contentView.setTextViewText(R.id.ra_downloadfile_filename, title); notification.contentView.setImageViewResource( R.id.ra_downloadfile_fileimg, notification.icon); notification_m.notify(idNotify, notification); } private void downFinish(int idNotify) { notification.icon = R.drawable.ra_downfinish; notification.contentView.setViewVisibility( R.id.ra_downloadfile_progress, RelativeLayout.GONE); notification.contentView.setViewVisibility(R.id.ra_downloadfile_finish, TextView.VISIBLE); notification.contentView.setTextViewText(R.id.ra_downloadfile_finish, "下载完成!"); notification.contentView.setImageViewResource( R.id.ra_downloadfile_fileimg, notification.icon); notification_m.notify(idNotify, notification); } private void downing(int idNotify, int lv) { notification.icon = R.drawable.ra_downing; notification.contentView.setViewVisibility(R.id.ra_downloadfile_finish, TextView.GONE); notification.contentView.setViewVisibility( R.id.ra_downloadfile_progress, RelativeLayout.VISIBLE); notification.contentView.setProgressBar( R.id.ra_downloadfile_progressbar, 100, lv, false); notification.contentView.setTextViewText( R.id.ra_downloadfile_progressnum, lv + "%"); notification.contentView.setImageViewResource( R.id.ra_downloadfile_fileimg, notification.icon); notification_m.notify(idNotify, notification); } private void downError(int idNotify, String error) { notification.icon = R.drawable.ra_downerror; notification.contentView.setViewVisibility( R.id.ra_downloadfile_progress, RelativeLayout.GONE); notification.contentView.setViewVisibility(R.id.ra_downloadfile_finish, TextView.VISIBLE); notification.contentView.setTextViewText(R.id.ra_downloadfile_finish, error); notification.contentView.setImageViewResource( R.id.ra_downloadfile_fileimg, notification.icon); notification_m.notify(idNotify, notification); } }