Retrofit+RxJava+Mvp实现多线程视频下载
2017-11-19 20:57
411 查看
依赖的导入:
compile'io.reactivex.rxjava2:rxjava:2.1.1' compile'io.reactivex.rxjava2:rxandroid:2.0.1' //retrofit compile'com.squareup.retrofit2:retrofit:2.2.0' //Gsonconverter compile'com.squareup.retrofit2:converter-gson:2.2.0' //RxJava2Adapter compile'com.squareup.retrofit2:adapter-rxjava2:2.2.0' //okhttp compile'com.squareup.okhttp3:okhttp:3.6.0' implementation'com.android.support:recyclerview-v7:26.1.0' compile'com.youth.banner:banner:1.4.9' compile'com.github.bumptech.glide:glide:3.7.0' compile'com.facebook.fresco:fresco:0.11.0' compile(name:'ijkplayer-java-release',ext:'aar') compile'org.greenrobot:greendao:3.2.0'第一步:注解@Streaming/*大文件需要加入这个判断,防止下载过程中写入到内存中*/@GET//我们在下载文件的时候,需要传回range值来继续下载 Observable<ResponseBody>download(@Header("RANGE")Stringstart,@UrlStringurl);
第二步:封装Retrofit
publicclassBaseService{ //okhttp的简单实例,如果我们加拦截器的话,就配上用场了 privatestaticOkHttpClient.BuilderhttpClient=newOkHttpClient.Builder(); //实例retrofit privatestaticRetrofit.Builderbuilder= newRetrofit.Builder() .baseUrl("http://result.eolinker.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()); //创建一个方法,提供外部创建retrofit publicstatic<S>ScreateService(Class<S>serviceClass){ Retrofitretrofit=builder.client(httpClient.build()).build(); returnretrofit.create(serviceClass); } }
第三步:model层处理下载问题 //这个方法使我们实现model接口中的那个方法
Stringurl3=""; @Override publicvoidgetData(Stringstart,Stringurl, 4000 finalStringurl2,finalGetCallbackcallback){ this.url3=url; //调用我们自己创建的retrofit中的方法 BaseService.createService(GetInterface.class).download(start,url3) .subscribeOn(Schedulers.io()) //可以不写在主线程, .observeOn(AndroidSchedulers.mainThread()) .subscribe(newObserver<ResponseBody>(){ @Override publicvoidonSubscribe(Disposabled){ } @Override publicvoidonNext(ResponseBodyresponseBody){ //获取文件的总长度 finallongl=responseBody.contentLength(); Log.i("=====length=====","onNext:"+l); //调用文件的长度 downloadfile(l,url2); } @Override publicvoidonError(Throwablee){ } @Override publicvoidonComplete(){ } }); } //传来的参数是我们文件的总长度和我们文件下载的路径 publicvoiddownloadfile(longlength,Stringurl2){ finalFilefile=newFile(url2); if(!file.exists()){ try{ file.createNewFile(); }catch(IOExceptione){ e.printStackTrace(); } }
intthreadNum=5; longblockSize=length/threadNum; longstartPosition=0; longend=0; ////四舍五入---让一个数字+0。5在四舍五入就变成向上取整 //计算出下载块以后创建线程执行下载操作 for(inti=0;i<threadNum;i++){ //在下载之前,我们先判断一下数据库有没有值,因为断点续传我们暂停后会有数据保存到数据库 List<Bean2>cityInfoList=DBHelper.getInstance(context).getCityInfoList(i); //如果有的话,我们将数据库中的数据查询出来,然后对我们下载的开始值和结束值进行赋值 if(cityInfoList.size()>0){ Longrange=cityInfoList.get(0).getRange(); Longend1=cityInfoList.get(0).getEnd(); startPosition=range; end=end1; Log.i("=====","downloadFile:"+startPosition+"=="+end); }else{ //如果没有值的话我们要计算它的长度,然后给开始结束的位置进行赋值 startPosition=blockSize*i; //让最后一个线程下载的大小是正好的,总长度-除了最后一个块的大小和 if(i==threadNum-1){ blockSize=length-blockSize*(threadNum-1); } //然后将我们计算好的中存放到数据库 end=startPosition+blockSize-1; Bean2bean2=newBean2(); bean2.setThreadNum(i+""); bean2.setRange(startPosition); bean2.setEnd(end); //数据库方法,插入的 DBHelper.getInstance(context).addToCityInfoTable(bean2); } //开启下载的任务 downloadTask(startPosition,file,end,length,i); }}}第4步:
downloadTask方法:
publicvoiddownloadTask(finallongstartPosition,finalFilefile,longend,finallonglength,finalinti){ //计算开始位置 Stringrange="bytes="+startPosition+"-"+end; BaseService.createService(GetInterface.class).download(range,url3) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(newObserver<ResponseBody>(){ @Override publicvoidonSubscribe(Disposabled){ } @Override publicvoidonNext(ResponseBodyresponseBody){ ///文件的输入流 BufferedInputStreambis=null; //写入文件的地址 RandomAccessFileraf=null; try{ bis=newBufferedInputStream(responseBody.byteStream()); raf=newRandomAccessFile(file,"rwd"); raf.seek(startPosition); byte[]buff=newbyte[1024*8]; intlen=0; longlength2=0; List<Bean2>cityInfoList=DBHelper.getInstance(context).getCityInfoList(i); if(cityInfoList.size()>0){ length2=cityInfoList.get(0).getRange(); Log.i("=====继续length2=======","onNext:"+length2); } while((len=bis.read(buff))!=-1){ Log.i("===循环继续====","onNext:"); //正在下载的判断 if(stateDownload==DOWNLOAD_ING){ Log.i("===继续下载====","onNext:"); length2+=len; raf.write(buff,0,len); handler.sendEmptyMessage((int)length2); //当我们点击暂停的时候,我们要改变状态。当我们点击继续的时候,我们一定要记得把状态值改变回下载的状态,(本人就是犯了这么个地级错误) }elseif(stateDownload==DOWNLOAD_PAUSE){ //更新数据库 DBHelper.getInstance(context).updateInfo(i,length2); break; } } }catch(IOExceptione){ e.printStackTrace(); }finally{ if(bis!=null){ try{ bis.close(); }catch(IOExceptione){ e.printStackTrace(); } } if(raf!=null){ try{ raf.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } @Override publicvoidonError(Throwablee){ } @Override publicvoidonComplete(){ } });
第5步:接口改变状态值: //暂停
@Override publicvoidstop(){ stateDownload=DOWNLOAD_PAUSE; } //继续 @Override publicvoidjixu(){ stateDownload=DOWNLOAD_ING; } @Override publicvoidgetProgress(){ }//集成GreenDao
publicclassDBHelper{ privatestaticContextmContext; privatestaticDBHelperinstance; Bean2Daobean2Dao; Bean2bean; //使用单例模式 privateDBHelper(){ } publicstaticDBHelpergetInstance(Contextcontext){ if(instance==null){ instance=newDBHelper(); if(mContext==null){ mContext=context; } //数据库对象 //数据库对象 DaoMaster.DevOpenHelperdevOpenHelper=newDaoMaster.DevOpenHelper(mContext,"student.db",null); DaoMasterdaoMaster=newDaoMaster(devOpenHelper.getWritableDb()); DaoSessiondaoSession=daoMaster.newSession(); instance.bean2Dao=daoSession.getBean2Dao(); } returninstance; } /**添加数据*/ publicvoidaddToCityInfoTable(Bean2item) { bean2Dao.insert(item); } /**查询*/ /**通过我们的线程数量号进行查询*/ publicList<Bean2>getCityInfoList(intthreadNum){ QueryBuilder<Bean2>qb=bean2Dao.queryBuilder(); qb.where(Bean2Dao.Properties.ThreadNum.eq(threadNum)); List<Bean2>list=qb.list(); Log.i("========","getCityInfoList:"+list); returnlist; } //更新数据库的方法 publicvoidupdateInfo(intid,longrang){ QueryBuilder<Bean2>qb=bean2Dao.queryBuilder(); qb.where(Bean2Dao.Properties.ThreadNum.eq(id)); List<Bean2>list=qb.list(); Bean2bean2=list.get(0); bean2.setRange(rang); bean2Dao.update(bean2); } }//bean类
@Entity publicclassBean2{ @Id privateLongid; @Property(nameInDb="RANGE") privateLongrange; @Property(nameInDb="END") privateLongend; @Property(nameInDb="ThREADNUM") privateStringThreadNum;第5步:视频播放:
compile(name:'ijkplayer-java-release',ext:'aar')
android{compileSdkVersion26defaultConfig{applicationId"com.bwie.mcowu.lx_zhouthree"minSdkVersion19targetSdkVersion26versionCode1versionName"1.0"testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"}buildTypes{release{minifyEnabledfalseproguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'}}sourceSets{main{jniLibs.srcDirs=['libs']}}}repositories{mavenCentral()flatDir{dirs'libs'//thiswaywecanfindthe.aarfileinlibsfolder}}第五步:
/***日志工具类在发布时不显示日志*@authorRANDY_ZHANG*/publicclassDebugLog{staticStringclassName;staticStringmethodName;staticintlineNumber;privateDebugLog(){/*Protectfrominstantiations*/}publicstaticbooleanisDebuggable(){returnBuildConfig.DEBUG;}privatestaticStringcreateLog(Stringlog){StringBufferbuffer=newStringBuffer();buffer.append("[");buffer.append(methodName);buffer.append(":");buffer.append(lineNumber);buffer.append("]");buffer.append(log);returnbuffer.toString();}privatestaticvoidgetMethodNames(StackTraceElement[]sElements){className=sElements[1].getFileName();methodName=sElements[1].getMethodName();lineNumber=sElements[1].getLineNumber();}publicstaticvoide(Stringmessage){if(!isDebuggable())return;//ThrowableinstancemustbecreatedbeforeanymethodsgetMethodNames(newThrowable().getStackTrace());Log.e(className,createLog(message));}publicstaticvoidi(Stringmessage){if(!isDebuggable())return;getMethodNames(newThrowable().getStackTrace());Log.i(className,createLog(message));}publicstaticvoidd(Stringmessage){if(!isDebuggable())return;getMethodNames(newThrowable().getStackTrace());Log.d(className,createLog(message));}publicstaticvoidv(Stringmessage){if(!isDebuggable())return;getMethodNames(newThrowable().getStackTrace());Log.v(className,createLog(message));}publicstaticvoidw(Stringmessage){if(!isDebuggable())return;getMethodNames(newThrowable().getStackTrace());Log.w(className,createLog(message));}publicstaticvoidwtf(Stringmessage){if(!isDebuggable())return;getMethodNames(newThrowable().getStackTrace());Log.wtf(className,createLog(message));}}第六步:playManager
publicclassPlayerManager{/***可能会剪裁,保持原视频的大小,显示在中心,当原视频的大小超过view的大小超过部分裁剪处理*/publicstaticfinalStringSCALETYPE_FITPARENT="fitParent";/***可能会剪裁,等比例放大视频,直到填满View为止,超过View的部分作裁剪处理*/publicstaticfinalStringSCALETYPE_FILLPARENT="fillParent";/***将视频的内容完整居中显示,如果视频大于view,则按比例缩视频直到完全显示在view中*/publicstaticfinalStringSCALETYPE_WRAPCONTENT="wrapContent";/***不剪裁,非等比例拉伸画面填满整个View*/publicstaticfinalStringSCALETYPE_FITXY="fitXY";/***不剪裁,非等比例拉伸画面到16:9,并完全显示在View中*/publicstaticfinalStringSCALETYPE_16_9="16:9";/***不剪裁,非等比例拉伸画面到4:3,并完全显示在View中*/publicstaticfinalStringSCALETYPE_4_3="4:3";/***状态常量*/privatefinalintSTATUS_ERROR=-1;privatefinalintSTATUS_IDLE=0;privatefinalintSTATUS_LOADING=1;privatefinalintSTATUS_PLAYING=2;privatefinalintSTATUS_PAUSE=3;privatefinalintSTATUS_COMPLETED=4;privatefinalActivityactivity;privatefinalIjkVideoViewvideoView;privatefinalAudioManageraudioManager;publicGestureDetectorgestureDetector;privatebooleanplayerSupport;privatebooleanisLive=false;//是否为直播privatebooleanfullScreenOnly;privatebooleanportrait;privatefinalintmMaxVolume;privateintscreenWidthPixels;privateintcurrentPosition;privateintstatus=STATUS_IDLE;privatelongpauseTime;privateStringurl;privatefloatbrightness=-1;privateintvolume=-1;privatelongnewPosition=-1;privatelongdefaultRetryTime=5000;privateOrientationEventListenerorientationEventListener;privatePlayerStateListenerplayerStateListener;publicvoidsetPlayerStateListener(PlayerStateListenerplayerStateListener){this.playerStateListener=playerStateListener;}privateOnErrorListeneronErrorListener=newOnErrorListener(){@OverridepublicvoidonError(intwhat,intextra){}};privateOnCompleteListeneronCompleteListener=newOnCompleteListener(){@OverridepublicvoidonComplete(){}};privateOnInfoListeneronInfoListener=newOnInfoListener(){@OverridepublicvoidonInfo(intwhat,intextra){}};privateOnControlPanelVisibilityChangeListeneronControlPanelVisibilityChangeListener=newOnControlPanelVisibilityChangeListener(){@Overridepublicvoidchange(booleanisShowing){}};/***trytoplaywhenerror(onlyforlivevideo)*@paramdefaultRetryTimemillisecond,0willstopretry,defaultis5000millisecond*/publicvoidsetDefaultRetryTime(longdefaultRetryTime){this.defaultRetryTime=defaultRetryTime;}publicPlayerManager(finalActivityactivity){try{IjkMediaPlayer.loadLibrariesOnce(null);IjkMediaPlayer.native_profileBegin("libijkplayer.so");playerSupport=true;}catch(Throwablee){Log.e("GiraffePlayer","loadLibrarieserror",e);}this.activity=activity;screenWidthPixels=activity.getResources().getDisplayMetrics().widthPixels;videoView=(IjkVideoView)activity.findViewById(R.id.video_view);videoView.setOnCompletionListener(newIMediaPlayer.OnCompletionListener(){@OverridepublicvoidonCompletion(IMediaPlayermp){statusChange(STATUS_COMPLETED);onCompleteListener.onComplete();}});videoView.setOnErrorListener(newIMediaPlayer.OnErrorListener(){@OverridepublicbooleanonError(IMediaPlayermp,intwhat,intextra){statusChange(STATUS_ERROR);onErrorListener.onError(what,extra);returntrue;}});videoView.setOnInfoListener(newIMediaPlayer.OnInfoListener(){@OverridepublicbooleanonInfo(IMediaPlayermp,intwhat,intextra){switch(what){caseIMediaPlayer.MEDIA_INFO_BUFFERING_START:statusChange(STATUS_LOADING);break;caseIMediaPlayer.MEDIA_INFO_BUFFERING_END:statusChange(STATUS_PLAYING);break;caseIMediaPlayer.MEDIA_INFO_NETWORK_BANDWIDTH://显示下载速度//Toast.show("downloadrate:"+extra);break;caseIMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:statusChange(STATUS_PLAYING);break;default:break;}onInfoListener.onInfo(what,extra);returnfalse;}});audioManager=(AudioManager)activity.getSystemService(Context.AUDIO_SERVICE);mMaxVolume=audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);gestureDetector=newGestureDetector(activity,newPlayerGestureListener());if(fullScreenOnly){activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}portrait=getScreenOrientation()==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;if(!playerSupport){DebugLog.e("","播放器不支持此设备");}}privatevoidstatusChange(intnewStatus){status=newStatus;if(!isLive&&newStatus==STATUS_COMPLETED){DebugLog.d("","statusChangeSTATUS_COMPLETED...");if(playerStateListener!=null){playerStateListener.onComplete();}}elseif(newStatus==STATUS_ERROR){DebugLog.d("","statusChangeSTATUS_ERROR...");if(playerStateListener!=null){playerStateListener.onError();}}elseif(newStatus==STATUS_LOADING){//$.id(R.id.app_video_loading).visible();if(playerStateListener!=null){playerStateListener.onLoading();}DebugLog.d("","statusChangeSTATUS_LOADING...");}elseif(newStatus==STATUS_PLAYING){DebugLog.d("","statusChangeSTATUS_PLAYING...");if(playerStateListener!=null){playerStateListener.onPlay();}}}publicvoidonPause(){pauseTime=System.currentTimeMillis();if(status==STATUS_PLAYING){videoView.pause();if(!isLive){currentPosition=videoView.getCurrentPosition();}}}publicvoidonResume(){pauseTime=0;if(status==STATUS_PLAYING){if(isLive){videoView.seekTo(0);}else{if(currentPosition>0){videoView.seekTo(currentPosition);}}videoView.start();}}publicvoidonDestroy(){orientationEventListener.disable();videoView.stopPlayback();}publicvoidplay(Stringurl){this.url=url;if(playerSupport){videoView.setVideoPath(url);videoView.start();}}privateStringgenerateTime(longtime){inttotalSeconds=(int)(time/1000);intseconds=totalSeconds%60;intminutes=(totalSeconds/60)%60;inthours=totalSeconds/3600;returnhours>0?String.format("%02d:%02d:%02d",hours,minutes,seconds):String.format("%02d:%02d",minutes,seconds);}privateintgetScreenOrientation(){introtation=activity.getWindowManager().getDefaultDisplay().getRotation();DisplayMetricsdm=newDisplayMetrics();activity.getWindowManager().getDefaultDisplay().getMetrics(dm);intwidth=dm.widthPixels;intheight=dm.heightPixels;intorientation;//ifthedevice'snaturalorientationisportrait:if((rotation==Surface.ROTATION_0||rotation==Surface.ROTATION_180)&&height>width||(rotation==Surface.ROTATION_90||rotation==Surface.ROTATION_270)&&width>height){switch(rotation){caseSurface.ROTATION_0:orientation=ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;break;caseSurface.ROTATION_90:orientation=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;break;caseSurface.ROTATION_180:orientation=ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;break;caseSurface.ROTATION_270:orientation=ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;break;default:orientation=ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;break;}}//ifthedevice'snaturalorientationislandscapeorifthedevice//issquare:else{switch(rotation){caseSurface.ROTATION_0:orientation=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;break;caseSurface.ROTATION_90:orientation=ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;break;caseSurface.ROTATION_180:orientation=ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;break;caseSurface.ROTATION_270:orientation=ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;break;default:orientation=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;break;}}returnorientation;}/***滑动改变声音大小**@parampercent*/privatevoidonVolumeSlide(floatpercent){if(volume==-1){volume=audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);if(volume<0)volume=0;}intindex=(int)(percent*mMaxVolume)+volume;if(index>mMaxVolume){index=mMaxVolume;}elseif(index<0){index=0;}//变更声音audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,index,0);//变更进度条inti=(int)(index*1.0/mMaxVolume*100);Strings=i+"%";if(i==0){s="off";}DebugLog.d("","onVolumeSlide:"+s);}privatevoidonProgressSlide(floatpercent){longposition=videoView.getCurrentPosition();longduration=videoView.getDuration();longdeltaMax=Math.min(100*1000,duration-position);longdelta=(long)(deltaMax*percent);newPosition=delta+position;if(newPosition>duration){newPosition=duration;}elseif(newPosition<=0){newPosition=0;delta=-position;}intshowDelta=(int)delta/1000;if(showDelta!=0){Stringtext=showDelta>0?("+"+showDelta):""+showDelta;DebugLog.d("","onProgressSlide:"+text);}}/***滑动改变亮度**@parampercent*/privatevoidonBrightnessSlide(floatpercent){if(brightness<0){brightness=activity.getWindow().getAttributes().screenBrightness;if(brightness<=0.00f){brightness=0.50f;}elseif(brightness<0.01f){brightness=0.01f;}}DebugLog.d("","brightness:"+brightness+",percent:"+percent);WindowManager.LayoutParamslpa=activity.getWindow().getAttributes();lpa.screenBrightness=brightness+percent;if(lpa.screenBrightness>1.0f){lpa.screenBrightness=1.0f;}elseif(lpa.screenBrightness<0.01f){lpa.screenBrightness=0.01f;}activity.getWindow().setAttributes(lpa);}publicvoidsetFullScreenOnly(booleanfullScreenOnly){this.fullScreenOnly=fullScreenOnly;tryFullScreen(fullScreenOnly);if(fullScreenOnly){activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}else{activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);}}privatevoidtryFullScreen(booleanfullScreen){if(activityinstanceofAppCompatActivity){ActionBarsupportActionBar=((AppCompatActivity)activity).getSupportActionBar();if(supportActionBar!=null){if(fullScreen){supportActionBar.hide();}else{supportActionBar.show();}}}setFullScreen(fullScreen);}privatevoidsetFullScreen(booleanfullScreen){if(activity!=null){WindowManager.LayoutParamsattrs=activity.getWindow().getAttributes();if(fullScreen){attrs.flags|=WindowManager.LayoutParams.FLAG_FULLSCREEN;activity.getWindow().setAttributes(attrs);activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);}else{attrs.flags&=(~WindowManager.LayoutParams.FLAG_FULLSCREEN);activity.getWindow().setAttributes(attrs);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);}}}/***<pre>*fitParent:可能会剪裁,保持原视频的大小,显示在中心,当原视频的大小超过view的大小超过部分裁剪处理*fillParent:可能会剪裁,等比例放大视频,直到填满View为止,超过View的部分作裁剪处理*wrapContent:将视频的内容完整居中显示,如果视频大于view,则按比例缩视频直到完全显示在view中*fitXY:不剪裁,非等比例拉伸画面填满整个View*16:9:不剪裁,非等比例拉伸画面到16:9,并完全显示在View中*4:3:不剪裁,非等比例拉伸画面到4:3,并完全显示在View中*</pre>*@paramscaleType*/publicvoidsetScaleType(StringscaleType){if(SCALETYPE_FITPARENT.equals(scaleType)){videoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT);}elseif(SCALETYPE_FILLPARENT.equals(scaleType)){videoView.setAspectRatio(IRenderView.AR_ASPECT_FILL_PARENT);}elseif(SCALETYPE_WRAPCONTENT.equals(scaleType)){videoView.setAspectRatio(IRenderView.AR_ASPECT_WRAP_CONTENT);}elseif(SCALETYPE_FITXY.equals(scaleType)){videoView.setAspectRatio(IRenderView.AR_MATCH_PARENT);}elseif(SCALETYPE_16_9.equals(scaleType)){videoView.setAspectRatio(IRenderView.AR_16_9_FIT_PARENT);}elseif(SCALETYPE_4_3.equals(scaleType)){videoView.setAspectRatio(IRenderView.AR_4_3_FIT_PARENT);}}publicvoidstart(){videoView.start();}publicvoidpause(){videoView.pause();}publicbooleanonBackPressed(){if(!fullScreenOnly&&getScreenOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);returntrue;}returnfalse;}classQuery{privatefinalActivityactivity;privateViewview;publicQuery(Activityactivity){this.activity=activity;}publicQueryid(intid){view=activity.findViewById(id);returnthis;}publicQueryimage(intresId){if(viewinstanceofImageView){((ImageView)view).setImageResource(resId);}returnthis;}publicQueryvisible(){if(view!=null){view.setVisibility(View.VISIBLE);}returnthis;}publicQuerygone(){if(view!=null){view.setVisibility(View.GONE);}returnthis;}publicQueryinvisible(){if(view!=null){view.setVisibility(View.INVISIBLE);}returnthis;}publicQueryclicked(View.OnClickListenerhandler){if(view!=null){view.setOnClickListener(handler);}returnthis;}publicQuerytext(CharSequencetext){if(view!=null&&viewinstanceofTextView){((TextView)view).setText(text);}returnthis;}publicQueryvisibility(intvisible){if(view!=null){view.setVisibility(visible);}returnthis;}privatevoidsize(booleanwidth,intn,booleandip){if(view!=null){ViewGroup.LayoutParamslp=view.getLayoutParams();if(n>0&&dip){n=dip2pixel(activity,n);}if(width){lp.width=n;}else{lp.height=n;}view.setLayoutParams(lp);}}publicvoidheight(intheight,booleandip){size(false,height,dip);}publicintdip2pixel(Contextcontext,floatn){intvalue=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,n,context.getResources().getDisplayMetrics());returnvalue;}publicfloatpixel2dip(Contextcontext,floatn){Resourcesresources=context.getResources();DisplayMetricsmetrics=resources.getDisplayMetrics();floatdp=n/(metrics.densityDpi/160f);returndp;}}publicclassPlayerGestureListenerextendsGestureDetector.SimpleOnGestureListener{privatebooleanfirstTouch;privatebooleanvolumeControl;privatebooleantoSeek;/***双击*/@OverridepublicbooleanonDoubleTap(MotionEvente){videoView.toggleAspectRatio();returntrue;}@OverridepublicbooleanonDown(MotionEvente){firstTouch=true;returnsuper.onDown(e);}/***滑动*/@OverridepublicbooleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX,floatdistanceY){floatmOldX=e1.getX(),mOldY=e1.getY();floatdeltaY=mOldY-e2.getY();floatdeltaX=mOldX-e2.getX();if(firstTouch){toSeek=Math.abs(distanceX)>=Math.abs(distanceY);volumeControl=mOldX>screenWidthPixels*0.5f;firstTouch=false;}if(toSeek){if(!isLive){onProgressSlide(-deltaX/videoView.getWidth());}}else{floatpercent=deltaY/videoView.getHeight();if(volumeControl){onVolumeSlide(percent);}else{onBrightnessSlide(percent);}}returnsuper.onScroll(e1,e2,distanceX,distanceY);}@OverridepublicbooleanonSingleTapUp(MotionEvente){returntrue;}}/***isplayersupportthisdevice*@return*/publicbooleanisPlayerSupport(){returnplayerSupport;}/***是否正在播放*@return*/publicbooleanisPlaying(){returnvideoView!=null?videoView.isPlaying():false;}publicvoidstop(){videoView.stopPlayback();}publicintgetCurrentPosition(){returnvideoView.getCurrentPosition();}/***getvideoduration*@return*/publicintgetDuration(){returnvideoView.getDuration();}publicPlayerManagerplayInFullScreen(booleanfullScreen){if(fullScreen){activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}returnthis;}publicPlayerManageronError(OnErrorListeneronErrorListener){this.onErrorListener=onErrorListener;returnthis;}publicPlayerManageronComplete(OnCompleteListeneronCompleteListener){this.onCompleteListener=onCompleteListener;returnthis;}publicPlayerManageronInfo(OnInfoListeneronInfoListener){this.onInfoListener=onInfoListener;returnthis;}publicPlayerManageronControlPanelVisibilityChange(OnControlPanelVisibilityChangeListenerlistener){this.onControlPanelVisibilityChangeListener=listener;returnthis;}/***setislive(can'tseekforward)*@paramisLive*@return*/publicPlayerManagerlive(booleanisLive){this.isLive=isLive;returnthis;}publicPlayerManagertoggleAspectRatio(){if(videoView!=null){videoView.toggleAspectRatio();}returnthis;}publicinterfacePlayerStateListener{voidonComplete();voidonError();voidonLoading();voidonPlay();}publicinterfaceOnErrorListener{voidonError(intwhat,intextra);}publicinterfaceOnCompleteListener{voidonComplete();}publicinterfaceOnControlPanelVisibilityChangeListener{voidchange(booleanisShowing);}publicinterfaceOnInfoListener{voidonInfo(intwhat,intextra);}}第七步:初始化
privatevoidinitPlayer(){player=newPlayerManager(this);player.setFullScreenOnly(true);player.setScaleType(PlayerManager.SCALETYPE_FILLPARENT);player.playInFullScreen(true);player.setPlayerStateListener(this);player.play(url);}@OverridepublicbooleanonTouchEvent(MotionEventevent){if(player.gestureDetector.onTouchEvent(event))returntrue;returnsuper.onTouchEvent(event);}@OverridepublicvoidonComplete(){Log.i("+++++","onComplete:");}@OverridepublicvoidonError(){Log.i("+++++","onError:");}@OverridepublicvoidonLoading(){Log.i("+++++","onLoading:");}@OverridepublicvoidonPlay(){Log.i("+++++","onPlay:");}@OverridepublicvoidonClick(Viewv){switch(v.getId()){caseR.id.btn:Stringurl2=getCacheDir()+"haha.mp4";presenter.down(String.valueOf(0),url,url2);break;default:break;}}@OverridepublicvoidgetData(ResponseBodyresponseBody){}
相关文章推荐
- Retrofit+RXJava_多线程下载视频列表
- RxJava+Retrofit+Mvp实现购物车(没有结算页面)
- RxJava2+MVP+Retrofit框架简单实现RecyclerView
- Retrofit+Rxjava下载文件进度的实现
- 使用rxjava,retrofit,okhttp实现mvp模式的数据解析
- RxJava+Retrofit+OkHttp实现多文件下载之断点续传
- Retrofit+rxjava+mvp实现登录
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- 基于Retrofit+Rxjava实现带进度显示的下载文件
- RxJava+Retrofit+Mvp实现购物车
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
- Retrofit Rxjava实现图片下载、保存并展示实例
- 使用MVP+Retrofit+RxJava实现的的Android Demo (上)使用Nuclues库实现MVP
- Android 框架设计Demo,一个简单的MVP示例搜索功能,网络请求用Retrofit+RxJava实现
- RxJava+Retrofit实现文件下载
- 使用MVP+Retrofit+RxJava实现的的Android Demo (下)使用Retrofit+RxJava处理网络请求
- Retrofit+Rxjava实现文件上传和下载功能
- MVP+Retrofit+RxJava请求网络数据实现RecyclerView多条目展示
- 终极封装 Rxjava+Retrofit+okhttp+mvp实现
- Android Retrofit+Rxjava+MVP+EventBus+ButterKnife实现接口登录(无正则表达式)