app离线下载
前段时间做了一个离线下载的模块,需求如下:
1 public static final int CANCEL_STATE = 1 ; 2 3 private state int state ; 4 5 ... 6 7 //download 8 9 10 11 while ( ... ) { 12 13 ... 14 15 if ( state == CANCEL_STATE ) { 16 17 break ; 18 19 } 20 21 }
暂停就相当于取消了当前任务,服务去处理下一个intent。
1 File file = new File ( path ) ; 2 3 file.getParentFile().mkdirs () ; 4 5 RandomAccessFile rdFile = new RandomAccessFile ( file, "rwd" ) ;
//获得刚刚下载的文件的大小
1 int mCurrentSize = ( int ) rdFile.length () ; 2 3 HttpURLConnection conn = ( HttpURLConnection ) new URL ( url ).openConnection () ; 4 5 conn.setConnectTimeout ( 5000 ) ; 6 7 conn.setRequestMethod ( "get" ) ;
//从mCurrentSize后开始下载
conn.setRequestProperty ( "Range", "bytes=" + mCurrentSize + "-" ) ;
rdFile.seek ( mCurrentSize ) ;
//下面自定义一个可以删除intent的服务,只显示新增的代码和覆盖的部分,其他和IntentService一样
1 public abstract class BaseIntentService extends Service { 2 3 private final int MESSAGE_TYPE = 12 ; //消息类型 4 5 6 7 @Override 8 9 public void onStart ( Intent intent, int startId ) { 10 11 Message msg = mServiceHandler.obtainMessage () ; 12 13 msg.arg1 = startId ; 14 15 msg.obj = intent ; 16 17 msg.what = MESSAGE_TYPE ; 18 19 mServiceHandler.sendMessage ( msg ) ; 20 21 } 22 23 24 25 protected boolean hasIntent ( Intent intent ) { 26 27 return mServiceHandler.hasMessages ( MESSAGE_TYPE, intent ) ; 28 29 } 30 31 32 33 protected void removeIntent ( Intent intent ) { 34 35 if ( mServiceHandler.hasMessages ( MESSAGE_TYPE, intent ) ) { 36 37 mServiceHandler.removeMessages ( MESSAGE_TYPE, intent ) ; 38 39 } 40 41 } 42 43 44 45 protected void removeAllIntent () { 46 47 mServiceHandler.removeMessages ( MESSAGE_TYPE ) ; 48 49 } 50 51 }
这边还有另外一个需要注意的地方:在测试中发现删除不了,后来才知道是个低级错误,默认Intent的equals方法是判断两个引用是否指向一个对象,所以我们要重载Intent的 hashCode 和 equals 方法。
1 public class NetworkUtils { 2 3 public static boolean existWifi ( Context context ) { 4 5 ConnectivityManager connManager = ( ConnectivityManager ) context.getSystemService ( Context.CONNECTIVITY_SERVICE ) ; 6 7 NetworkInfo info = connManager.getActiveNetworkInfo () ; 8 9 return ( null != info && ConnectivityManager.TYPE_WIFI == info.getType () ) ; 10 11 } 12 13 }
1 public class SDUtils { 2 3 public static boolean existSDCard () { 4 5 return ( android.os.Environment.getExternalStorageStage(). 6 7 equals( android.os.Environment.MEDIA_MOUNTED ) ) ; 8 9 } 10 11 }
1 public class MainActivity extends Activity { 2 3 ... 4 5 6 7 public void startDownload () { 8 9 Intent intent = new ... 10 11 intent.putExtra ( "receiver", new DownloadReceiver() ) ; 12 13 ... 14 15 startService ( intent ) ; 16 17 } 18 19 20 21 public class DownloadReceiver extends ResultReceiver { 22 23 ... 24 25 } 26 27 28 29 }
//在IntentService中的onHandleIntent中,获得ResultReceiver
ResultReceiver receiver = intent.getParcelableExtra ( "receiver" ) ;
//在循环下载处理中,发送下载进度
1 Bundle resultData = new Bundle () ; 2 3 resultData.putString ( "progress", percent ) ; 4 5 receiver.send ( UPDATE_PROGRESS, resultData ) ;
1 public static void startAlarm ( Context context, long time ) { 2 3 AlarmManager am = (AlarmManager) context.getSystemService ( Context.ALARM_SERVICE ) ; 4 5 Intent intent = new Intent ( context, AlarmReceiver.class ) ; 6 7 PendingIntent pIntent = PendingIntent.getBroadcast ( context, 0, intent, 0 ) ; 8 9 am.cancel ( pIntent ) ; 10 11 am.setRepeating ( AlarmManager.RTC_WAKEUP, time, AlarmManager.INTERVAL_DAY, pIntent ) ; 12 13 } 14 15 16 17 public class AlarmReceiver extends BroadcastReceiver { 18 19 @Override 20 21 public void onReceive ( Context context, Intent intent ) { 22 23 //启动下载服务 24 25 。。。 26 27 } 28 29 }
我们在下载的时候可以唤醒手机,下载后可以回到休眠状态,利用PowerManager
1 public class WakeLockUtils { 2 3 public static WakeLock wl ; 4 5 public static String tag ; // 服务的包名 6 7 8 9 public static void acquirePratialWakeLock ( Context context ) { 10 11 if ( null != wl ) return ; 12 13 PowerManager pm = ( PoweerManager ) ( context.getSystemService ( Context.POWER_SERVICE ) ) ; 14 15 wl = pm.newWakeLock ( PowerManager.PARTIAL_WAKE_LOCK, tag ) ; 16 17 wl.acquire () ; 18 19 } 20 21 22 23 public static void releaseWakeLock () { 24 25 if ( null != wl && wl.isHeld () ) { 26 27 wl.release () ; 28 29 wl = null ; 30 31 } 32 33 } 34 35 } 36 37
1 public AutoRunReceiver extends BroadcastReceiver { 2 3 public void onReceive ( Context context, Intent intent ) { 4 5 //启动定时器 6 7 8 9 。。。startAlram () ; 10 11 } 12 13 }
在AndroidManifest.xml注册此接收器:
1 <receiver android:name="包名"> 2 3 <intent-filter> 4 5 <action android:name="android.intent.action.BOOT_COMPLETED"/> 6 7 <category android:name="android.intent.category.HOME"/> 8 9 </intent-filter> 10 11 </receiver>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。