================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.cjj.bb"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
multiDexEnabled true
// dex突破65535的限制
multiDexEnabled true
// 默认是xinhao的渠道
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "bili"]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
xinhao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "cjj"]
}
weixin {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "bili"]
}
// baidu {
// manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
// }
// wandoujia {
// manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
// }
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile project(':vitamio')
compile files('libs/universal-image-loader-1.9.3.jar')
compile files('libs/jsoup-1.8.1.jar')
compile project(':DanmakuFlameMaster')
// compile project(':VPIndexLibrary')
compile 'com.android.support:support-v4:22.1.1'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\as\sdk-install/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: app/src/androidTest/java/com/cjj/bb/ApplicationTest.java
================================================
package com.cjj.bb;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* Testing Fundamentals
*/
public class ApplicationTest extends ApplicationTestCase {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
================================================
FILE: app/src/main/assets/comment.json
================================================
[{"c":"0,16777215,1,25,196050,1364468342","m":"。。。。。。。。。。。。。。。。。。。。。。"},{"c":"3.619,16777215,1,25,196050,1364468347","m":"。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。"},{"c":"7.539,16777215,1,25,196050,1364468351","m":"。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。"},{"c":"11.291,16777215,1,25,196050,1364468355","m":"。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。"},{"c":"13.476,16777215,1,25,196050,1364468357","m":"。。。。。。。。"},{"c":"1.724,16777215,1,25,196050,1364468442","m":"3.28 打卡"},{"c":"31.229,16777215,1,25,478568,1364994609","m":"0 0"},{"c":"54.791,16777215,1,25,418656,1365183861","m":"...."},{"c":"65.617,10027008,1,25,2ack2073121228,1365184819","m":"一天不看香蕉君,不舒服斯基丶"},{"c":"11.188,16776960,1,25,478568,1365823290","m":"。。。。"},{"c":"61.625,16776960,1,25,478568,1365823340","m":"卧槽"},{"c":"87.933,16777215,1,25,461326,1366819637","m":"小湿机你在看咩"},{"c":"87.933,16777215,1,25,461326,1366819652","m":"小湿机"},{"c":"0,16776960,1,25,1bak1902192501,1368157455","m":".."},{"c":"10.711,16776960,1,25,1bak1902192501,1368157482","m":"............................"},{"c":"39.512,16777215,1,25,27dk1948164898,1368848882","m":"科比"},{"c":"35.673,16777215,1,25,22ck1867180364,1369403593","m":"播放次数:396042"},{"c":"61.976,16777215,1,25,24ek2015510060,1370615680","m":"在线2 "},{"c":"6.519,16777215,1,25,17dk3730002906,1370623489","m":"卧槽...点错了"},{"c":"27.787,16777215,1,25,36ek248534870,1370698155","m":"金♂刚♂如♂来"},{"c":"87.589,16777215,1,25,350k2104532353,1370921441","m":" 萎了、、、、、、、、、、、、"},{"c":"23.343,16777215,1,25,1f0k242492437,1371043001","m":"fuck"},{"c":"79.84,16777215,1,25,1f0k242492437,1371043057","m":"顶上去报复社会"},{"c":"49.79,16777215,1,25,231580,1371209285","m":"美国"},{"c":"47.652,65280,1,25,498k2063980741,1371983881","m":" 暖被窝一次一千円节假日半价 / 发布于 2011年 4月28日(星期四) 7时24分 / 播放:397078 评论:2456 收藏:1504 "},{"c":"25.769,16777215,1,25,38ek1896980399,1373078365","m":"炒饭无误"},{"c":"15.499,16777215,1,25,104k3072012724,1373078412","m":"顶上去!!!!!报复社会!!!!!!!!!!"},{"c":"87.927,16777215,1,25,535868,1373078428","m":"打卡"},{"c":"54.177,16777215,1,25,104k3072012724,1373078485","m":"收藏的什么性取向?"},{"c":"55.095,16777215,1,25,2d9k2101697339,1373082287","m":"我瞎了。。。"},{"c":"8.009,16777215,1,25,1fbk1946851889,1373082945","m":"报复社会"},{"c":"64.865,16777215,1,25,2e5k1018989651,1373083835","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.102,16777215,1,25,2e5k1018989651,1373083865","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"72.016,16777215,1,25,563619,1373086101","m":"顶上去报复社会"},{"c":"4.466,16777215,1,25,563619,1373086131","m":"1584个收藏是闹那样"},{"c":"65.066,16777215,1,25,4c7k2002975241,1373086719","m":"改版后老多老坟"},{"c":"33.342,16777215,1,25,1ffk2090928940,1373087526","m":"2013年7月6日 13:12:22"},{"c":"22.229,16777215,1,25,247k1855594942,1373088592","m":"2013.7.6"},{"c":"11.035,16777215,1,25,117k3702574478,1373089139","m":"yoooooooooooooooooooooooooooooo"},{"c":"23.519,16777215,1,25,115k3078797035,1373092760","m":"2013年7月6日14:39:18"},{"c":"17.136,16777215,1,25,484k1017188638,1373093593","m":"......................................................"},{"c":"82.21,16777215,1,25,4c3k244535907,1373094036","m":"石更了"},{"c":"3.156,65280,1,25,551590,1373094641","m":"。。。。。。。。。。。。"},{"c":"18.774,65280,1,25,551590,1373094657","m":"我次奥"},{"c":"5.036,16777215,1,25,329k987402398,1373095195","m":"草"},{"c":"17.707,16777215,1,25,33ck249485211,1373103359","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.1,16777215,1,37,33ck249485211,1373103502","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.246,3407616,1,25,48ek3702141711,1373106289","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"22.92,3407616,1,25,48ek3702141711,1373106384","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"21.267,16711833,1,25,1f8k3671002319,1373107024","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"35.259,16777215,1,25,482k3721736082,1373107177","m":"打卡"},{"c":"16.772,16777215,1,25,123k2075644583,1373108045","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"81.461,16777215,1,25,308543,1373109391","m":"我居然无耻的看完了"},{"c":"16.612,16777215,1,25,36ek1035411925,1373109676","m":"炒饭小号 无误"},{"c":"6.797,16777215,1,25,501507,1373110201","m":"每日打卡"},{"c":"20.621,16777215,1,25,192k2103294627,1373110747","m":"............"},{"c":"84.827,16777215,1,25,28ak467794641,1373111880","m":"双手打字以示清白"},{"c":"7.152,16737792,1,25,262k455357332,1373112100","m":"啊"},{"c":"14.061,16777215,1,25,562163,1373115212","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"2.747,65280,1,25,30bk3722666395,1373115887","m":"打卡啦"},{"c":"32.453,16777215,1,25,1adk3736329486,1373116156","m":"求BGM!!!!!!!!!!!!!!!!!!!!!!!!!!"},{"c":"55.498,16777215,1,25,1aak3072357289,1373118377","m":" 还能动。。。。"},{"c":"61.828,16777215,1,25,1aak3072357289,1373118380","m":"FUCK"},{"c":"20.848,16777215,1,25,3eek1962717247,1373121959","m":"我来打卡了......."},{"c":"40.693,3381759,1,25,1edk1962794156,1373123160","m":"1111111111111111111111111111111111111111"},{"c":"52.029,3381759,1,25,1edk1962794156,1373123171","m":"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"},{"c":"4.408,16777215,1,25,2f9k454125677,1373124185","m":"哦草!"},{"c":"50.444,65280,1,25,553421,1373125176","m":"收藏1618什么心态..."},{"c":"38.361,16777215,1,25,4a4k29683238,1373126181","m":"你麻痹?"},{"c":"19.81,16777215,1,25,3d2k1967534807,1373132178","m":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},{"c":"17.87,16777215,1,25,451k465242735,1373135469","m":"哎呦卧槽,顶上去报复世界"},{"c":"12.465,16777215,1,25,1abk2016062444,1373146913","m":"2013年7月7日5:40:08"},{"c":"22.633,16777215,1,25,420552,1373155854","m":"必须顶上去报复社会"},{"c":"0,16777215,1,25,548565,1373158670","m":"打卡"},{"c":"21.253,16777215,1,25,548565,1373158760","m":""},{"c":"12.916,16777215,1,25,406k2091038619,1373159899","m":"打卡2013年7月7日9:17:11"},{"c":"16.102,16777215,1,25,174857,1373163531","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"28.248,16777215,1,25,418656,1373164750","m":"打卡"},{"c":"28.434,16777215,1,25,258613,1373166524","m":"香蕉君无敌了"},{"c":"16.911,16777215,1,25,444k1861315545,1373166705","m":"香蕉君!"},{"c":"77.817,16777215,1,25,186k1885029973,1373166760","m":"双手打字以示清白"},{"c":"32.187,16777215,1,25,184k2102925457,1373168322","m":"bibli"},{"c":"12.112,16777215,1,25,489191,1373168409","m":"2013年7月7日11:40:17"},{"c":"16.479,16776960,1,25,334k3740305770,1373168589","m":"烧死这些同性恋"},{"c":"15.867,16711680,1,25,357k3730546841,1373170277","m":"简直丧心病狂"},{"c":"10.316,16777215,1,25,3cdk1035642435,1373171091","m":"501"},{"c":"19.164,16711782,1,25,3ffk717661093,1373171300","m":"。。。。。。。。。。。。。。。。。。。。。。。。。。"},{"c":"17.066,16711782,1,25,3ffk717661093,1373171306","m":"!!!"},{"c":"4.323,16777215,1,25,269k3738528475,1373172137","m":"2013 7.7"},{"c":"42.129,10027008,4,37,31dk3033839023,1373174002","m":"科比!"},{"c":"12.815,16777215,1,25,26ck3074307386,1373175261","m":" 打卡"},{"c":"46.931,16777215,1,25,187k3682680642,1373176996","m":"..........."},{"c":"78.136,16777215,1,25,13ak1874150387,1373180305","m":"报复社会。。"},{"c":"9.993,16711680,1,25,16dk3071440325,1373181548","m":"我是小伙伴! 我是小伙伴!"},{"c":"44.141,16711680,4,37,16dk3071440325,1373181608","m":"我是小伙伴!"},{"c":"15.061,16777215,1,25,150k1987611877,1373181620","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"64.491,16711680,4,37,16dk3071440325,1373181628","m":"我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙伴!我是小伙"},{"c":"15.237,16777215,1,25,415083,1373182130","m":"日常打卡,"},{"c":"23.934,16777215,1,25,420552,1373186603","m":"报复社会节奏开启"},{"c":"8.832,16777215,1,25,366k2936106977,1373186676","m":"2013年7月7日16:43:41"},{"c":"52.229,16777215,1,25,217k3722465722,1373187469","m":"主页 \u003e 生活娱乐 / 暖被窝一次一千円节假日半价 / 发布于 2011年 4月28日(星期四) 7时24分 / 播放:404511 评论:2486 收藏:1638 / 举"},{"c":"9.524,16777215,1,25,446k987429084,1373190152","m":"- - - - - - "},{"c":"37.971,16777215,1,25,446k987429084,1373190180","m":" 这打吗的好屌"},{"c":"14.824,16777215,1,25,36ak1874994172,1373192037","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"58.871,16777215,1,25,2bak2006106235,1373192955","m":"无法直视Ort"},{"c":"48.069,16777215,1,25,376k242592647,1373197574","m":"主页 \u003e 生活娱乐 / 暖被窝一次一千円节假日半价 / 发布于 2011年 4月28日(星期四) 7时24分 / 播放:404903 评论:2502 收藏:1646 / 举"},{"c":"41.6,3407616,1,25,385k3726527761,1373198456","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"43.539,16777215,1,25,317k3740600479,1373201930","m":"吊..................................................................................................."},{"c":"0,16777215,1,25,2dfk3683682083,1373202156","m":"呵呵呵呵呵"},{"c":"40.008,16777215,1,25,247k1946749991,1373205163","m":"叼暴了"},{"c":"86.723,16777215,1,37,247k1946749991,1373205210","m":"撸起来,骚年"},{"c":"16.624,16777215,1,25,395k3740450750,1373205479","m":"18个香蕉不说话"},{"c":"11.544,16777215,1,25,2c7k1965573824,1373205504","m":"2013年7月7日 21:57:24 打卡"},{"c":"29.134,13369344,1,25,27fk3062632765,1373206329","m":"啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊"},{"c":"34.049,16777215,1,25,1a2k1968491684,1373207523","m":"卧槽"},{"c":"84.827,16777215,1,25,420552,1373208023","m":"顶上去报复社会"},{"c":"14.981,16777215,1,25,361k1912296216,1373209053","m":"顶上去啊!!!!!!!!!!!!!!!!!!"},{"c":"51.766,16777215,1,25,361k1912296216,1373209106","m":"1657个收藏 我干"},{"c":"14.226,3407616,1,25,304k3722405032,1373209311","m":"。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。"},{"c":"40.375,16777215,1,25,152k3661681594,1373211071","m":"啊婆主 已经在上心病狂"},{"c":"8.751,16777215,1,25,4a8k3029030104,1373212120","m":"打卡"},{"c":"63.029,16777215,1,25,3dck454568877,1373214809","m":"yooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"},{"c":"82.312,16777215,1,25,545714,1373215092","m":"2013年7月8日0:38:20"},{"c":"21.909,16777215,1,25,237975,1373224589","m":"谁挖坟的"},{"c":"22.424,16777215,1,25,451k465242735,1373240898","m":"每日报复社会节奏"},{"c":"14.501,16777215,1,25,3ack1901744269,1373242869","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"10.479,65280,1,25,150k1870239625,1373244297","m":"科比加强版"},{"c":"20.483,16777215,1,25,466k986806395,1373249876","m":"耶"},{"c":"14.877,16777215,1,25,144k1896832537,1373250214","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"12.279,16777215,1,25,2c4k2095314541,1373250965","m":"我来打卡了"},{"c":"62.535,16777215,1,25,261770,1373251247","m":"...."},{"c":"82.023,16777215,1,25,451k465242735,1373253347","m":"赢了怎么破"},{"c":"12.744,52479,1,25,451k465242735,1373342293","m":"顶上去报复社会"},{"c":"17.345,16777215,1,25,423547,1373815673","m":"报复社会,走你"},{"c":"42.26,16777215,1,25,244k2004555617,1373984022","m":"x笑尿。。"},{"c":"39.958,65280,1,25,360346,1374154683","m":"好吧我手滑一下"},{"c":"54.943,65280,1,25,360346,1374154698","m":"无法直视"},{"c":"13.424,16777215,1,25,325344,1374311786","m":"打卡。。 2013年7月20日 17:15:56"},{"c":"0,16724838,1,25,3c5k242233919,1374320952","m":"吾欲报复社会"},{"c":"15.278,16777215,1,25,585664,1376018232","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"18.567,16777215,1,25,585664,1376018236","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"37.071,13434624,1,25,104k2003100892,1376019458","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"19.153,13369344,1,25,458834,1376019767","m":"我擦破"},{"c":"17.607,13369344,1,25,458834,1376019864","m":"耶耶耶耶耶耶耶耶耶爷爷夜"},{"c":"0,6750003,1,25,612871,1376020469","m":"...."},{"c":"20.048,16776960,4,25,539076,1376020667","m":"打卡! "},{"c":"10.402,16777215,1,25,460k3707822210,1376022278","m":"........................"},{"c":"1.338,16777215,1,25,19ak3084018091,1376023699","m":"摇起来"},{"c":"47.208,16777215,1,25,611704,1376025935","m":"...............收藏的什么心态"},{"c":"19.201,16777215,1,25,149k993230092,1376025990","m":"我去"},{"c":"50.283,16777215,1,25,149k993230092,1376026021","m":"鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅饿鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅鹅"},{"c":"80.286,16777215,1,25,149k993230092,1376026051","m":"啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊"},{"c":"27.743,16777215,1,25,403201,1376027204","m":"看上瘾了咋办"},{"c":"25.821,16737996,1,25,530815,1376028242","m":"!!!!!!!!!!!!!!!!!!!!"},{"c":"36.653,16737996,1,25,530815,1376028253","m":"干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"39.751,16737996,1,25,530815,1376028257","m":"干干干干干干干干干干干干干干干干干干干干干干"},{"c":"43.081,16737996,1,25,530815,1376028260","m":"干干干干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"45.765,16737996,1,25,530815,1376028263","m":"干干干干干干干干干干干干干干干干干干干干干干"},{"c":"48.797,16737996,1,25,530815,1376028266","m":"干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"51.47,16737996,1,25,530815,1376028268","m":"干干干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"54.289,16737996,1,25,530815,1376028271","m":"干干干干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"56.611,16737996,1,25,530815,1376028274","m":"干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"58.936,16737996,1,25,530815,1376028276","m":"干干干干干干干干干干干干干干干干干干干干干"},{"c":"61.193,16737996,1,25,530815,1376028278","m":"干干干干干干干干干干干干干干干干干干干"},{"c":"63.175,16737996,1,25,530815,1376028280","m":"干干干干干干干干干干干干干"},{"c":"26.562,16777215,1,25,571814,1376028282","m":"耶耶耶耶耶耶耶耶耶耶耶"},{"c":"66.757,16737996,1,25,530815,1376028284","m":"干干干干干干干干干干干干干干干干"},{"c":"69.165,16737996,1,25,530815,1376028286","m":"干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"71.557,16737996,1,25,530815,1376028288","m":"干干干干干干干干干干干干干干干干干干干干干干"},{"c":"73.735,16737996,1,25,530815,1376028291","m":"干干干干干干干干干干干干干干干干干干干干干"},{"c":"76.557,16737996,1,25,530815,1376028293","m":"干干干干干干干干干干干干干干干干干干干干"},{"c":"29.092,16711680,1,37,614672,1376028731","m":"16个基友"},{"c":"22.594,16777215,1,25,309584,1376030511","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"17.225,16777215,5,25,44bk3071973485,1376031371","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"3.602,16777215,1,25,13ek3664566159,1376031421","m":"。。。。。。。。"},{"c":"60.201,16777215,5,25,44bk3071973485,1376031433","m":"开撸"},{"c":"33.999,16777215,1,25,13ek3664566159,1376031451","m":"。。。。。。。。。。。。。。。。。。。。。。。。。。。。"},{"c":"81.941,16777215,1,25,27ek1017187980,1376032222","m":"诱惑"},{"c":"5.011,16777215,1,25,139k2015525676,1376032988","m":"打卡- -!"},{"c":"44.246,65535,1,37,455173,1376033209","m":"啊"},{"c":"36.058,16777215,1,25,377k1911910901,1376033512","m":"2013年8月9日15:31:52"},{"c":"21.127,16777215,1,25,104k1947652358,1376033802","m":"AHAHHAHAHA"},{"c":"2.284,16777215,1,25,194k2032039251,1376037377","m":"这么有来首页了"},{"c":"9.476,16776960,1,25,3f6k3070804403,1376042411","m":"打卡"},{"c":"0,16777215,1,25,325344,1376043241","m":"哈哈哈 又上来了 打卡 2013年8月9日 18:12:36"},{"c":"44.144,16777215,1,25,25fk3061655078,1376043624","m":"收藏的什么心态收藏的什么心态收藏的什么心态收藏的什么心态收藏的什么心态"},{"c":"10.301,16777215,1,25,1cak241839552,1376044031","m":"打卡"},{"c":"50.969,16777215,1,25,318k1904807183,1376045391","m":"。。。"},{"c":"73.398,16777215,1,25,318k1904807183,1376045413","m":"好大的屌!"},{"c":"26.087,16711680,1,25,614708,1376045441","m":".."},{"c":"31.691,16777215,1,25,4d4k3030298853,1376046937","m":"2013年马薇留"},{"c":"6.405,16777215,1,25,619757,1376048357","m":"重口味"},{"c":"24.329,16777215,1,25,619757,1376048374","m":"打卡"},{"c":"67.762,16777215,1,25,258k3730122316,1376050181","m":"0000000000000000000000000000000000000000000000"},{"c":"73.064,16777215,1,25,258k3730122316,1376050186","m":".0000000000000000000000000"},{"c":"78.785,16777215,1,25,258k3730122316,1376050192","m":"00000000000000000000000000000000000"},{"c":"87.771,16777215,1,25,258k3730122316,1376050203","m":"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},{"c":"1.437,13421772,1,25,611275,1376050973","m":"我看了这个就想走。。"},{"c":"15.69,13421772,1,37,611275,1376051015","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.69,13421772,1,37,611275,1376051017","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.69,13421772,1,37,611275,1376051019","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.69,13421772,1,37,611275,1376051022","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.69,13421772,1,25,611275,1376051026","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.69,13421772,1,16,611275,1376051030","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"67.909,3381759,1,37,611275,1376051114","m":"我不知道我想干什么。可是我就是想说话。。"},{"c":"79.327,3381759,1,37,611275,1376051135","m":"不觉得。。。杨坤么。。"},{"c":"7.009,13369344,1,25,458834,1376053218","m":".................."},{"c":"27.069,13369344,1,25,458834,1376053280","m":"草"},{"c":"34.131,16777215,1,25,367k1035115771,1376053822","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"13.785,16777215,1,25,330k1885029985,1376056009","m":"每日打卡"},{"c":"21.79,16777215,1,25,486050,1376056370","m":"......................."},{"c":"19.539,16711731,1,25,12bk2059537792,1376056446","m":"瞬间被刷屏了……"},{"c":"70.195,16711731,1,25,12bk2059537792,1376056498","m":"我竟然看完了……"},{"c":"12.902,16777215,1,25,393225,1376056911","m":"主页 \u003e 生活娱乐 / 暖被窝一次一千円节假日半价 / 发布于 2011年 4月28日(星期四) 7时24分 / 播放:408,415 评论:2,512 收藏:1,721 /"},{"c":"48.342,16777215,1,25,41ek3701560160,1376057555","m":"0 0"},{"c":"59.019,16777215,1,25,41ek3701560160,1376057566","m":"收藏什么心态"},{"c":"41.194,10027008,1,25,419k1007188745,1376057962","m":"基佬在此"},{"c":"69.806,10027008,1,25,419k1007188745,1376057991","m":"曹操草草草草草草草草草草草草草草草草草草草草草草草草草草草草草草草草"},{"c":"28.757,16777215,1,25,349k1965803175,1376058287","m":"是谁"},{"c":"0,16751001,4,25,617145,1376059073","m":"我操,史前巨坟,考古队赛高"},{"c":"49.29,16777215,1,25,546869,1376059201","m":"同步率爆表!"},{"c":"2.347,16711680,4,37,134k1020459866,1376060215","m":"杨坤即视感!爆表!"},{"c":"18.808,3394560,1,25,383341,1376061683","m":"顶起来顶起来"},{"c":"32.758,16777215,1,25,401332,1376062619","m":"..............................................."},{"c":"79.203,16777215,1,25,600050,1376063136","m":"1728个收藏是什么情况?"},{"c":"7.577,16711680,1,25,591937,1376066729","m":"打卡"},{"c":"14.959,16777215,1,25,312k2005722785,1376068554","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"27.52,16777215,1,25,620468,1376071363","m":"wocao"},{"c":"74.958,16711935,1,25,32ek3723106730,1376073723","m":"毫无节操"},{"c":"14.71,16777215,1,25,244k3703207273,1376075750","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"19.997,16777215,1,25,244k3703207273,1376075756","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"69.767,16777215,1,25,244k3703207273,1376075786","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"20.485,16776960,1,25,394k2021656327,1376097000","m":"什么情况?"},{"c":"82.358,16776960,1,25,394k2021656327,1376097055","m":"石更了"},{"c":"15.177,16777215,1,25,537000,1376098220","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.402,16777215,1,25,537000,1376098244","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"33.161,16777215,1,25,4d0k3059467444,1376098921","m":"我日"},{"c":"0.655,6723840,1,25,24ak1919230024,1376099553","m":"打卡"},{"c":"32.027,65280,1,25,566893,1376102189","m":"主页 \u003e 生活娱乐 / 暖被窝一次一千円节假日半价 / 发布于 2011年 4月28日(星期四) 7时24分 / "},{"c":"11.472,16777215,1,25,307884,1376104108","m":"每日打开"},{"c":"12.86,16777215,1,25,382659,1376104392","m":"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"},{"c":"15.413,16777215,1,25,382659,1376104409","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.413,16777215,1,25,382659,1376104415","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.413,16777215,1,25,382659,1376104422","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.413,16777215,1,25,382659,1376104428","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.413,16777215,1,25,382659,1376104435","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"29.998,13408665,1,25,439024,1376104583","m":"打卡"},{"c":"29.078,16777215,1,25,245951,1376105072","m":"打卡..."},{"c":"16.893,16777215,1,25,611704,1376108149","m":"走起来~也噩噩噩噩噩噩噩噩噩噩"},{"c":"15.124,16777215,1,25,252k1933384533,1376117070","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"25.018,16777215,1,25,338k1939335882,1376119947","m":"耶"},{"c":"0.482,16777215,1,25,566783,1376120825","m":"\u003d \u003d"},{"c":"34.632,16711680,1,25,289013,1376120976","m":"可耻的银恶灵"},{"c":"4.284,16777215,1,25,566697,1376121670","m":"神甩头……"},{"c":"16.939,13369344,4,25,48ck1942933904,1376124247","m":"报复社会搞起啊"},{"c":"12.574,16777215,1,25,499k3662479322,1376126734","m":"。。。。。"},{"c":"77.721,16777215,1,25,499k3662479322,1376126799","m":"我居然看完了+1..."},{"c":"66.386,6737151,1,25,621354,1376127623","m":"飞 "},{"c":"33.26,16777215,1,25,621447,1376131168","m":"日常打卡系列"},{"c":"13.877,16777215,1,25,4b1k3662454931,1376131296","m":"2013年8月10日 18:40:29"},{"c":"8.711,16777215,1,25,127k2104708180,1376131476","m":"..."},{"c":"13.243,16777215,1,25,10fk1034146970,1376131479","m":"来打卡。。。。。。。。。。"},{"c":"13.691,16777215,1,25,237582,1376131564","m":"啊♂"},{"c":"84.488,16777215,1,25,237582,1376131657","m":"这健美的肌肉,王の谜微笑"},{"c":"18.155,16777215,1,25,4d2k1018810962,1376133311","m":"顶上去报复社会"},{"c":"55.547,16776960,4,25,418k1996750992,1376133796","m":"小伙伴好强悍"},{"c":"14.218,13434624,1,25,576058,1376134995","m":"wocao "},{"c":"26.499,13434624,1,25,576058,1376135008","m":"3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"},{"c":"39.818,13434624,1,25,576058,1376135021","m":"3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"},{"c":"52.38,13434624,1,25,576058,1376135033","m":"3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"},{"c":"35.837,16777215,1,25,2c9k2078827628,1376135639","m":"顶上去报复社会"},{"c":"15.832,16777215,1,25,186k3074211670,1376137394","m":"杨坤 卧槽"},{"c":"38.655,16777215,1,25,186k3074211670,1376137417","m":"啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊"},{"c":"51.2,16777215,1,25,186k3074211670,1376137430","m":"科比"},{"c":"37.391,16777215,1,25,608896,1376137620","m":"挖坟老坑了!!- -"},{"c":"20.606,16777215,1,25,325344,1376139878","m":"打卡 2013年8月10日 21:03:12 "},{"c":"31.826,13369344,1,25,3b9k1947407437,1376139894","m":"啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊"},{"c":"23.769,16777215,1,25,249393,1376142115","m":"耶耶耶"},{"c":"6.929,13434777,1,25,404k2086353330,1376145403","m":"打卡吧……"},{"c":"76.145,16777215,1,25,458k2034184434,1376146315","m":"好屌屌屌屌屌屌屌屌屌屌屌屌屌屌"},{"c":"87.886,16777215,1,25,317k3729928182,1376147520","m":"有木有感觉像罗纳尔多"},{"c":"46.027,16777215,1,25,1cek2105502321,1376149328","m":"410000"},{"c":"66.967,13369395,5,25,489k3661677826,1376150846","m":"前来打卡"},{"c":"12.447,16777215,1,25,37ck1785980621,1376179903","m":"- -2013.8.11"},{"c":"48.757,16777215,1,25,37ck1785980621,1376179940","m":"硬了怎么办"},{"c":"0.297,6749952,5,25,516261,1376181869","m":"欢迎观看《肌肉进行曲》"},{"c":"14.965,16777215,1,25,44bk3071973485,1376182825","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"12.347,16776960,4,37,507878,1376183526","m":"AV画质"},{"c":"44.318,16776960,4,37,507878,1376183560","m":"1765个收藏心态"},{"c":"15.332,16777215,1,25,1d4k236011651,1376187564","m":"罗纳尔多"},{"c":"23.92,16777215,1,25,1dbk1786742976,1376190305","m":"............."},{"c":"87.917,16777215,1,25,1dbk1786742976,1376190407","m":"迷の微笑"},{"c":"47.296,16777215,1,25,2b5k3730060046,1376191845","m":"广西频道发来贺电"},{"c":"47.032,16777215,1,25,1b7k2095450225,1376193392","m":"我要吐了"},{"c":"77.956,6684672,5,25,1b7k2095450225,1376193474","m":"?????????????????????????????????????????????"},{"c":"14.184,16777215,1,25,320k2883429025,1376193568","m":"YEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYEYE"},{"c":"77.956,6684672,5,25,1b7k2095450225,1376193581","m":"?????????欢迎使用护眼弹幕??????????"},{"c":"77.956,6684672,5,25,1b7k2095450225,1376193596","m":"??????????????????????????????????????"},{"c":"16.222,13395609,1,25,320k2883429025,1376193605","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"27.023,16777215,1,25,529412,1376193841","m":"节操掉了一地"},{"c":"1.652,13434624,1,25,595888,1376197519","m":"看过不说话"},{"c":"8.227,16777215,1,25,622565,1376199281","m":"打卡"},{"c":"14.5,3394815,1,25,506067,1376202751","m":"打卡"},{"c":"18.145,16777215,1,25,584461,1376203682","m":"每日打卡!!!!"},{"c":"3.565,16777215,1,25,622662,1376203695","m":"..."},{"c":"12.625,16777215,1,25,39ak977057938,1376205596","m":"哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇"},{"c":"73.017,16777215,1,25,592163,1376206800","m":"光滑 没毛!!!!"},{"c":"73.017,10092441,1,25,592163,1376206815","m":"没毛!!"},{"c":"6.05,16777215,1,25,37ck1785980621,1376206948","m":"2013.8.11"},{"c":"58.484,16711680,1,37,2d8k1946238324,1376208217","m":"他要自摸了。。。。。。。。。受不鸟了。。。。"},{"c":"5.201,16777215,1,25,250k409716719,1376208782","m":"打开"},{"c":"18.939,16777215,1,25,206k1911775910,1376210523","m":"呵呵"},{"c":"52.488,16777215,1,25,206k1911775910,1376210557","m":"刷屏+1"},{"c":"67.016,16777215,1,25,206k1911775910,1376210571","m":"法克"},{"c":"81.281,16777215,1,25,3f4k2073541231,1376210956","m":"啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊"},{"c":"80.625,16777215,1,25,100k3030428551,1376211394","m":"打证白"},{"c":"31.416,16777215,1,25,614007,1376212423","m":"什么东西"},{"c":"14.009,16777215,1,25,44bk3071973485,1376212845","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"27.607,16777215,1,25,572231,1376213936","m":"日常打卡"},{"c":"16.912,16777215,1,25,605743,1376218302","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"9.1,16777215,1,25,605743,1376219700","m":"看一遍笑一次。。"},{"c":"16.279,16777215,1,25,605743,1376219708","m":"耶耶耶耶耶"},{"c":"15.025,16777215,1,25,2a0k1010239990,1376219790","m":"........................................................................"},{"c":"4.305,16777215,1,25,11ak1894547491,1376220450","m":"..."},{"c":"10.339,16777215,1,25,482k2034062684,1376221602","m":"d打卡"},{"c":"20.025,16777215,1,25,482k2034062684,1376221611","m":"夜夜夜夜"},{"c":"30.814,16777215,1,25,498k2102044667,1376224344","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶爷爷爷爷夜夜夜yee5"},{"c":"58.483,16777215,1,25,498k2102044667,1376224371","m":"擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦"},{"c":"12.275,16777215,1,25,23bk3733406631,1376224558","m":"打卡"},{"c":"9.587,16711782,1,25,367k2057138470,1376225672","m":"表情超销魂!"},{"c":"13.88,16711680,1,25,334k3070638933,1376226617","m":" "},{"c":"18.243,16777215,1,25,375895,1376228032","m":"我也来打个卡吧"},{"c":"35.603,16777215,1,25,309177,1376228477","m":"夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜夜"},{"c":"24.416,16777215,1,25,158576,1376228832","m":"无法直视"},{"c":"13.837,13382502,1,25,620591,1376231904","m":"打卡"},{"c":"25.387,13382502,1,25,620591,1376231916","m":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},{"c":"53.762,13382502,1,25,620591,1376231944","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"73.111,13382502,4,25,620591,1376231964","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"84.769,13382502,1,25,620591,1376231975","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"22.134,16777215,1,25,623376,1376232266","m":"......................"},{"c":"55.778,16777215,1,25,597552,1376232792","m":"神弹幕 不可否认 我是看弹幕的"},{"c":"8.139,16777215,1,25,130k2876188882,1376234404","m":"a"},{"c":"15.353,16777215,1,25,121k3730778254,1376234861","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.659,6684825,1,25,189k2073480635,1376239744","m":"夜夜夜夜夜夜夜夜夜夜夜夜"},{"c":"23.454,16724736,1,25,1b3k3670962492,1376266101","m":"2013.8.12"},{"c":"14.862,16724736,1,25,1b3k3670962492,1376266182","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"22.954,16724736,1,25,1b3k3670962492,1376266190","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"30.16,16776960,1,25,180k249509149,1376275642","m":"液"},{"c":"6.397,16777215,1,25,624035,1376276334","m":"打卡"},{"c":"30.983,16777215,1,25,4a5k1946234471,1376279150","m":"软掉了 T.T..."},{"c":"54.218,16777215,1,25,4a5k1946234471,1376279174","m":"竟然软掉了 ,,,,"},{"c":"40.096,16777215,1,25,1e2k3029168501,1376279250","m":"我是来听BGM的"},{"c":"30.241,16777215,1,25,454k463273829,1376280162","m":"打卡"},{"c":"48.883,16777215,1,25,393225,1376281142","m":"今日打卡2013年8月12日 12:19:05"},{"c":"45.148,13369599,4,37,1b3k1033710953,1376282278","m":"2013.8.12"},{"c":"57.568,16777215,1,25,44bk1851130326,1376282652","m":"真的是香蕉吗"},{"c":"17.456,16777215,1,25,2c3k3702014318,1376283657","m":"\u003d \u003d"},{"c":"10.043,6749952,1,25,4d8k3722613906,1376285088","m":"打卡"},{"c":"81.256,6749952,1,25,4d8k3722613906,1376285159","m":"我艹!不能直视啊 "},{"c":"77.976,16777215,1,25,532917,1376287835","m":"1799收藏"},{"c":"0.632,16777215,1,25,624425,1376289715","m":"打卡"},{"c":"24.667,16777215,1,25,622912,1376291639","m":"2013-8-12 15:13:58"},{"c":"0,16777215,1,25,567743,1376294017","m":"打卡了绅士们..."},{"c":"21.687,13408512,1,25,20bk986871394,1376294378","m":"耶耶耶"},{"c":"15.04,13408512,1,25,20bk986871394,1376294480","m":"耶耶耶耶耶"},{"c":"18.614,16777215,1,25,585664,1376297871","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.819,16711680,1,25,591937,1376297948","m":"打卡!!!!!!!!!"},{"c":"16.468,16711680,1,25,591937,1376298006","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"17.037,16777215,1,25,566697,1376300118","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶夜夜2"},{"c":"14.844,16777215,1,25,566697,1376300171","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.789,16777215,1,25,20ek2007451346,1376301534","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"13.681,16777215,1,25,559740,1376302153","m":"yoo"},{"c":"14.361,16777215,1,25,597374,1376304489","m":"打卡"},{"c":"3.66,16777215,1,25,266k3723106730,1376308867","m":"打卡"},{"c":"30.341,16711731,4,37,266k3723106730,1376308894","m":"继续丧心病狂"},{"c":"10.565,16777215,1,25,3c6k3757386694,1376309156","m":"打卡"},{"c":"16.416,16777215,1,25,4d2k1018810962,1376309537","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"12.315,16777215,1,25,4d2k1018810962,1376309718","m":"看了7遍了。。"},{"c":"45.952,16777215,1,25,271k1867408839,1376310116","m":"顶上去报复社会"},{"c":"59.282,16777215,1,25,315k3396199020,1376310939","m":"我擦啊啊 啊啊啊啊啊啊啊"},{"c":"24.622,16777215,1,25,248k1911799324,1376311419","m":"打卡+1"},{"c":"41.684,16777215,1,25,248k1911799324,1376311436","m":"每日必看- -"},{"c":"80.693,16777215,1,25,38ak1960930797,1376312094","m":"..."},{"c":"25.238,16777215,1,25,1b5k3701977691,1376318290","m":"................"},{"c":"13.113,16777215,1,25,172661,1376318903","m":"2013.8.12"},{"c":"51.958,16711680,1,25,387645,1376321267","m":"顶上去报复社会"},{"c":"19.408,16777215,1,25,178252,1376325904","m":"金刚如来!"},{"c":"13.351,16777215,1,25,166k3662278790,1376328310","m":"求BGM"},{"c":"52.529,16777215,1,25,166k3662278790,1376328349","m":"文化接触太给力了"},{"c":"46.894,16777215,1,25,258k3658903074,1376342389","m":"丧心病狂!"},{"c":"23.442,16777215,1,25,625727,1376342676","m":"打卡啊"},{"c":"11.096,16777215,1,25,385k2006107404,1376352828","m":"前来打卡"},{"c":"19.957,16777215,1,25,313k2074454599,1376353232","m":"弹幕好多啊"},{"c":"76.404,16777215,1,25,522845,1376353426","m":" - -"},{"c":"14.544,16777215,1,25,34fk245272954,1376357240","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"16.276,16777215,1,25,34fk245272954,1376357245","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"16.276,16777215,1,25,34fk245272954,1376357250","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"9.564,16777215,1,25,572231,1376360217","m":"每日打卡"},{"c":"14.666,3407616,1,25,576285,1376361161","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361165","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361168","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361171","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,4,25,576285,1376361178","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,4,25,576285,1376361181","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,4,25,576285,1376361183","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361192","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361196","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361198","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361200","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361202","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361204","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361206","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361210","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361213","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.666,3407616,1,25,576285,1376361218","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"5.177,26316,4,25,267k2090994000,1376361508","m":"炒饭?"},{"c":"87.933,16777215,1,25,1a7k3069283466,1376361779","m":"2013年8月13"},{"c":"27.815,16777215,1,25,171405,1376362569","m":"耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!"},{"c":"32.579,16777215,1,25,171405,1376362574","m":"耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!耶耶!!!!!!!!!!!"},{"c":"7.32,16777215,1,25,119k1857965230,1376365425","m":"耶耶耶耶~"},{"c":"15.537,16777215,1,25,1c7k2101364304,1376365766","m":"没弹幕"},{"c":"45.25,10027161,1,25,387k453943713,1376367231","m":"杨坤,"},{"c":"7.229,16776960,1,25,606859,1376370237","m":"打卡。。"},{"c":"0,6710886,1,25,582628,1376370715","m":"wa"},{"c":"5.823,16777215,1,25,352k1017434011,1376371231","m":"......................."},{"c":"3.909,16777215,1,25,417219,1376371271","m":"打卡。。。。。。"},{"c":"17.374,16777215,1,25,566697,1376373973","m":"耶耶耶耶耶耶耶耶耶"},{"c":"14.054,16777215,1,37,566697,1376374027","m":"are you ready"},{"c":"13.541,16711680,5,37,566697,1376374083","m":"Are you ready"},{"c":"17.659,3381759,1,25,424199,1376374824","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"33.684,16777011,1,25,406k3029170287,1376377099","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"13.417,16777215,1,25,532321,1376377112","m":"2013-08-13 14:58:38 打卡"},{"c":"16.714,13158,1,37,532321,1376377128","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"20.598,13158,1,37,532321,1376377132","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"22.68,13158,1,37,532321,1376377134","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"76.478,16777011,4,25,406k3029170287,1376377142","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"87.215,16777011,4,25,406k3029170287,1376377153","m":"500个基友不说话"},{"c":"19.279,13369344,5,37,532321,1376377169","m":"2013-08-13 14:59:35 每日打卡"},{"c":"29.294,16777215,1,25,626391,1376377489","m":"我看了3次了"},{"c":"79.901,16777215,1,25,626391,1376377540","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"59.807,16777215,1,25,4dck1035737753,1376377654","m":"杨坤有木有?"},{"c":"11.296,16777215,1,25,4dck1035737753,1376377695","m":"杨坤杨坤杨坤"},{"c":"39.395,16777215,1,25,4dck1035737753,1376377708","m":"杨坤"},{"c":"63.041,16777215,1,25,532917,1376377930","m":"主页 \u003e 生活娱乐 / 暖被窝一次一千円节假日半价 / 发布于 2011年 4月28日(星期四) 7时24分 / 播放:415,449 评论:2,533 收藏:1,824 /"},{"c":"25.6,16777215,1,25,145k3395750786,1376378270","m":"打卡日常!"},{"c":"24.629,6750207,1,25,478k3072636344,1376385749","m":"弄得一手好洛阳铲!"},{"c":"64.338,6750207,1,37,478k3072636344,1376385789","m":"大香蕉!"},{"c":"76.837,6750207,1,37,478k3072636344,1376385802","m":"有耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"9.913,16711680,1,25,461k2032076344,1376387128","m":"不是这首歌捏"},{"c":"41.313,16711680,1,25,461k2032076344,1376387160","m":"怎么可能是炒饭呢 我不认识他……\u003d。\u003d"},{"c":"66.44,16777215,1,25,605539,1376392369","m":"1826个收藏什么心态"},{"c":"5.782,16777215,1,25,360088,1376396483","m":"摇起来"},{"c":"26.991,16777215,1,25,21ak1033502638,1376397265","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"16.38,16777215,1,25,21ak1033502638,1376397277","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶v耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"44.459,16777215,1,25,3bdk2947511981,1376398050","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"55.836,16777215,1,25,3bdk2947511981,1376398062","m":"小丁丁"},{"c":"24.275,3407616,1,25,597033,1376398577","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"15.221,16711680,1,25,120k3085204837,1376398889","m":"......"},{"c":"14.751,16711680,1,25,120k3085204837,1376398919","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"19.935,16711680,1,25,120k3085204837,1376398924","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"33.583,16777215,1,25,441775,1376402422","m":"打卡不解释"},{"c":"18.175,16777215,1,25,600087,1376402531","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"14.615,16777215,5,25,585664,1376402819","m":"Are you ready?"},{"c":"10.981,16777215,1,25,400k3061677543,1376402907","m":"打卡"},{"c":"19.41,16777215,1,25,29ck1900353397,1376403241","m":"................."},{"c":"40.775,16777215,1,25,223k244518479,1376406469","m":"看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊看不到啊"},{"c":"17.361,16777215,1,25,3b3k3659281694,1376407201","m":"2013年8月13日 23:19:57"},{"c":"34.2,16777215,1,25,599621,1376409181","m":"我又来了"},{"c":"0,16711680,1,25,611275,1376410430","m":"这是一个让大家都变基佬的阴谋。"},{"c":"47.866,16711680,1,25,611275,1376410484","m":"我的眼睛!!!"},{"c":"55.535,16711680,4,37,611275,1376410502","m":"我的眼睛!"},{"c":"84.865,65535,1,25,3a5k1781617181,1376411413","m":"干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干干"},{"c":"12.776,16777215,1,25,276k1981480729,1376412042","m":"。。。。"},{"c":"47.856,16711680,1,25,4cek1867427908,1376414470","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"78.741,16711680,1,37,4cek1867427908,1376414501","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"70.281,16777215,1,25,40fk2948117381,1376427964","m":"无法直视 丧心病狂"},{"c":"17.25,16777215,1,25,20ek3083468584,1376428049","m":"打卡8.14早上"},{"c":"17.965,16777215,1,25,20ek3083468584,1376428081","m":"耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶耶"},{"c":"36.487,16777215,1,25,254049,1376429548","m":"求bgm"},{"c":"43.589,16777215,1,25,177k3662843066,1376435280","m":"丧心病狂的七夕"},{"c":"15.152,16777215,1,25,453k3723125416,1376444152","m":"打卡"},{"c":"65.262,16777215,1,25,453k3723125416,1376444202","m":"卧槽、"},{"c":"16.507,16777215,1,25,166316,1376446088","m":"美国大雕"},{"c":"17.339,13369344,1,25,532321,1376453125","m":"2013年8月14日 12:05:26 打卡"},{"c":"48.351,6750003,1,25,615328,1376453285","m":"baofushehui!!!!!!!!!!!"},{"c":"58.802,16777215,1,25,3d0k2095941037,1376456170","m":"⑨个小伙你好"},{"c":"68.467,16777215,1,25,3d0k2095941037,1376456180","m":"曹。。。。"},{"c":"18.832,16711680,1,25,385421,1376457625","m":"8月14日赵志斌打卡"},{"c":"0.493,16711680,4,25,385421,1376457661","m":"8月14日赵志斌打卡广州北大附中贺电"},{"c":"0,16777215,1,25,403k3721738134,1376458877","m":"2013年8月14日13:42"},{"c":"5.345,16777215,1,25,19ak2000570677,1376459956","m":"打卡"},{"c":"4.087,16777215,1,25,580660,1376461730","m":"兄贵--------------------------------------------------------------------------------------------------"},{"c":"12.885,16777215,1,25,149k1912070066,1376466041","m":"......................"},{"c":"21.97,16777215,1,25,149k1912070066,1376466070","m":"表情帝!!!!!!!!!!!!!!!!!!"},{"c":"5.968,13408512,1,25,4d9k3736983214,1376466747","m":"日常打卡"},{"c":"63.916,13408512,1,25,4d9k3736983214,1376466805","m":" 收藏:1,842 "},{"c":"38.359,16777215,1,25,18ck3663086991,1376468188","m":".."},{"c":"10.45,16777215,1,25,554498,1376469294","m":"k "},{"c":"14.564,16777215,1,25,146k3740635017,1376470286","m":"```````````````````````"},{"c":"77.734,16777215,1,25,376k1900079524,1376471392","m":"一样呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀呀"}]
================================================
FILE: app/src/main/assets/online.xml
================================================
1.1.0default stream001002003004005006007008009010011012013014214216072073366370018027036037038039042043044045046047048049050051052053054055056057058059061064170171172174286016017068070075107159160161162163164231294203204208209212213201277005015094126140322366367368277369018022112113114027108111126127128130131132133372373240320368036085086087088089090094056115116117118119202337338339340341342040134140141225064015060061062065066123124165191192193194195196197198199200234235334335369055295296297298299300301057323324325326327328329059302303304305306307308170226345346347348349350286042322332047310311312063352353354355356171045187236
================================================
FILE: app/src/main/java/com/cjj/bb/activity/ABPlayerApplication.java
================================================
package com.cjj.bb.activity;
import android.app.Application;
import android.content.Context;
import android.os.Environment;
import com.cjj.bb.view.FileUtils;
public class ABPlayerApplication extends Application{
private static ABPlayerApplication mApplication;
/** OPlayer SD卡缓存路径 */
public static final String OPLAYER_CACHE_BASE = Environment.getExternalStorageDirectory() + "/oplayer";
/** 视频截图缓冲路径 */
public static final String OPLAYER_VIDEO_THUMB = OPLAYER_CACHE_BASE + "/thumb/";
/** 首次扫描 */
public static final String PREF_KEY_FIRST = "application_first";
@Override
public void onCreate() {
super.onCreate();
mApplication = this;
init();
}
private void init() {
//创建缓存目录
FileUtils.createIfNoExists(OPLAYER_CACHE_BASE);
FileUtils.createIfNoExists(OPLAYER_VIDEO_THUMB);
}
public static ABPlayerApplication getApplication() {
return mApplication;
}
public static Context getContext() {
return mApplication;
}
/** 销毁 */
public void destory() {
mApplication = null;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/BiliVideoViewActivity.java
================================================
package com.cjj.bb.activity;
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import io.vov.vitamio.utils.FileUtils;
import io.vov.vitamio.utils.Log;
import io.vov.vitamio.widget.OutlineTextView;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.zip.DataFormatException;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.helper.HttpConnection.Response;
import master.flame.danmaku.controller.IDanmakuView;
import master.flame.danmaku.danmaku.loader.ILoader;
import master.flame.danmaku.danmaku.loader.IllegalDataException;
import master.flame.danmaku.danmaku.loader.android.DanmakuLoaderFactory;
import master.flame.danmaku.danmaku.model.android.DanmakuGlobalConfig;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.danmaku.parser.IDataSource;
import master.flame.danmaku.danmaku.parser.android.BiliDanmukuParser;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.cjj.bb.R;
import com.cjj.bb.utils.CompressionTools;
import com.cjj.bb.utils.DeviceUtils;
import com.cjj.bb.utils.HttpUtil;
import com.cjj.bb.utils.ImageUtils;
import com.cjj.bb.utils.MediaUtils;
import com.cjj.bb.utils.PreferenceUtils;
import com.cjj.bb.utils.StringUtils;
import com.cjj.bb.utils.ToastUtils;
import com.cjj.bb.view.ApplicationUtils;
import com.cjj.bb.view.MediaController;
import com.cjj.bb.view.PlayerService;
import com.cjj.bb.view.VP;
import com.cjj.bb.view.VideoView;
@SuppressLint("HandlerLeak")
public class BiliVideoViewActivity extends Activity implements
MediaController.MediaPlayerControl, VideoView.SurfaceCallback {
public static final int RESULT_FAILED = -7;
private static final IntentFilter USER_PRESENT_FILTER = new IntentFilter(
Intent.ACTION_USER_PRESENT);
private static final IntentFilter SCREEN_FILTER = new IntentFilter(
Intent.ACTION_SCREEN_ON);
private static final IntentFilter HEADSET_FILTER = new IntentFilter(
Intent.ACTION_HEADSET_PLUG);
private static final IntentFilter BATTERY_FILTER = new IntentFilter(
Intent.ACTION_BATTERY_CHANGED);
private IDanmakuView mDanmakuView;//弹幕控件
private BaseDanmakuParser mParser;
private String danmakuPath;
private String av;
private String page;
private boolean isload = false;
private boolean isfirst = true;
private View startVideo;
private TextView startVideoInfo;
private String startText = "初始化播放器...";
private ImageView biliAnim;
private AnimationDrawable anim;
private boolean mCreated = false;
private boolean mNeedLock;
private String mDisplayName;
private String mBatteryLevel;
private boolean mFromStart;
private int mLoopCount;
private boolean mSaveUri;
private int mParentId;
private float mStartPos;
private boolean mEnd = false;
private String mSubPath;
private boolean mSubShown;
private View mViewRoot;
private VideoView mVideoView;
private View mVideoLoadingLayout;
private TextView mVideoLoadingText;
private View mSubtitleContainer;
private OutlineTextView mSubtitleText;
private ImageView mSubtitleImage;
private Uri mUri;
private ScreenReceiver mScreenReceiver;
private HeadsetPlugReceiver mHeadsetPlugReceiver;
private UserPresentReceiver mUserPresentReceiver;
private BatteryReceiver mBatteryReceiver;
private boolean mReceiverRegistered = false;
private boolean mHeadsetPlaying = false;
private boolean mCloseComplete = false;
private boolean mIsHWCodec = false;
private MediaController mMediaController;
private PlayerService vPlayer;
private ServiceConnection vPlayerServiceConnection;
// private Animation mLoadingAnimation;
// private View mLoadingProgressView;
static {
SCREEN_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
return;
vPlayerServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
vPlayer = ((PlayerService.LocalBinder) service).getService();
mServiceConnected = true;
if (mSurfaceCreated)
vPlayerHandler.sendEmptyMessage(OPEN_FILE);
}
@Override
public void onServiceDisconnected(ComponentName name) {
vPlayer = null;
mServiceConnected = false;
}
};
setVolumeControlStream(AudioManager.STREAM_MUSIC);
parseIntent(getIntent());
loadView(R.layout.activity_video);
manageReceivers();
findViews();
mCreated = true;
startText = startText + "【完成】\n解析视频地址...【完成】\n全舰弹幕填装...";
startVideoInfo.setText(startText);
new VideoViewInitTask().execute();
}
private void findViews(){
// DanmakuView
mDanmakuView = (IDanmakuView) findViewById(R.id.sv_danmaku);
startVideo = (View) findViewById(R.id.video_start);
startVideo.setVisibility(View.VISIBLE);
startVideoInfo = (TextView) findViewById(R.id.video_start_info);
biliAnim = (ImageView) findViewById(R.id.bili_anim);
anim = (AnimationDrawable) biliAnim.getBackground();
anim.start();
DanmakuGlobalConfig.DEFAULT.setDanmakuStyle(DanmakuGlobalConfig.DANMAKU_STYLE_STROKEN, 3).setDuplicateMergingEnabled(false);
// if (mDanmakuView != null) {
// //mParser = createParser(this.getResources().openRawResource(R.raw.comments));
// mParser = createParser(openFileInput(danmakuPath));
// //mParser = createParser(danmakuPath);
// mDanmakuView.setCallback(new Callback() {
//
// @Override
// public void updateTimer(DanmakuTimer timer) {
//
// }
//
// @Override
// public void prepared() {
// isload = true;
// startPlayer();
// //mDanmakuView.start();
// }
// });
// mDanmakuView.prepare(mParser);
//
// mDanmakuView.showFPS(true);
// mDanmakuView.enableDanmakuDrawingCache(true);
// ((View) mDanmakuView).setOnClickListener(new View.OnClickListener() {
//
// @Override
// public void onClick(View view) {
// mMediaController.setVisibility(View.VISIBLE);
// }
// });
// }
}
private BaseDanmakuParser createParser(InputStream stream) {
if(stream==null){
return new BaseDanmakuParser() {
@Override
protected Danmakus parse() {
return new Danmakus();
}
};
}
ILoader loader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);
try {
loader.load(stream);
} catch (IllegalDataException e) {
e.printStackTrace();
}
BaseDanmakuParser parser = new BiliDanmukuParser();
IDataSource> dataSource = loader.getDataSource();
parser.load(dataSource);
return parser;
}
private BaseDanmakuParser createParser(String uri) {
InputStream stream = null;
if(uri==null){
return new BaseDanmakuParser() {
@Override
protected Danmakus parse() {
return new Danmakus();
}
};
}
try {
Response rsp = (Response) Jsoup.connect(uri).execute();
stream = new ByteArrayInputStream(CompressionTools.decompressXML(rsp.bodyAsBytes()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (DataFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ILoader loader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);
try {
loader.load(stream);
} catch (IllegalDataException e) {
e.printStackTrace();
}
BaseDanmakuParser parser = new BiliDanmukuParser();
IDataSource> dataSource = loader.getDataSource();
parser.load(dataSource);
return parser;
}
private void attachMediaController() {
if (mMediaController != null) {
mNeedLock = mMediaController.isLocked();
mMediaController.release();
}
mMediaController = new MediaController(this, mNeedLock);
mMediaController.setMediaPlayer(this);
mMediaController.setAnchorView(mVideoView.getRootView());
setFileName();
setBatteryLevel();
}
@Override
public void onStart() {
super.onStart();
if (!mCreated)
return;
// Intent serviceIntent = new Intent(this, PlayerService.class);
// serviceIntent.putExtra("isHWCodec", mIsHWCodec);
// bindService(serviceIntent, vPlayerServiceConnection,
// Context.BIND_AUTO_CREATE);
}
@Override
public void onResume() {
super.onResume();
if (!mCreated)
return;
if (isInitialized()) {
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
if (!keyguardManager.inKeyguardRestrictedInputMode()) {
startPlayer();
}
} else {
if (mCloseComplete) {
reOpen();
}
}
if (mDanmakuView != null && mDanmakuView.isPrepared() && mDanmakuView.isPaused()) {
mDanmakuView.resume();
}
}
@Override
public void onPause() {
super.onPause();
if (!mCreated)
return;
if (isInitialized()) {
//savePosition();
if (vPlayer != null && vPlayer.isPlaying()) {
stopPlayer();
}
}
if (mDanmakuView != null && mDanmakuView.isPrepared()) {
mDanmakuView.pause();
}
}
@Override
public void onStop() {
super.onStop();
if (!mCreated)
return;
if (isInitialized()) {
vPlayer.releaseSurface();
}
if (mServiceConnected) {
unbindService(vPlayerServiceConnection);
mServiceConnected = false;
}
// if (mDanmakuView != null) {
// // dont forget release!
// mDanmakuView.release();
// mDanmakuView = null;
// }
}
@Override
public void onDestroy() {
super.onDestroy();
if (!mCreated)
return;
manageReceivers();
if (isInitialized() && !vPlayer.isPlaying())
release();
if (mMediaController != null)
mMediaController.release();
if (mDanmakuView != null) {
// dont forget release!
mDanmakuView.release();
mDanmakuView = null;
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (isInitialized()) {
setVideoLayout();
attachMediaController();
}
super.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed() {
// super.onBackPressed();
// if (mDanmakuView != null) {
// // dont forget release!
// mDanmakuView.release();
// mDanmakuView = null;
// }
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// http://code.google.com/p/android/issues/detail?id=19917
outState.putString("WORKAROUND_FOR_BUG_19917_KEY",
"WORKAROUND_FOR_BUG_19917_VALUE");
super.onSaveInstanceState(outState);
}
@Override
public void showMenu() {
}
private void loadView(int id) {
setContentView(id);
getWindow().setBackgroundDrawable(null);
mViewRoot = findViewById(R.id.video_root);
mVideoView = (VideoView) findViewById(R.id.video);
mVideoView.initialize(this, this, mIsHWCodec);
mSubtitleContainer = findViewById(R.id.subtitle_container);
mSubtitleText = (OutlineTextView) findViewById(R.id.subtitle_text);
mSubtitleImage = (ImageView) findViewById(R.id.subtitle_image);
mVideoLoadingText = (TextView) findViewById(R.id.video_loading_text);
mVideoLoadingLayout = findViewById(R.id.video_loading);
// mLoadingProgressView =
// mVideoLoadingLayout.findViewById(R.id.video_loading_progress);
// mLoadingAnimation = AnimationUtils.loadAnimation(VideoActivity.this,
// R.anim.loading_rotate);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
private void parseIntent(Intent i) {
// Uri dat = IntentHelper.getIntentUri(i);
// if (dat == null)
// resultFinish(RESULT_FAILED);
//
// String datString = dat.toString();
// if (!datString.equals(dat.toString()))
// dat = Uri.parse(datString);
//
// mUri = dat;
// danmakuPath = "http://comment.bilibili.com/"+i.getStringExtra("CID")+".xml";
// Logger.d(danmakuPath);
av = i.getStringExtra("av");
page = i.getStringExtra("page");
mNeedLock = i.getBooleanExtra("lockScreen", false);
mDisplayName = i.getStringExtra("displayName");
mFromStart = i.getBooleanExtra("fromStart", false);
mSaveUri = i.getBooleanExtra("saveUri", true);
mStartPos = i.getFloatExtra("startPosition", -1.0f);
mLoopCount = i.getIntExtra("loopCount", 1);
mParentId = i.getIntExtra("parentId", 0);
mSubPath = i.getStringExtra("subPath");
mSubShown = i.getBooleanExtra("subShown", true);
mIsHWCodec = i.getBooleanExtra("hwCodec", false);
Log.i("L: %b, N: %s, S: %b, P: %f, LP: %d", mNeedLock, mDisplayName,
mFromStart, mStartPos, mLoopCount);
}
private void manageReceivers() {
if (!mReceiverRegistered) {
mScreenReceiver = new ScreenReceiver();
registerReceiver(mScreenReceiver, SCREEN_FILTER);
mUserPresentReceiver = new UserPresentReceiver();
registerReceiver(mUserPresentReceiver, USER_PRESENT_FILTER);
mBatteryReceiver = new BatteryReceiver();
registerReceiver(mBatteryReceiver, BATTERY_FILTER);
mHeadsetPlugReceiver = new HeadsetPlugReceiver();
registerReceiver(mHeadsetPlugReceiver, HEADSET_FILTER);
mReceiverRegistered = true;
} else {
try {
if (mScreenReceiver != null)
unregisterReceiver(mScreenReceiver);
if (mUserPresentReceiver != null)
unregisterReceiver(mUserPresentReceiver);
if (mHeadsetPlugReceiver != null)
unregisterReceiver(mHeadsetPlugReceiver);
if (mBatteryReceiver != null)
unregisterReceiver(mBatteryReceiver);
} catch (IllegalArgumentException e) {
}
mReceiverRegistered = false;
}
}
private void setFileName() {
if (mUri != null) {
String name = null;
if (mUri.getScheme() == null || mUri.getScheme().equals("file"))
name = FileUtils.getName(mUri.toString());
else
name = mUri.getLastPathSegment();
if (name == null)
name = "null";
if (mDisplayName == null)
mDisplayName = name;
mMediaController.setFileName(mDisplayName);
}
}
private void applyResult(int resultCode) {
vPlayerHandler.removeMessages(BUFFER_PROGRESS);
Intent i = new Intent();
i.putExtra("filePath", mUri.toString());
if (isInitialized()) {
i.putExtra("position", (double) vPlayer.getCurrentPosition()
/ vPlayer.getDuration());
i.putExtra("duration", vPlayer.getDuration());
//savePosition();
}
switch (resultCode) {
case RESULT_FAILED:
ToastUtils.showLongToast(R.string.video_cannot_play);
break;
case RESULT_CANCELED:
case RESULT_OK:
break;
}
setResult(resultCode, i);
}
private void resultFinish(int resultCode) {
applyResult(resultCode);
if (DeviceUtils.hasICS() && resultCode != RESULT_FAILED) {
android.os.Process.killProcess(android.os.Process.myPid());
} else {
finish();
}
}
private void release() {
if (vPlayer != null) {
if (DeviceUtils.hasICS()) {
android.os.Process.killProcess(android.os.Process.myPid());
} else {
vPlayer.release();
vPlayer.releaseContext();
}
}
}
private void reOpen(Uri path, String name, boolean fromStart) {
if (isInitialized()) {
//savePosition();
vPlayer.release();
vPlayer.releaseContext();
}
Intent i = getIntent();
if (mMediaController != null)
i.putExtra("lockScreen", mMediaController.isLocked());
i.putExtra("startPosition", PreferenceUtils.getFloat(mUri
+ VP.SESSION_LAST_POSITION_SUFIX, 7.7f));
i.putExtra("fromStart", fromStart);
i.putExtra("displayName", name);
i.setData(path);
parseIntent(i);
mUri = path;
if (mViewRoot != null)
mViewRoot.invalidate();
if (mOpened != null)
mOpened.set(false);
}
public void reOpen() {
reOpen(mUri, mDisplayName, false);
}
protected void startPlayer() {
if (isInitialized() && mScreenReceiver.screenOn
&& !vPlayer.isBuffering()&&isload) {
Log.i("VideoActivity#startPlayer");
if (!vPlayer.isPlaying()) {
vPlayer.start();
if(mDanmakuView.isPaused())
mDanmakuView.resume();
else
mDanmakuView.start();
}
}
}
protected void stopPlayer() {
if (isInitialized()) {
vPlayer.stop();
if(mDanmakuView != null){
if(mDanmakuView.isPrepared()&&mDanmakuView.isShown());
mDanmakuView.pause();
}
}
}
private void setBatteryLevel() {
if (mMediaController != null)
mMediaController.setBatteryLevel(mBatteryLevel);
}
private class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = scale > 0 ? level * 100 / scale : 0;
if (percent > 100)
percent = 100;
mBatteryLevel = String.valueOf(percent) + "%";
setBatteryLevel();
}
}
private class UserPresentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isRootActivity()) {
startPlayer();
}
}
}
private boolean isRootActivity() {
return ApplicationUtils.isTopActivity(getApplicationContext(),
getClass().getName());
// ActivityManager activity = (ActivityManager)
// getSystemService(Context.ACTIVITY_SERVICE);
// return
// activity.getRunningTasks(1).get(0).topActivity.flattenToString().endsWith("io.vov.vitamio.activity.VideoActivity");
}
public class HeadsetPlugReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.hasExtra("state")) {
int state = intent.getIntExtra("state", -1);
if (state == 0) {
mHeadsetPlaying = isPlaying();
stopPlayer();
} else if (state == 1) {
if (mHeadsetPlaying)
startPlayer();
}
}
};
}
private class ScreenReceiver extends BroadcastReceiver {
private boolean screenOn = true;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOn = false;
stopPlayer();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOn = true;
}
}
}
private void loadVPlayerPrefs() {
if (!isInitialized())
return;
vPlayer.setBuffer(VP.DEFAULT_BUF_SIZE);
vPlayer.setVideoQuality(VP.DEFAULT_VIDEO_QUALITY);
vPlayer.setDeinterlace(VP.DEFAULT_DEINTERLACE);
vPlayer.setVolume(VP.DEFAULT_STEREO_VOLUME, VP.DEFAULT_STEREO_VOLUME);
vPlayer.setSubEncoding(VP.DEFAULT_SUB_ENCODING);
MarginLayoutParams lp = (MarginLayoutParams) mSubtitleContainer
.getLayoutParams();
lp.bottomMargin = (int) VP.DEFAULT_SUB_POS;
mSubtitleContainer.setLayoutParams(lp);
vPlayer.setSubShown(mSubShown);
setTextViewStyle(mSubtitleText);
if (!TextUtils.isEmpty(mSubPath))
vPlayer.setSubPath(mSubPath);
if (mVideoView != null && isInitialized())
setVideoLayout();
}
private void setTextViewStyle(OutlineTextView v) {
v.setTextColor(VP.DEFAULT_SUB_COLOR);
v.setTypeface(VP.getTypeface(VP.DEFAULT_TYPEFACE_INT),
VP.DEFAULT_SUB_STYLE);
v.setShadowLayer(VP.DEFAULT_SUB_SHADOWRADIUS, 0, 0,
VP.DEFAULT_SUB_SHADOWCOLOR);
}
private boolean isInitialized() {
return (mCreated && vPlayer != null && vPlayer.isInitialized());
}
private Handler mSubHandler = new Handler() {
Bundle data;
String text;
byte[] pixels;
int width = 0, height = 0;
Bitmap bm = null;
int oldType = SUBTITLE_TEXT;
@Override
public void handleMessage(Message msg) {
data = msg.getData();
switch (msg.what) {
case SUBTITLE_TEXT:
if (oldType != SUBTITLE_TEXT) {
mSubtitleImage.setVisibility(View.GONE);
mSubtitleText.setVisibility(View.VISIBLE);
oldType = SUBTITLE_TEXT;
}
text = data.getString(VP.SUB_TEXT_KEY);
mSubtitleText.setText(text == null ? "" : text.trim());
break;
case SUBTITLE_BITMAP:
if (oldType != SUBTITLE_BITMAP) {
mSubtitleText.setVisibility(View.GONE);
mSubtitleImage.setVisibility(View.VISIBLE);
oldType = SUBTITLE_BITMAP;
}
pixels = data.getByteArray(VP.SUB_PIXELS_KEY);
if (bm == null || width != data.getInt(VP.SUB_WIDTH_KEY)
|| height != data.getInt(VP.SUB_HEIGHT_KEY)) {
width = data.getInt(VP.SUB_WIDTH_KEY);
height = data.getInt(VP.SUB_HEIGHT_KEY);
bm = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
}
if (pixels != null)
bm.copyPixelsFromBuffer(ByteBuffer.wrap(pixels));
mSubtitleImage.setImageBitmap(bm);
break;
}
}
};
private AtomicBoolean mOpened = new AtomicBoolean(Boolean.FALSE);
private boolean mSurfaceCreated = false;
private boolean mServiceConnected = false;
private Object mOpenLock = new Object();
private static final int OPEN_FILE = 0;
private static final int OPEN_START = 1;
private static final int OPEN_SUCCESS = 2;
private static final int OPEN_FAILED = 3;
private static final int HW_FAILED = 4;
private static final int LOAD_PREFS = 5;
private static final int BUFFER_START = 11;
private static final int BUFFER_PROGRESS = 12;
private static final int BUFFER_COMPLETE = 13;
private static final int CLOSE_START = 21;
private static final int CLOSE_COMPLETE = 22;
private static final int SUBTITLE_TEXT = 0;
private static final int SUBTITLE_BITMAP = 1;
private Handler vPlayerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case OPEN_FILE:
synchronized (mOpenLock) {
if (!mOpened.get() && vPlayer != null) {
mOpened.set(true);
vPlayer.setVPlayerListener(vPlayerListener);
if (vPlayer.isInitialized())
mUri = vPlayer.getUri();
if (mVideoView != null)
vPlayer.setDisplay(mVideoView.getHolder());
if (mUri != null)
vPlayer.initialize(mUri, mDisplayName, mSaveUri,
getStartPosition(), vPlayerListener,
mParentId, mIsHWCodec);
}
}
break;
case OPEN_START:
mVideoLoadingText.setText(R.string.video_layout_loading);
setVideoLoadingLayoutVisibility(View.VISIBLE);
break;
case OPEN_SUCCESS:
loadVPlayerPrefs();
setVideoLoadingLayoutVisibility(View.GONE);
setVideoLayout();
vPlayer.start();
if(mDanmakuView.isPaused())
mDanmakuView.resume();
else
mDanmakuView.start();
attachMediaController();
break;
case OPEN_FAILED:
resultFinish(RESULT_FAILED);
break;
case BUFFER_START:
setVideoLoadingLayoutVisibility(View.VISIBLE);
vPlayerHandler.sendEmptyMessageDelayed(BUFFER_PROGRESS, 1000);
break;
case BUFFER_PROGRESS:
if (vPlayer.getBufferProgress() >= 100) {
setVideoLoadingLayoutVisibility(View.GONE);
} else {
mVideoLoadingText.setText(getString(
R.string.video_layout_buffering_progress,
vPlayer.getBufferProgress()));
vPlayerHandler.sendEmptyMessageDelayed(BUFFER_PROGRESS,
1000);
stopPlayer();
}
break;
case BUFFER_COMPLETE:
setVideoLoadingLayoutVisibility(View.GONE);
vPlayerHandler.removeMessages(BUFFER_PROGRESS);
break;
case CLOSE_START:
mVideoLoadingText.setText(R.string.closing_file);
setVideoLoadingLayoutVisibility(View.VISIBLE);
break;
case CLOSE_COMPLETE:
mCloseComplete = true;
break;
case HW_FAILED:
if (mVideoView != null) {
mVideoView.setVisibility(View.GONE);
mVideoView.setVisibility(View.VISIBLE);
mVideoView.initialize(BiliVideoViewActivity.this,
BiliVideoViewActivity.this, false);
}
break;
case LOAD_PREFS:
loadVPlayerPrefs();
break;
}
}
};
private void setVideoLoadingLayoutVisibility(int visibility) {
if (mVideoLoadingLayout != null) {
// if (visibility == View.VISIBLE)
// mLoadingProgressView.startAnimation(mLoadingAnimation);
mVideoLoadingLayout.setVisibility(visibility);
}
}
private PlayerService.VPlayerListener vPlayerListener = new PlayerService.VPlayerListener() {
@Override
public void onHWRenderFailed() {
if (Build.VERSION.SDK_INT < 11 && mIsHWCodec) {
vPlayerHandler.sendEmptyMessage(HW_FAILED);
vPlayerHandler.sendEmptyMessageDelayed(HW_FAILED, 200);
}
}
@Override
public void onSubChanged(String sub) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString(VP.SUB_TEXT_KEY, sub);
msg.setData(b);
msg.what = SUBTITLE_TEXT;
mSubHandler.sendMessage(msg);
}
@Override
public void onSubChanged(byte[] pixels, int width, int height) {
Message msg = new Message();
Bundle b = new Bundle();
b.putByteArray(VP.SUB_PIXELS_KEY, pixels);
b.putInt(VP.SUB_WIDTH_KEY, width);
b.putInt(VP.SUB_HEIGHT_KEY, height);
msg.setData(b);
msg.what = SUBTITLE_BITMAP;
mSubHandler.sendMessage(msg);
}
@Override
public void onOpenStart() {
vPlayerHandler.sendEmptyMessage(OPEN_START);
}
@Override
public void onOpenSuccess() {
vPlayerHandler.sendEmptyMessage(OPEN_SUCCESS);
}
@Override
public void onOpenFailed() {
vPlayerHandler.sendEmptyMessage(OPEN_FAILED);
}
@Override
public void onBufferStart() {
//if(isfirst){}
vPlayerHandler.sendEmptyMessage(BUFFER_START);
stopPlayer();
}
@Override
public void onBufferComplete() {
Log.i("VideoActivity#onBufferComplete " + vPlayer.needResume());
if(isfirst){
startVideo.setVisibility(View.GONE);
anim.stop();
isfirst = false;
}
vPlayerHandler.sendEmptyMessage(BUFFER_COMPLETE);
if (vPlayer != null && !vPlayer.needResume())
startPlayer();
}
@Override
public void onPlaybackComplete() {
mEnd = true;
if (mLoopCount == 0 || mLoopCount-- > 1) {
vPlayer.start();
if(mDanmakuView.isPaused())
mDanmakuView.resume();
else
mDanmakuView.start();
vPlayer.seekTo(0);
} else {
resultFinish(RESULT_OK);
}
}
@Override
public void onCloseStart() {
vPlayerHandler.sendEmptyMessage(CLOSE_START);
}
@Override
public void onCloseComplete() {
vPlayerHandler.sendEmptyMessage(CLOSE_COMPLETE);
}
@Override
public void onVideoSizeChanged(int width, int height) {
if (mVideoView != null) {
setVideoLayout();
}
}
@Override
public void onDownloadRateChanged(int kbPerSec) {
if (!MediaUtils.isNative(mUri.toString())
&& mMediaController != null) {
mMediaController.setDownloadRate(String.format("%dKB/s",
kbPerSec));
}
}
};
private int mVideoMode = VideoView.VIDEO_LAYOUT_SCALE;
private void setVideoLayout() {
mVideoView.setVideoLayout(mVideoMode, VP.DEFAULT_ASPECT_RATIO,
vPlayer.getVideoWidth(), vPlayer.getVideoHeight(),
vPlayer.getVideoAspectRatio());
}
private void savePosition() {
if (vPlayer != null && mUri != null) {
PreferenceUtils.put(
mUri.toString(),
StringUtils.generateTime((int) (0.5 + vPlayer
.getCurrentPosition()))
+ " / "
+ StringUtils.generateTime(vPlayer.getDuration()));
if (mEnd)
PreferenceUtils
.put(mUri + VP.SESSION_LAST_POSITION_SUFIX, 1.0f);
else
PreferenceUtils
.put(mUri + VP.SESSION_LAST_POSITION_SUFIX,
(float) (vPlayer.getCurrentPosition() / (double) vPlayer
.getDuration()));
}
}
private float getStartPosition() {
if (mFromStart)
return 1.1f;
if (mStartPos <= 0.0f || mStartPos >= 1.0f)
return PreferenceUtils.getFloat(mUri
+ VP.SESSION_LAST_POSITION_SUFIX, 7.7f);
return mStartPos;
}
@Override
public int getBufferPercentage() {
if (isInitialized())
return (int) (vPlayer.getBufferProgress() * 100);
return 0;
}
@Override
public long getCurrentPosition() {
if (isInitialized())
return vPlayer.getCurrentPosition();
return (long) (getStartPosition() * vPlayer.getDuration());
}
@Override
public long getDuration() {
if (isInitialized())
return vPlayer.getDuration();
return 0;
}
@Override
public boolean isPlaying() {
if (isInitialized())
return vPlayer.isPlaying();
return false;
}
@Override
public void pause() {
if (isInitialized())
vPlayer.stop();
mDanmakuView.pause();
}
@Override
public void seekTo(long arg0) {
if (isInitialized())
vPlayer.seekTo((float) ((double) arg0 / vPlayer.getDuration()));
mDanmakuView.seekTo(arg0);
mDanmakuView.pause();
}
@Override
public void start() {
if (isInitialized())
vPlayer.start();
if(mDanmakuView.isPaused())
mDanmakuView.resume();
else
mDanmakuView.start();
}
@Override
public void previous() {
}
@Override
public void next() {
}
private static final int VIDEO_MAXIMUM_HEIGHT = 2048;
private static final int VIDEO_MAXIMUM_WIDTH = 2048;
@Override
public float scale(float scaleFactor) {
float userRatio = VP.DEFAULT_ASPECT_RATIO;
int videoWidth = vPlayer.getVideoWidth();
int videoHeight = vPlayer.getVideoHeight();
float videoRatio = vPlayer.getVideoAspectRatio();
float currentRatio = mVideoView.mVideoHeight / (float) videoHeight;
currentRatio += (scaleFactor - 1);
if (videoWidth * currentRatio >= VIDEO_MAXIMUM_WIDTH)
currentRatio = VIDEO_MAXIMUM_WIDTH / (float) videoWidth;
if (videoHeight * currentRatio >= VIDEO_MAXIMUM_HEIGHT)
currentRatio = VIDEO_MAXIMUM_HEIGHT / (float) videoHeight;
if (currentRatio < 0.5f)
currentRatio = 0.5f;
mVideoView.mVideoHeight = (int) (videoHeight * currentRatio);
mVideoView.setVideoLayout(mVideoMode, userRatio, videoWidth,
videoHeight, videoRatio);
return currentRatio;
}
@SuppressLint("SimpleDateFormat")
@Override
public void snapshot() {
if (!com.cjj.bb.utils.FileUtils.sdAvailable()) {
ToastUtils.showToast(R.string.file_explorer_sdcard_not_available);
} else {
Uri imgUri = null;
Bitmap bitmap = vPlayer.getCurrentFrame();
if (bitmap != null) {
File screenshotsDirectory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ VP.SNAP_SHOT_PATH);
if (!screenshotsDirectory.exists()) {
screenshotsDirectory.mkdirs();
}
File savePath = new File(
screenshotsDirectory.getPath()
+ "/"
+ new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date()) + ".jpg");
if (ImageUtils.saveBitmap(savePath.getPath(), bitmap)) {
imgUri = Uri.fromFile(savePath);
}
}
if (imgUri != null) {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
imgUri));
ToastUtils.showLongToast(getString(
R.string.video_screenshot_save_in, imgUri.getPath()));
} else {
ToastUtils.showToast(R.string.video_screenshot_failed);
}
}
}
@Override
public void toggleVideoMode(int mode) {
mVideoMode = mode;
setVideoLayout();
}
@Override
public void stop() {
onBackPressed();
}
@Override
public long goForward() {
return 0;
}
@Override
public long goBack() {
return 0;
}
@Override
public void removeLoadingView() {
mVideoLoadingLayout.setVisibility(View.GONE);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
Log.i("onSurfaceCreated");
mSurfaceCreated = true;
if (mServiceConnected)
vPlayerHandler.sendEmptyMessage(OPEN_FILE);
if (vPlayer != null)
vPlayer.setDisplay(holder);
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (vPlayer != null) {
setVideoLayout();
}
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
Log.i("onSurfaceDestroyed");
if (vPlayer != null && vPlayer.isInitialized()) {
if (vPlayer.isPlaying()) {
vPlayer.stop();
vPlayer.setState(PlayerService.STATE_NEED_RESUME);
}
vPlayer.releaseSurface();
if (vPlayer.needResume()){
vPlayer.start();
if(mDanmakuView.isPaused())
mDanmakuView.resume();
else
mDanmakuView.start();
}
}
}
@Override
public void setDanmakushow(boolean isShow) {
// TODO Auto-generated method stub
if(mDanmakuView != null){
if(isShow){
mDanmakuView.show();
}else{
mDanmakuView.hide();
}
}
}
private class VideoViewInitTask extends AsyncTask {
@Override
protected Integer doInBackground(String... arg0) {
// TODO Auto-generated method stub
Log.d("TAG", "开始解析视频地址");
try {
JSONObject videopathjson = new JSONObject(HttpUtil.getHtmlString("http://www.bilibili.com/m/html5?aid=" + av + "&page=" + page));
Log.d("QAQ--->","===>"+videopathjson.getString("src").toString());
danmakuPath = videopathjson.getString("cid").toString();
mUri = Uri.parse(videopathjson.getString("src").toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("TAG", "开始加载弹幕");
mParser = createParser(danmakuPath);
return null;
}
@Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.d("TAG", "加载弹幕成功");
// if (mDanmakuView != null) {
// mDanmakuView.prepare(mParser);
// mDanmakuView.showFPS(true);
// mDanmakuView.enableDanmakuDrawingCache(true);
// isload = true;
// //startPlayer();
//
// }
if(mParser != null){
mDanmakuView.prepare(mParser);
mDanmakuView.showFPS(false);
mDanmakuView.enableDanmakuDrawingCache(false);
}else{
startText = startText + "【失败】\n视频缓冲中...";
startVideoInfo.setText(startText);
}
// mDanmakuView.prepare(mParser);
// mDanmakuView.showFPS(true);
// mDanmakuView.enableDanmakuDrawingCache(true);
isload = true;
Intent serviceIntent = new Intent(getApplicationContext(), PlayerService.class);
serviceIntent.putExtra("isHWCodec", mIsHWCodec);
bindService(serviceIntent, vPlayerServiceConnection,Context.BIND_AUTO_CREATE);
startText = startText + "【完成】\n视频缓冲中...";
startVideoInfo.setText(startText);
}
}
/*退出的间隔时间 */
private static final long EXIT_INTERVAL_TIME = 2000;
private long touchTime = 0;
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
) {
long currentTime = System.currentTimeMillis();
if ((currentTime - touchTime) >= EXIT_INTERVAL_TIME) {
Toast.makeText(BiliVideoViewActivity.this, "再按一下退出喵(。・ω・。)~", Toast.LENGTH_SHORT).show();
touchTime = currentTime;
} else {
finish();
if(mDanmakuView!=null)
mDanmakuView.release();
}
return false;
} else {
return true;
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/BiliWebviewActivity.java
================================================
package com.cjj.bb.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.ProgressBar;
import com.cjj.bb.R;
public class BiliWebviewActivity extends Activity{
private ProgressBar progressBar; // 进度条
private ImageView reLoadImageView; // 重新加载的图片
private WebView biliWebView;//网页控件
private ImageView backBtn; // 回退按钮
private ImageView commentBtn; // 评论按钮
public static String url;
private String filename;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);// 无标题
super.onCreate(savedInstanceState);
setContentView(R.layout.bili_webview);
init();
initComponent();
biliWebView.getSettings().setJavaScriptEnabled(true);
biliWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
});
biliWebView.loadUrl(url);
}
// 初始化
private void init() {
url = getIntent().getExtras().getString("bannerLink");
filename = url.substring(url.lastIndexOf("/") + 1);
System.out.println("filename--->" + filename);
}
// 初始化组件
private void initComponent() {
biliWebView = (WebView)findViewById(R.id.BiliWebView);
progressBar = (ProgressBar) findViewById(R.id.blogContentPro);
reLoadImageView = (ImageView) findViewById(R.id.reLoadImage);
reLoadImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
reLoadImageView.setVisibility(View.INVISIBLE);
progressBar.setVisibility(View.VISIBLE);
}
});
backBtn = (ImageView) findViewById(R.id.backBtn);
backBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
finish();
}
});
commentBtn = (ImageView) findViewById(R.id.comment);
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/DonghuaActivity.java
================================================
package com.cjj.bb.activity;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.adapter.BankumiTabAdapter;
import com.cjj.bb.adapter.DianyingTabAdapter;
import com.cjj.bb.adapter.DonghuaTabAdapter;
import com.cjj.bb.adapter.KejiTabAdapter;
import com.cjj.bb.adapter.MusicTabAdapter;
import com.cjj.bb.adapter.RankAdapter;
import com.cjj.bb.adapter.YouxiTabAdapter;
import com.cjj.bb.adapter.YuleTabAdapter;
import viewpagerindicator.PageIndicator;
/**
* 动画界面
*
* @author wwj_748
* @date 2014/8/9
*/
public class DonghuaActivity extends ActionBarActivity {
public int mAreaType;
private View backButton;
private TextView titleText;
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE); // 无标题
super.onCreate(savedInstanceState);
setContentView(R.layout.donghua_tab);
backButton = findViewById(R.id.logobutton);
titleText = (TextView) findViewById(R.id.textViewTitle);
FragmentPagerAdapter adapter = null;
mAreaType = getIntent().getIntExtra("AreaType", 1);
Log.d("QAQ","----->"+mAreaType+titleText.getText());
switch (mAreaType){
case 1:
titleText.setText("番剧");
adapter = new BankumiTabAdapter(getSupportFragmentManager());
break;
case 2:
titleText.setText("动画");
adapter = new DonghuaTabAdapter(getSupportFragmentManager());
break;
case 3:
titleText.setText("音乐");
adapter = new MusicTabAdapter(getSupportFragmentManager());
break;
case 4:
titleText.setText("游戏");
adapter = new YouxiTabAdapter(getSupportFragmentManager());
break;
case 5:
titleText.setText("科学·技术");
adapter = new KejiTabAdapter(getSupportFragmentManager());
break;
case 6:
titleText.setText("娱乐");
adapter = new YuleTabAdapter(getSupportFragmentManager());
break;
case 7:
titleText.setText("电影");
adapter = new DianyingTabAdapter(getSupportFragmentManager());
break;
case 8:
titleText.setText("排行榜");
adapter = new RankAdapter(getSupportFragmentManager());
break;
default:
titleText.setText("电影");
adapter = new DianyingTabAdapter(getSupportFragmentManager());
break;
}
// 视图切换器
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setOffscreenPageLimit(1);
pager.setAdapter(adapter);
// 页面指示器
PageIndicator indicator = (PageIndicator) findViewById(R.id.indicator);
indicator.setViewPager(pager);
backButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
getSupportActionBar().hide();
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/MainActivity.java
================================================
package com.cjj.bb.activity;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.Window;
import com.cjj.bb.R;
import com.cjj.bb.adapter.MainTabAdapter;
import viewpagerindicator.TabPageIndicator;
import viewpagerindicator.TitlePageIndicator;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE); // 无标题
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentPagerAdapter adapter = new MainTabAdapter(getSupportFragmentManager());
// 视图切换器
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setOffscreenPageLimit(3);
pager.setAdapter(adapter);
// // 页面指示器
// PageIndicator indicator = (PageIndicator) findViewById(R.id.indicator);
// indicator.setViewPager(pager);
TitlePageIndicator indicator = (TitlePageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(pager);
indicator.setCurrentItem(1);
/*if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new SubareaFragment())
.commit();
}*/
// AdManager.getInstance(this).init("118250e2aa39dea9", "bc5f4490f33da8e6", false);
// SpotManager.getInstance(this).loadSpotAds();
// SpotManager.getInstance(this).setAnimationType(SpotManager.ANIM_ADVANCE);
// SpotManager.getInstance(this).setSpotOrientation(SpotManager.ORIENTATION_PORTRAIT);
// AdManager.getInstance(this).setUserDataCollect(true);
getSupportActionBar().hide();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* On key up.
*
* @param keyCode
* the key code
* @param event
* the event
* @return true, if successful
*/
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// show_existDialog();
// 退出程序
finish();
return false;
} else {
return true;
}
}
// private void show_existDialog() {
// // 弹出退出对话框
// Builder dialog = new Builder(MainActivity.this)
// .setMessage("您确定要退出吗?")
// .setPositiveButton("确定", new DialogInterface.OnClickListener() {
//
// @Override
// public void onClick(DialogInterface arg0, int arg1) {
// // 退出程序
// finish();
// }
// })
// .setNegativeButton("支持我", new DialogInterface.OnClickListener() {
//
// @Override
// public void onClick(DialogInterface arg0, int arg1) {
// SpotManager.getInstance(MainActivity.this).showSpotAds(
// MainActivity.this, new SpotDialogListener() {
// @Override
// public void onShowSuccess() {
// Log.i("YoumiAdDemo", "展示成功");
// }
//
// @Override
// public void onShowFailed() {
// Log.i("YoumiAdDemo", "展示失败");
// }
//
// @Override
// public void onSpotClosed() {
// Log.i("YoumiAdDemo", "展示关闭");
// }
//
// });
// }
// });
// dialog.show();
// }
//
public void onBackPressed() {
// // 如果有需要,可以点击后退关闭插播广告。
// if (!SpotManager.getInstance(this).disMiss()) {
// // 弹出退出窗口,可以使用自定义退屏弹出和回退动画,参照demo,若不使用动画,传入-1
// super.onBackPressed();
// }
}
@Override
protected void onStop() {
// 如果不调用此方法,则按home键的时候会出现图标无法显示的情况。
// SpotManager.getInstance(this).onStop();
super.onStop();
}
@Override
protected void onDestroy() {
// SpotManager.getInstance(this).onDestroy();
super.onDestroy();
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/TVActivity.java
================================================
package com.cjj.bb.activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.fragment.OnlineFragment;
public class TVActivity extends ActionBarActivity{
private View backButton;
private TextView titleText;
private OnlineFragment online = new OnlineFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE); // 无标题
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_info);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, online)
.commit();
}
backButton = findViewById(R.id.logobutton);
titleText = (TextView) findViewById(R.id.textViewTitle);
titleText.setText("网络电视");
backButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
getSupportActionBar().hide();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onBackPressed() {
if (online.onBackPressed())
return;
else
super.onBackPressed();
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/VideoInfoActivity.java
================================================
package com.cjj.bb.activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.fragment.VideoInfoFragment;
public class VideoInfoActivity extends ActionBarActivity{
private View backButton;
private TextView titleText;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE); // 无标题
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_info);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new VideoInfoFragment())
.commit();
}
backButton = findViewById(R.id.logobutton);
titleText = (TextView) findViewById(R.id.textViewTitle);
titleText.setText("视频详情");
backButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
getSupportActionBar().hide();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/activity/VideoViewActivity.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.activity;
import io.vov.vitamio.utils.FileUtils;
import io.vov.vitamio.utils.Log;
import io.vov.vitamio.widget.OutlineTextView;
import java.io.File;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.utils.DeviceUtils;
import com.cjj.bb.utils.ImageUtils;
import com.cjj.bb.utils.IntentHelper;
import com.cjj.bb.utils.MediaUtils;
import com.cjj.bb.utils.PreferenceUtils;
import com.cjj.bb.utils.StringUtils;
import com.cjj.bb.utils.ToastUtils;
import com.cjj.bb.view.ApplicationUtils;
import com.cjj.bb.view.MediaController;
import com.cjj.bb.view.PlayerService;
import com.cjj.bb.view.VP;
import com.cjj.bb.view.VideoView;
@SuppressLint("HandlerLeak")
public class VideoViewActivity extends Activity implements
MediaController.MediaPlayerControl, VideoView.SurfaceCallback {
public static final int RESULT_FAILED = -7;
private static final IntentFilter USER_PRESENT_FILTER = new IntentFilter(
Intent.ACTION_USER_PRESENT);
private static final IntentFilter SCREEN_FILTER = new IntentFilter(
Intent.ACTION_SCREEN_ON);
private static final IntentFilter HEADSET_FILTER = new IntentFilter(
Intent.ACTION_HEADSET_PLUG);
private static final IntentFilter BATTERY_FILTER = new IntentFilter(
Intent.ACTION_BATTERY_CHANGED);
private boolean mCreated = false;
private boolean mNeedLock;
private String mDisplayName;
private String mBatteryLevel;
private boolean mFromStart;
private int mLoopCount;
private boolean mSaveUri;
private int mParentId;
private float mStartPos;
private boolean mEnd = false;
private String mSubPath;
private boolean mSubShown;
private View mViewRoot;
private VideoView mVideoView;
private View mVideoLoadingLayout;
private TextView mVideoLoadingText;
private View mSubtitleContainer;
private OutlineTextView mSubtitleText;
private ImageView mSubtitleImage;
private Uri mUri;
private ScreenReceiver mScreenReceiver;
private HeadsetPlugReceiver mHeadsetPlugReceiver;
private UserPresentReceiver mUserPresentReceiver;
private BatteryReceiver mBatteryReceiver;
private boolean mReceiverRegistered = false;
private boolean mHeadsetPlaying = false;
private boolean mCloseComplete = false;
private boolean mIsHWCodec = false;
private MediaController mMediaController;
private PlayerService vPlayer;
private ServiceConnection vPlayerServiceConnection;
// private Animation mLoadingAnimation;
// private View mLoadingProgressView;
static {
SCREEN_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
return;
vPlayerServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
vPlayer = ((PlayerService.LocalBinder) service).getService();
mServiceConnected = true;
if (mSurfaceCreated)
vPlayerHandler.sendEmptyMessage(OPEN_FILE);
}
@Override
public void onServiceDisconnected(ComponentName name) {
vPlayer = null;
mServiceConnected = false;
}
};
setVolumeControlStream(AudioManager.STREAM_MUSIC);
parseIntent(getIntent());
loadView(R.layout.activity_video);
manageReceivers();
mCreated = true;
}
private void attachMediaController() {
if (mMediaController != null) {
mNeedLock = mMediaController.isLocked();
mMediaController.release();
}
mMediaController = new MediaController(this, mNeedLock);
mMediaController.setMediaPlayer(this);
mMediaController.setAnchorView(mVideoView.getRootView());
mMediaController.setDanmakuVisible(false);
setFileName();
setBatteryLevel();
}
@Override
public void onStart() {
super.onStart();
if (!mCreated)
return;
Intent serviceIntent = new Intent(this, PlayerService.class);
serviceIntent.putExtra("isHWCodec", mIsHWCodec);
bindService(serviceIntent, vPlayerServiceConnection,
Context.BIND_AUTO_CREATE);
}
@Override
public void onResume() {
super.onResume();
if (!mCreated)
return;
if (isInitialized()) {
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
if (!keyguardManager.inKeyguardRestrictedInputMode()) {
startPlayer();
}
} else {
if (mCloseComplete) {
reOpen();
}
}
}
@Override
public void onPause() {
super.onPause();
if (!mCreated)
return;
if (isInitialized()) {
savePosition();
if (vPlayer != null && vPlayer.isPlaying()) {
stopPlayer();
}
}
}
@Override
public void onStop() {
super.onStop();
if (!mCreated)
return;
if (isInitialized()) {
vPlayer.releaseSurface();
}
if (mServiceConnected) {
unbindService(vPlayerServiceConnection);
mServiceConnected = false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (!mCreated)
return;
manageReceivers();
if (isInitialized() && !vPlayer.isPlaying())
release();
if (mMediaController != null)
mMediaController.release();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (isInitialized()) {
setVideoLayout();
attachMediaController();
}
super.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// http://code.google.com/p/android/issues/detail?id=19917
outState.putString("WORKAROUND_FOR_BUG_19917_KEY",
"WORKAROUND_FOR_BUG_19917_VALUE");
super.onSaveInstanceState(outState);
}
@Override
public void showMenu() {
}
private void loadView(int id) {
setContentView(id);
getWindow().setBackgroundDrawable(null);
mViewRoot = findViewById(R.id.video_root);
mVideoView = (VideoView) findViewById(R.id.video);
mVideoView.initialize(this, this, mIsHWCodec);
mSubtitleContainer = findViewById(R.id.subtitle_container);
mSubtitleText = (OutlineTextView) findViewById(R.id.subtitle_text);
mSubtitleImage = (ImageView) findViewById(R.id.subtitle_image);
mVideoLoadingText = (TextView) findViewById(R.id.video_loading_text);
mVideoLoadingLayout = findViewById(R.id.video_loading);
// mLoadingProgressView =
// mVideoLoadingLayout.findViewById(R.id.video_loading_progress);
// mLoadingAnimation = AnimationUtils.loadAnimation(VideoActivity.this,
// R.anim.loading_rotate);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
private void parseIntent(Intent i) {
Uri dat = IntentHelper.getIntentUri(i);
if (dat == null)
resultFinish(RESULT_FAILED);
String datString = dat.toString();
if (!datString.equals(dat.toString()))
dat = Uri.parse(datString);
mUri = dat;
mNeedLock = i.getBooleanExtra("lockScreen", false);
mDisplayName = i.getStringExtra("displayName");
mFromStart = i.getBooleanExtra("fromStart", false);
mSaveUri = i.getBooleanExtra("saveUri", true);
mStartPos = i.getFloatExtra("startPosition", -1.0f);
mLoopCount = i.getIntExtra("loopCount", 1);
mParentId = i.getIntExtra("parentId", 0);
mSubPath = i.getStringExtra("subPath");
mSubShown = i.getBooleanExtra("subShown", true);
mIsHWCodec = i.getBooleanExtra("hwCodec", false);
Log.i("L: %b, N: %s, S: %b, P: %f, LP: %d", mNeedLock, mDisplayName,
mFromStart, mStartPos, mLoopCount);
}
private void manageReceivers() {
if (!mReceiverRegistered) {
mScreenReceiver = new ScreenReceiver();
registerReceiver(mScreenReceiver, SCREEN_FILTER);
mUserPresentReceiver = new UserPresentReceiver();
registerReceiver(mUserPresentReceiver, USER_PRESENT_FILTER);
mBatteryReceiver = new BatteryReceiver();
registerReceiver(mBatteryReceiver, BATTERY_FILTER);
mHeadsetPlugReceiver = new HeadsetPlugReceiver();
registerReceiver(mHeadsetPlugReceiver, HEADSET_FILTER);
mReceiverRegistered = true;
} else {
try {
if (mScreenReceiver != null)
unregisterReceiver(mScreenReceiver);
if (mUserPresentReceiver != null)
unregisterReceiver(mUserPresentReceiver);
if (mHeadsetPlugReceiver != null)
unregisterReceiver(mHeadsetPlugReceiver);
if (mBatteryReceiver != null)
unregisterReceiver(mBatteryReceiver);
} catch (IllegalArgumentException e) {
}
mReceiverRegistered = false;
}
}
private void setFileName() {
if (mUri != null) {
String name = null;
if (mUri.getScheme() == null || mUri.getScheme().equals("file"))
name = FileUtils.getName(mUri.toString());
else
name = mUri.getLastPathSegment();
if (name == null)
name = "null";
if (mDisplayName == null)
mDisplayName = name;
mMediaController.setFileName(mDisplayName);
}
}
private void applyResult(int resultCode) {
vPlayerHandler.removeMessages(BUFFER_PROGRESS);
Intent i = new Intent();
i.putExtra("filePath", mUri.toString());
if (isInitialized()) {
i.putExtra("position", (double) vPlayer.getCurrentPosition()
/ vPlayer.getDuration());
i.putExtra("duration", vPlayer.getDuration());
savePosition();
}
switch (resultCode) {
case RESULT_FAILED:
ToastUtils.showLongToast(R.string.video_cannot_play);
break;
case RESULT_CANCELED:
case RESULT_OK:
break;
}
setResult(resultCode, i);
}
private void resultFinish(int resultCode) {
applyResult(resultCode);
if (DeviceUtils.hasICS() && resultCode != RESULT_FAILED) {
android.os.Process.killProcess(android.os.Process.myPid());
} else {
finish();
}
}
private void release() {
if (vPlayer != null) {
if (DeviceUtils.hasICS()) {
android.os.Process.killProcess(android.os.Process.myPid());
} else {
vPlayer.release();
vPlayer.releaseContext();
}
}
}
private void reOpen(Uri path, String name, boolean fromStart) {
if (isInitialized()) {
savePosition();
vPlayer.release();
vPlayer.releaseContext();
}
Intent i = getIntent();
if (mMediaController != null)
i.putExtra("lockScreen", mMediaController.isLocked());
i.putExtra("startPosition", PreferenceUtils.getFloat(mUri
+ VP.SESSION_LAST_POSITION_SUFIX, 7.7f));
i.putExtra("fromStart", fromStart);
i.putExtra("displayName", name);
i.setData(path);
parseIntent(i);
mUri = path;
if (mViewRoot != null)
mViewRoot.invalidate();
if (mOpened != null)
mOpened.set(false);
}
public void reOpen() {
reOpen(mUri, mDisplayName, false);
}
protected void startPlayer() {
if (isInitialized() && mScreenReceiver.screenOn
&& !vPlayer.isBuffering()) {
Log.i("VideoActivity#startPlayer");
if (!vPlayer.isPlaying()) {
vPlayer.start();
}
}
}
protected void stopPlayer() {
if (isInitialized()) {
vPlayer.stop();
}
}
private void setBatteryLevel() {
if (mMediaController != null)
mMediaController.setBatteryLevel(mBatteryLevel);
}
private class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = scale > 0 ? level * 100 / scale : 0;
if (percent > 100)
percent = 100;
mBatteryLevel = String.valueOf(percent) + "%";
setBatteryLevel();
}
}
private class UserPresentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isRootActivity()) {
startPlayer();
}
}
}
private boolean isRootActivity() {
return ApplicationUtils.isTopActivity(getApplicationContext(),
getClass().getName());
// ActivityManager activity = (ActivityManager)
// getSystemService(Context.ACTIVITY_SERVICE);
// return
// activity.getRunningTasks(1).get(0).topActivity.flattenToString().endsWith("io.vov.vitamio.activity.VideoActivity");
}
public class HeadsetPlugReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.hasExtra("state")) {
int state = intent.getIntExtra("state", -1);
if (state == 0) {
mHeadsetPlaying = isPlaying();
stopPlayer();
} else if (state == 1) {
if (mHeadsetPlaying)
startPlayer();
}
}
};
}
private class ScreenReceiver extends BroadcastReceiver {
private boolean screenOn = true;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOn = false;
stopPlayer();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOn = true;
}
}
}
private void loadVPlayerPrefs() {
if (!isInitialized())
return;
vPlayer.setBuffer(VP.DEFAULT_BUF_SIZE);
vPlayer.setVideoQuality(VP.DEFAULT_VIDEO_QUALITY);
vPlayer.setDeinterlace(VP.DEFAULT_DEINTERLACE);
vPlayer.setVolume(VP.DEFAULT_STEREO_VOLUME, VP.DEFAULT_STEREO_VOLUME);
vPlayer.setSubEncoding(VP.DEFAULT_SUB_ENCODING);
MarginLayoutParams lp = (MarginLayoutParams) mSubtitleContainer
.getLayoutParams();
lp.bottomMargin = (int) VP.DEFAULT_SUB_POS;
mSubtitleContainer.setLayoutParams(lp);
vPlayer.setSubShown(mSubShown);
setTextViewStyle(mSubtitleText);
if (!TextUtils.isEmpty(mSubPath))
vPlayer.setSubPath(mSubPath);
if (mVideoView != null && isInitialized())
setVideoLayout();
}
private void setTextViewStyle(OutlineTextView v) {
v.setTextColor(VP.DEFAULT_SUB_COLOR);
v.setTypeface(VP.getTypeface(VP.DEFAULT_TYPEFACE_INT),
VP.DEFAULT_SUB_STYLE);
v.setShadowLayer(VP.DEFAULT_SUB_SHADOWRADIUS, 0, 0,
VP.DEFAULT_SUB_SHADOWCOLOR);
}
private boolean isInitialized() {
return (mCreated && vPlayer != null && vPlayer.isInitialized());
}
private Handler mSubHandler = new Handler() {
Bundle data;
String text;
byte[] pixels;
int width = 0, height = 0;
Bitmap bm = null;
int oldType = SUBTITLE_TEXT;
@Override
public void handleMessage(Message msg) {
data = msg.getData();
switch (msg.what) {
case SUBTITLE_TEXT:
if (oldType != SUBTITLE_TEXT) {
mSubtitleImage.setVisibility(View.GONE);
mSubtitleText.setVisibility(View.VISIBLE);
oldType = SUBTITLE_TEXT;
}
text = data.getString(VP.SUB_TEXT_KEY);
mSubtitleText.setText(text == null ? "" : text.trim());
break;
case SUBTITLE_BITMAP:
if (oldType != SUBTITLE_BITMAP) {
mSubtitleText.setVisibility(View.GONE);
mSubtitleImage.setVisibility(View.VISIBLE);
oldType = SUBTITLE_BITMAP;
}
pixels = data.getByteArray(VP.SUB_PIXELS_KEY);
if (bm == null || width != data.getInt(VP.SUB_WIDTH_KEY)
|| height != data.getInt(VP.SUB_HEIGHT_KEY)) {
width = data.getInt(VP.SUB_WIDTH_KEY);
height = data.getInt(VP.SUB_HEIGHT_KEY);
bm = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
}
if (pixels != null)
bm.copyPixelsFromBuffer(ByteBuffer.wrap(pixels));
mSubtitleImage.setImageBitmap(bm);
break;
}
}
};
private AtomicBoolean mOpened = new AtomicBoolean(Boolean.FALSE);
private boolean mSurfaceCreated = false;
private boolean mServiceConnected = false;
private Object mOpenLock = new Object();
private static final int OPEN_FILE = 0;
private static final int OPEN_START = 1;
private static final int OPEN_SUCCESS = 2;
private static final int OPEN_FAILED = 3;
private static final int HW_FAILED = 4;
private static final int LOAD_PREFS = 5;
private static final int BUFFER_START = 11;
private static final int BUFFER_PROGRESS = 12;
private static final int BUFFER_COMPLETE = 13;
private static final int CLOSE_START = 21;
private static final int CLOSE_COMPLETE = 22;
private static final int SUBTITLE_TEXT = 0;
private static final int SUBTITLE_BITMAP = 1;
private Handler vPlayerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case OPEN_FILE:
synchronized (mOpenLock) {
if (!mOpened.get() && vPlayer != null) {
mOpened.set(true);
vPlayer.setVPlayerListener(vPlayerListener);
if (vPlayer.isInitialized())
mUri = vPlayer.getUri();
if (mVideoView != null)
vPlayer.setDisplay(mVideoView.getHolder());
if (mUri != null)
vPlayer.initialize(mUri, mDisplayName, mSaveUri,
getStartPosition(), vPlayerListener,
mParentId, mIsHWCodec);
}
}
break;
case OPEN_START:
mVideoLoadingText.setText(R.string.video_layout_loading);
setVideoLoadingLayoutVisibility(View.VISIBLE);
break;
case OPEN_SUCCESS:
loadVPlayerPrefs();
setVideoLoadingLayoutVisibility(View.GONE);
setVideoLayout();
vPlayer.start();
attachMediaController();
break;
case OPEN_FAILED:
resultFinish(RESULT_FAILED);
break;
case BUFFER_START:
setVideoLoadingLayoutVisibility(View.VISIBLE);
vPlayerHandler.sendEmptyMessageDelayed(BUFFER_PROGRESS, 1000);
break;
case BUFFER_PROGRESS:
if (vPlayer.getBufferProgress() >= 100) {
setVideoLoadingLayoutVisibility(View.GONE);
} else {
mVideoLoadingText.setText(getString(
R.string.video_layout_buffering_progress,
vPlayer.getBufferProgress()));
vPlayerHandler.sendEmptyMessageDelayed(BUFFER_PROGRESS,
1000);
stopPlayer();
}
break;
case BUFFER_COMPLETE:
setVideoLoadingLayoutVisibility(View.GONE);
vPlayerHandler.removeMessages(BUFFER_PROGRESS);
break;
case CLOSE_START:
mVideoLoadingText.setText(R.string.closing_file);
setVideoLoadingLayoutVisibility(View.VISIBLE);
break;
case CLOSE_COMPLETE:
mCloseComplete = true;
break;
case HW_FAILED:
if (mVideoView != null) {
mVideoView.setVisibility(View.GONE);
mVideoView.setVisibility(View.VISIBLE);
mVideoView.initialize(VideoViewActivity.this,
VideoViewActivity.this, false);
}
break;
case LOAD_PREFS:
loadVPlayerPrefs();
break;
}
}
};
private void setVideoLoadingLayoutVisibility(int visibility) {
if (mVideoLoadingLayout != null) {
// if (visibility == View.VISIBLE)
// mLoadingProgressView.startAnimation(mLoadingAnimation);
mVideoLoadingLayout.setVisibility(visibility);
}
}
private PlayerService.VPlayerListener vPlayerListener = new PlayerService.VPlayerListener() {
@Override
public void onHWRenderFailed() {
if (Build.VERSION.SDK_INT < 11 && mIsHWCodec) {
vPlayerHandler.sendEmptyMessage(HW_FAILED);
vPlayerHandler.sendEmptyMessageDelayed(HW_FAILED, 200);
}
}
@Override
public void onSubChanged(String sub) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString(VP.SUB_TEXT_KEY, sub);
msg.setData(b);
msg.what = SUBTITLE_TEXT;
mSubHandler.sendMessage(msg);
}
@Override
public void onSubChanged(byte[] pixels, int width, int height) {
Message msg = new Message();
Bundle b = new Bundle();
b.putByteArray(VP.SUB_PIXELS_KEY, pixels);
b.putInt(VP.SUB_WIDTH_KEY, width);
b.putInt(VP.SUB_HEIGHT_KEY, height);
msg.setData(b);
msg.what = SUBTITLE_BITMAP;
mSubHandler.sendMessage(msg);
}
@Override
public void onOpenStart() {
vPlayerHandler.sendEmptyMessage(OPEN_START);
}
@Override
public void onOpenSuccess() {
vPlayerHandler.sendEmptyMessage(OPEN_SUCCESS);
}
@Override
public void onOpenFailed() {
vPlayerHandler.sendEmptyMessage(OPEN_FAILED);
}
@Override
public void onBufferStart() {
vPlayerHandler.sendEmptyMessage(BUFFER_START);
stopPlayer();
}
@Override
public void onBufferComplete() {
Log.i("VideoActivity#onBufferComplete " + vPlayer.needResume());
vPlayerHandler.sendEmptyMessage(BUFFER_COMPLETE);
if (vPlayer != null && !vPlayer.needResume())
startPlayer();
}
@Override
public void onPlaybackComplete() {
mEnd = true;
if (mLoopCount == 0 || mLoopCount-- > 1) {
vPlayer.start();
vPlayer.seekTo(0);
} else {
resultFinish(RESULT_OK);
}
}
@Override
public void onCloseStart() {
vPlayerHandler.sendEmptyMessage(CLOSE_START);
}
@Override
public void onCloseComplete() {
vPlayerHandler.sendEmptyMessage(CLOSE_COMPLETE);
}
@Override
public void onVideoSizeChanged(int width, int height) {
if (mVideoView != null) {
setVideoLayout();
}
}
@Override
public void onDownloadRateChanged(int kbPerSec) {
if (!MediaUtils.isNative(mUri.toString())
&& mMediaController != null) {
mMediaController.setDownloadRate(String.format("%dKB/s",
kbPerSec));
}
}
};
private int mVideoMode = VideoView.VIDEO_LAYOUT_SCALE;
private void setVideoLayout() {
mVideoView.setVideoLayout(mVideoMode, VP.DEFAULT_ASPECT_RATIO,
vPlayer.getVideoWidth(), vPlayer.getVideoHeight(),
vPlayer.getVideoAspectRatio());
}
private void savePosition() {
if (vPlayer != null && mUri != null) {
PreferenceUtils.put(
mUri.toString(),
StringUtils.generateTime((int) (0.5 + vPlayer
.getCurrentPosition()))
+ " / "
+ StringUtils.generateTime(vPlayer.getDuration()));
if (mEnd)
PreferenceUtils
.put(mUri + VP.SESSION_LAST_POSITION_SUFIX, 1.0f);
else
PreferenceUtils
.put(mUri + VP.SESSION_LAST_POSITION_SUFIX,
(float) (vPlayer.getCurrentPosition() / (double) vPlayer
.getDuration()));
}
}
private float getStartPosition() {
if (mFromStart)
return 1.1f;
if (mStartPos <= 0.0f || mStartPos >= 1.0f)
return PreferenceUtils.getFloat(mUri
+ VP.SESSION_LAST_POSITION_SUFIX, 7.7f);
return mStartPos;
}
@Override
public int getBufferPercentage() {
if (isInitialized())
return (int) (vPlayer.getBufferProgress() * 100);
return 0;
}
@Override
public long getCurrentPosition() {
if (isInitialized())
return vPlayer.getCurrentPosition();
return (long) (getStartPosition() * vPlayer.getDuration());
}
@Override
public long getDuration() {
if (isInitialized())
return vPlayer.getDuration();
return 0;
}
@Override
public boolean isPlaying() {
if (isInitialized())
return vPlayer.isPlaying();
return false;
}
@Override
public void pause() {
if (isInitialized())
vPlayer.stop();
}
@Override
public void seekTo(long arg0) {
if (isInitialized())
vPlayer.seekTo((float) ((double) arg0 / vPlayer.getDuration()));
}
@Override
public void start() {
if (isInitialized())
vPlayer.start();
}
@Override
public void previous() {
}
@Override
public void next() {
}
private static final int VIDEO_MAXIMUM_HEIGHT = 2048;
private static final int VIDEO_MAXIMUM_WIDTH = 2048;
@Override
public float scale(float scaleFactor) {
float userRatio = VP.DEFAULT_ASPECT_RATIO;
int videoWidth = vPlayer.getVideoWidth();
int videoHeight = vPlayer.getVideoHeight();
float videoRatio = vPlayer.getVideoAspectRatio();
float currentRatio = mVideoView.mVideoHeight / (float) videoHeight;
currentRatio += (scaleFactor - 1);
if (videoWidth * currentRatio >= VIDEO_MAXIMUM_WIDTH)
currentRatio = VIDEO_MAXIMUM_WIDTH / (float) videoWidth;
if (videoHeight * currentRatio >= VIDEO_MAXIMUM_HEIGHT)
currentRatio = VIDEO_MAXIMUM_HEIGHT / (float) videoHeight;
if (currentRatio < 0.5f)
currentRatio = 0.5f;
mVideoView.mVideoHeight = (int) (videoHeight * currentRatio);
mVideoView.setVideoLayout(mVideoMode, userRatio, videoWidth,
videoHeight, videoRatio);
return currentRatio;
}
@SuppressLint("SimpleDateFormat")
@Override
public void snapshot() {
if (!com.cjj.bb.utils.FileUtils.sdAvailable()) {
ToastUtils.showToast(R.string.file_explorer_sdcard_not_available);
} else {
Uri imgUri = null;
Bitmap bitmap = vPlayer.getCurrentFrame();
if (bitmap != null) {
File screenshotsDirectory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ VP.SNAP_SHOT_PATH);
if (!screenshotsDirectory.exists()) {
screenshotsDirectory.mkdirs();
}
File savePath = new File(
screenshotsDirectory.getPath()
+ "/"
+ new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date()) + ".jpg");
if (ImageUtils.saveBitmap(savePath.getPath(), bitmap)) {
imgUri = Uri.fromFile(savePath);
}
}
if (imgUri != null) {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
imgUri));
ToastUtils.showLongToast(getString(
R.string.video_screenshot_save_in, imgUri.getPath()));
} else {
ToastUtils.showToast(R.string.video_screenshot_failed);
}
}
}
@Override
public void toggleVideoMode(int mode) {
mVideoMode = mode;
setVideoLayout();
}
@Override
public void stop() {
onBackPressed();
}
@Override
public long goForward() {
return 0;
}
@Override
public long goBack() {
return 0;
}
@Override
public void removeLoadingView() {
mVideoLoadingLayout.setVisibility(View.GONE);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
Log.i("onSurfaceCreated");
mSurfaceCreated = true;
if (mServiceConnected)
vPlayerHandler.sendEmptyMessage(OPEN_FILE);
if (vPlayer != null)
vPlayer.setDisplay(holder);
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (vPlayer != null) {
setVideoLayout();
}
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
Log.i("onSurfaceDestroyed");
if (vPlayer != null && vPlayer.isInitialized()) {
if (vPlayer.isPlaying()) {
vPlayer.stop();
vPlayer.setState(PlayerService.STATE_NEED_RESUME);
}
vPlayer.releaseSurface();
if (vPlayer.needResume())
vPlayer.start();
}
}
@Override
public void setDanmakushow(boolean isShow) {
// TODO Auto-generated method stub
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/AreaGridAdapter.java
================================================
package com.cjj.bb.adapter;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.activity.DonghuaActivity;
import com.cjj.bb.activity.TVActivity;
import com.cjj.bb.model.AreaItem;
public class AreaGridAdapter extends BaseAdapter{
private Context mContext;
private List mList;
public AreaGridAdapter(Context mContext,List mList){
this.mContext = mContext;
this.mList = mList;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public AreaItem getItem(int position) {
return mList == null ? null : mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
AreaItem areaItem = getItem(position);
convertView = LayoutInflater.from(mContext).inflate(R.layout.area_item, null);
ImageView areaImageView = (ImageView) convertView.findViewById(R.id.areaImageView);
TextView areaTextView = (TextView) convertView.findViewById(R.id.areaTextView);
areaImageView.setImageResource(areaItem.getImg());
areaTextView.setText(areaItem.getText());
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",position+1);
if(position == 7){
i.setClass(mContext, TVActivity.class);
}else{
i.setClass(mContext, DonghuaActivity.class);
}
mContext.startActivity(i);
// 动画过渡
((Activity) mContext).overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
});
return convertView;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/ArrayAdapter.java
================================================
package com.cjj.bb.adapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.BaseAdapter;
public abstract class ArrayAdapter extends BaseAdapter {
// 数据
protected ArrayList mObjects;
protected LayoutInflater mInflater;
protected final Object mLock = new Object();
public ArrayAdapter(final Context ctx, final ArrayList l) {
mObjects = l == null ? new ArrayList() : l;
mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public ArrayAdapter(final Context ctx, final T... l) {
mObjects = new ArrayList();
mObjects.addAll(Arrays.asList(l));
mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public ArrayAdapter(final Context ctx, final List l) {
mObjects = new ArrayList();
if (l != null)
mObjects.addAll(l);
mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public ArrayAdapter(final Context ctx, final Collection l) {
mObjects = new ArrayList();
if (l != null)
mObjects.addAll(l);
mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mObjects.size();
}
@Override
public T getItem(int position) {
return mObjects.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
public void add(T item) {
this.mObjects.add(item);
}
public void replace(ArrayList newObjects) {
if (newObjects == null)
newObjects = new ArrayList();
this.mObjects = newObjects;
}
/**
* Adds the specified items at the end of the array.
*
* @param items The items to add at the end of the array.
*/
public void addAll(T... items) {
ArrayList values = this.mObjects;
for (T item : items) {
values.add(item);
}
this.mObjects = values;
}
/**
*
* @param collection
*/
public void addAll(Collection extends T> collection) {
mObjects.addAll(collection);
}
/**
* Remove all elements from the list.
*/
public void clear() {
mObjects.clear();
}
/**
* 获取所有数据
*
* @return
*/
public final ArrayList getAll() {
return mObjects;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/BankumiTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class BankumiTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "连载动画", "完结动画",
"动画资讯", "官方延伸", "国产动画" };
public BankumiTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(33);
case 1:
return new DonghuaFragment(32);
case 2:
return new DonghuaFragment(51);
case 3:
return new DonghuaFragment(152);
case 4:
return new DonghuaFragment(153);
default:
return new DonghuaFragment(33);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/DianyingTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class DianyingTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区动态", "欧美电影",
"日本电影", "国产电影", "电影相关" };
public DianyingTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(23);
case 1:
return new DonghuaFragment(145);
case 2:
return new DonghuaFragment(146);
case 3:
return new DonghuaFragment(147);
case 4:
return new DonghuaFragment(82);
default:
return new DonghuaFragment(23);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/DonghuaTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class DonghuaTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区动态", "MAD·AMV",
"MMD·3D", "动画短片", "综合" };
public DonghuaTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(1);
case 1:
return new DonghuaFragment(24);
case 2:
return new DonghuaFragment(25);
case 3:
return new DonghuaFragment(47);
case 4:
return new DonghuaFragment(27);
default:
return new DonghuaFragment(1);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/GameListAdapter.java
================================================
package com.cjj.bb.adapter;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.model.GameItem;
import com.cjj.bb.utils.ToastUtils;
public class GameListAdapter extends BaseAdapter{
private Context mContext;
private List mList;
GameItem gameItem;
public GameListAdapter(Context mContext,List mList){
this.mContext = mContext;
this.mList = mList;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public GameItem getItem(int position) {
return mList == null ? null : mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
gameItem = getItem(position);
convertView = LayoutInflater.from(mContext).inflate(R.layout.game_list_item, null);
ImageView gameImageView = (ImageView) convertView.findViewById(R.id.game_item_image);
TextView gameTextView = (TextView) convertView.findViewById(R.id.game_item_title);
Button gameButton = (Button) convertView.findViewById(R.id.GameButton);
gameImageView.setImageResource(gameItem.getImg());
gameTextView.setText(gameItem.getText());
gameButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mList.get(position).getPath()));
ToastUtils.showToast("(`・ω・´)转跳到" + mList.get(position).getText() + "官网");
//i.setClass(mContext, DonghuaActivity.class);
mContext.startActivity(intent);
// 动画过渡
((Activity) mContext).overridePendingTransition(R.anim.push_left_in,R.anim.push_no);
}
});
return convertView;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/GridAdapter.java
================================================
package com.cjj.bb.adapter;
import java.util.List;
import com.cjj.bb.R;
import com.cjj.bb.activity.VideoInfoActivity;
import com.cjj.bb.model.VideoItem;
import com.nostra13.universalimageloader.core.ImageLoader;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class GridAdapter extends BaseAdapter{
private Context mContext;
private List mList;
private ImageLoader mImageLoader;
public GridAdapter(Context mContext,List mList,ImageLoader mImageLoader){
this.mContext = mContext;
this.mList = mList;
this.mImageLoader = mImageLoader;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public VideoItem getItem(int position) {
return mList == null ? null : mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mHolder;
VideoItem videoitem = getItem(position);
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.homepage_item, null);
mHolder = new ViewHolder();
mHolder.icon = (ImageView) convertView.findViewById(R.id.list_item_image);
mHolder.msg = (TextView) convertView.findViewById(R.id.list_item_title);
mHolder.bofang = (TextView) convertView.findViewById(R.id.BangumiImageView_baofang);
mHolder.danmagu = (TextView) convertView.findViewById(R.id.BangumiImageView_danmugu);
convertView.setTag(mHolder);
}else{
mHolder = (ViewHolder) convertView.getTag();
}
mImageLoader.displayImage(videoitem.getPic(), mHolder.icon);
mHolder.msg.setText(videoitem.getTitle());
mHolder.bofang.setText(videoitem.getPlay());
mHolder.danmagu.setText(videoitem.getVideo_review());
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
VideoItem item = (VideoItem) mList.get(position);
Intent i = new Intent();
Bundle bundle = new Bundle();
bundle.putSerializable("videoItemdata", item);
i.setClass(mContext, VideoInfoActivity.class);
i.putExtras(bundle);
mContext.startActivity(i);
// 动画过渡
((Activity) mContext).overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
});
return convertView;
}
private class ViewHolder{
private ImageView icon;
private TextView msg;
private TextView bofang;
private TextView danmagu;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/ItemsAdapter.java
================================================
package com.cjj.bb.adapter;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.cjj.bb.R;
public class ItemsAdapter extends ArrayAdapter{
Context context;
LayoutInflater inflater;
String[] texts;
int layoutResourceId;
float imageWidth;
public ItemsAdapter(Context context, int layoutResourceId, Integer[] items,String[] texts) {
super(context, layoutResourceId, items);
this.context = context;
this.layoutResourceId = layoutResourceId;
this.texts = texts;
float width = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth();
float margin = (int)convertDpToPixel(10f, (Activity)context);
// two images, three margins of 10dips
imageWidth = ((width - (3 * margin)) / 2);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout row = (LinearLayout) convertView;
ItemHolder holder;
Integer item = getItem(position);
if (row == null) {
holder = new ItemHolder();
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = (LinearLayout) inflater.inflate(layoutResourceId, parent, false);
ImageView itemImage = (ImageView)row.findViewById(R.id.item_image);
TextView itemText = (TextView)row.findViewById(R.id.bankumi_item_title);
holder.itemImage = itemImage;
holder.itemText = itemText;
} else {
holder = (ItemHolder) row.getTag();
}
row.setTag(holder);
setImageBitmap(item, holder.itemImage);
holder.itemText.setText(texts[position]);
return row;
}
public static class ItemHolder
{
ImageView itemImage;
TextView itemText;
}
// resize the image proportionately so it fits the entire space
private void setImageBitmap(Integer item, ImageView imageView){
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), item);
float i = ((float) imageWidth) / ((float) bitmap.getWidth());
float imageHeight = i * (bitmap.getHeight());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imageView.getLayoutParams();
params.height = (int) imageHeight;
params.width = (int) imageWidth;
imageView.setLayoutParams(params);
imageView.setImageResource(item);
}
public static float convertDpToPixel(float dp, Context context){
Resources resources = context.getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * (metrics.densityDpi/160f);
return px;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/KejiTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class KejiTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区动态", "纪录片",
"科普人文", "野生技术", "公开课" , "军事", "数码"};
public KejiTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(36);
case 1:
return new DonghuaFragment(37);
case 2:
return new DonghuaFragment(124);
case 3:
return new DonghuaFragment(122);
case 4:
return new DonghuaFragment(39);
case 5:
return new DonghuaFragment(96);
case 6:
return new DonghuaFragment(95);
default:
return new DonghuaFragment(36);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/MainTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.BangumiFragment;
import com.cjj.bb.fragment.DonghuaFragment;
import com.cjj.bb.fragment.FragmentLogin;
import com.cjj.bb.fragment.FramentTime;
import com.cjj.bb.fragment.GamesCenterFragment;
import com.cjj.bb.fragment.HomePageFragment2;
import com.cjj.bb.fragment.SubareaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class MainTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "个人中心","首页",
"分区导航", "新番专题", "游戏中心","放松时间表" };
public HomePageFragment2 homepage = new HomePageFragment2();
public SubareaFragment subarea = new SubareaFragment();
public MainTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new FragmentLogin();
case 1:
return homepage;
case 2:
return subarea;
case 3:
return new BangumiFragment();
case 4:
return new GamesCenterFragment();
case 5:
return new FramentTime();
default:
return new DonghuaFragment(33);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/MusicTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class MusicTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区动态", "翻唱",
"VOCALOID", "演奏", "音乐选集"};
public MusicTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(3);
case 1:
return new DonghuaFragment(31);
case 2:
return new DonghuaFragment(30);
case 3:
return new DonghuaFragment(59);
case 4:
return new DonghuaFragment(130);
default:
return new DonghuaFragment(3);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/RankAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.RankFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class RankAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区", "新番",
"动画", "音乐", "游戏", "科学", "娱乐", "电影" };
public RankAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new RankFragment(10070);
case 1:
return new RankFragment(100733);
case 2:
return new RankFragment(10071);
case 3:
return new RankFragment(10073);
case 4:
return new RankFragment(10074);
case 5:
return new RankFragment(100736);
case 6:
return new RankFragment(10075);
case 7:
return new RankFragment(100723);
default:
return new RankFragment(1);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/VideoInfoListAdapter.java
================================================
package com.cjj.bb.adapter;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.activity.BiliVideoViewActivity;
public class VideoInfoListAdapter extends BaseAdapter{
private Context mContext;
private List mList;
String videoItem;
String av;
String page;
public VideoInfoListAdapter(Context mContext,List mList,String av){
this.mContext = mContext;
this.mList = mList;
this.av = av;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public String getItem(int position) {
return mList == null ? null : mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
videoItem = getItem(position);
convertView = LayoutInflater.from(mContext).inflate(R.layout.video_info_list_item, null);
TextView titleTextView = (TextView) convertView.findViewById(R.id.title);
View itemView = convertView.findViewById(R.id.linearlayout_row);
titleTextView.setText(mList.get(position));
itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
//ToastUtils.showToast("(`・ω・´) "+mList.get(position));
page = String.valueOf(position+1);
//i.setClass(mContext, DonghuaActivity.class);
//mContext.startActivity(intent);
// 动画过渡
//((Activity) mContext).overridePendingTransition(R.anim.push_left_in,R.anim.push_no);
Intent intent = new Intent(mContext, BiliVideoViewActivity.class);
intent.putExtra("displayName",mList.get(position));
intent.putExtra("av",av);
intent.putExtra("page",page);
mContext.startActivity(intent);
((Activity) mContext).overridePendingTransition(R.anim.push_left_in,R.anim.push_no);
}
});
return convertView;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/VideoListAdapter.java
================================================
package com.cjj.bb.adapter;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.model.VideoItem;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
/**
* 视频列表适配器
*
* @author wwj_748
* @date 2012/8/9
*/
public class VideoListAdapter extends BaseAdapter {
private ViewHolder holder; // 视图容器
private LayoutInflater layoutInflater; // 布局加载器
private Context context; // 上下文对象
private List list; // 博客列表
private ImageLoader imageLoader = ImageLoader.getInstance();// 得到图片加载器
private DisplayImageOptions options; // 显示图像设置
public VideoListAdapter(Context context) {
super();
this.context = context;
layoutInflater = LayoutInflater.from(context);
list = new ArrayList();
// 图片加载器初始化
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
// 使用DisplayImageOptions.Builder()创建DisplayImageOptions
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.bili_default_image_tv_with_bg) // 设置图片下载期间显示的图片
.showImageForEmptyUri(R.drawable.bili_default_image_tv_with_bg) // 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.bili_default_image_tv_with_bg) // 设置图片加载或解码过程中发生错误显示的图片
.cacheInMemory() // 设置下载的图片是否缓存在内存中
.cacheOnDisc() // 设置下载的图片是否缓存在SD卡中
.displayer(new RoundedBitmapDisplayer(1)) // 设置成圆角图片
.build(); // 创建配置过得DisplayImageOption对象
}
public void setList(List list) {
this.list = list;
}
public void addList(List list) {
this.list.addAll(list);
}
public void clearList() {
this.list.clear();
}
public List getList() {
return list;
}
public void removeItem(int position) {
if (list.size() > 0) {
list.remove(position);
}
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null ) {
// 装载布局文件blog_list_item.xml
convertView = layoutInflater.inflate(R.layout.video_list_item, null);
holder = new ViewHolder();
// holder.id = (TextView) convertView.findViewById(R.id.id);
holder.title = (TextView) convertView.findViewById(R.id.list_item_title);
holder.uptext = (TextView) convertView.findViewById(R.id.TextView_up);
holder.bofangtext = (TextView) convertView.findViewById(R.id.TextView_bofang);
holder.img = (ImageView) convertView.findViewById(R.id.list_item_image);
convertView.setTag(holder); // 表示给View添加一个格外的数据,
} else {
holder = (ViewHolder) convertView.getTag();// 通过getTag的方法将数据取出来
}
VideoItem item = list.get(position); // 获取当前数据
if (item != null) {
// 显示标题内容
holder.title.setText(item.getTitle());
holder.uptext.setText("UP主:"+item.getAuthor());
holder.bofangtext.setText("播放:"+item.getPlay());
if (item.getPic() != null) {
holder.img.setVisibility(View.VISIBLE);
// 异步加载图片
imageLoader
.displayImage(item.getPic(), holder.img, options);
} else {
//
holder.img.setVisibility(View.VISIBLE);
}
}
return convertView;
}
private class ViewHolder {
TextView title;
ImageView img;
TextView uptext;
TextView bofangtext;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/YouxiTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class YouxiTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区动态", "单机联机",
"网络游戏", "电子竞技" };
public YouxiTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(4);
case 1:
return new DonghuaFragment(17);
case 2:
return new DonghuaFragment(65);
case 3:
return new DonghuaFragment(60);
default:
return new DonghuaFragment(4);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/adapter/YuleTabAdapter.java
================================================
package com.cjj.bb.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import com.cjj.bb.fragment.DonghuaFragment;
/**
* FragmentPager适配器
*
* @author wwj_748
* @2014/8/9
*/
public class YuleTabAdapter extends FragmentPagerAdapter {
// 内容标题
public static final String[] DONG_HUA_TITLE = new String[] { "全区动态", "搞笑",
"生活", "综艺"};
public YuleTabAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
// 获取项
@Override
public Fragment getItem(int position) {
System.out.println("Fragment position:" + position);
switch (position) {
case 0:
return new DonghuaFragment(5);
case 1:
return new DonghuaFragment(138);
case 2:
return new DonghuaFragment(21);
case 3:
return new DonghuaFragment(71);
default:
return new DonghuaFragment(5);
}
// MainFragment fragment = new MainFragment(position);
// return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
// 返回页面标题
return DONG_HUA_TITLE[position % DONG_HUA_TITLE.length].toUpperCase();
}
@Override
public int getCount() {
// 页面个数
return DONG_HUA_TITLE.length;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/BangumiFragment.java
================================================
package com.cjj.bb.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.AbsListView.OnScrollListener;
import com.cjj.bb.R;
import com.cjj.bb.adapter.ItemsAdapter;
public class BangumiFragment extends Fragment{
private ListView listViewLeft;
private ListView listViewRight;
private ItemsAdapter leftAdapter;
private ItemsAdapter rightAdapter;
int[] leftViewsHeights;
int[] rightViewsHeights;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.items_list, container, false);
listViewLeft = (ListView) rootView.findViewById(R.id.list_view_left);
listViewRight = (ListView) rootView.findViewById(R.id.list_view_right);
loadItems();
listViewLeft.setOnTouchListener(touchListener);
listViewRight.setOnTouchListener(touchListener);
listViewLeft.setOnScrollListener(scrollListener);
listViewRight.setOnScrollListener(scrollListener);
return rootView;
}
// Passing the touch event to the opposite list
OnTouchListener touchListener = new OnTouchListener() {
boolean dispatched = false;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.equals(listViewLeft) && !dispatched) {
dispatched = true;
listViewRight.dispatchTouchEvent(event);
} else if (v.equals(listViewRight) && !dispatched) {
dispatched = true;
listViewLeft.dispatchTouchEvent(event);
}
dispatched = false;
return false;
}
};
/**
* Synchronizing scrolling
* Distance from the top of the first visible element opposite list:
* sum_heights(opposite invisible screens) - sum_heights(invisible screens) + distance from top of the first visible child
*/
OnScrollListener scrollListener = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView v, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (view.getChildAt(0) != null) {
if (view.equals(listViewLeft) ){
leftViewsHeights[view.getFirstVisiblePosition()] = view.getChildAt(0).getHeight();
int h = 0;
for (int i = 0; i < listViewRight.getFirstVisiblePosition(); i++) {
h += rightViewsHeights[i];
}
int hi = 0;
for (int i = 0; i < listViewLeft.getFirstVisiblePosition(); i++) {
hi += leftViewsHeights[i];
}
int top = h - hi + view.getChildAt(0).getTop();
listViewRight.setSelectionFromTop(listViewRight.getFirstVisiblePosition(), top);
} else if (view.equals(listViewRight)) {
rightViewsHeights[view.getFirstVisiblePosition()] = view.getChildAt(0).getHeight();
int h = 0;
for (int i = 0; i < listViewLeft.getFirstVisiblePosition(); i++) {
h += leftViewsHeights[i];
}
int hi = 0;
for (int i = 0; i < listViewRight.getFirstVisiblePosition(); i++) {
hi += rightViewsHeights[i];
}
int top = h - hi + view.getChildAt(0).getTop();
listViewLeft.setSelectionFromTop(listViewLeft.getFirstVisiblePosition(), top);
}
}
}
};
private void loadItems(){
Integer[] leftItems = new Integer[]{R.drawable.c1, R.drawable.c2, R.drawable.c3, R.drawable.c4, R.drawable.c5};
Integer[] rightItems = new Integer[]{R.drawable.c6, R.drawable.c7, R.drawable.c8, R.drawable.c9, R.drawable.c10};
String[] lefttexts = new String[]{"御神乐学园组曲","摸索吧!部活剧 第三季","怪盗JOKER 第二季","SHOW BY ROCK!!","雨色可可"};
String[] righttexts = new String[]{"攻壳机动队ARISE ALTERNATIVE ARCHITECTURE","亚尔斯兰战记","JOJO的奇妙冒险",
"黑子的篮球 第三季","可塑性记忆"};
leftAdapter = new ItemsAdapter(getActivity(), R.layout.item, leftItems,lefttexts);
rightAdapter = new ItemsAdapter(getActivity(), R.layout.item, rightItems,righttexts);
listViewLeft.setAdapter(leftAdapter);
listViewRight.setAdapter(rightAdapter);
leftViewsHeights = new int[leftItems.length];
rightViewsHeights = new int[rightItems.length];
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/BroadcastTimetableFragment.java
================================================
package com.cjj.bb.fragment;
import android.support.v4.app.Fragment;
public class BroadcastTimetableFragment extends Fragment{
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/DonghuaFragment.java
================================================
package com.cjj.bb.fragment;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import com.cjj.bb.R;
import com.cjj.bb.activity.VideoInfoActivity;
import com.cjj.bb.adapter.VideoListAdapter;
import com.cjj.bb.model.Page;
import com.cjj.bb.model.VideoItem;
import com.cjj.bb.utils.Constants;
import com.cjj.bb.utils.HttpUtil;
import com.cjj.bb.utils.URLUtil;
/**
* Fragment页面
*
* @author wwj_748
* @date 2014/8/9
*/
public class DonghuaFragment extends Fragment implements AbsListView.OnScrollListener
{
private ListView videoListView;// 视频列表
private View noBlogView; // 无数据时显示
private VideoListAdapter adapter;// 列表适配器
private List templist;
private boolean isLoad = false; // 是否加载
private int videoType = 1; // 视频类别
private Page page; // 页面引用
private LinearLayout ll_loading;
private String refreshDate = ""; // 刷新日期
public DonghuaFragment(int videoType) {
this.videoType = videoType;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
//
@Override
public void onActivityCreated(Bundle savedInstanceState) {
templist = new ArrayList();
VideoItem tempItem = new VideoItem();
// tempItem.setAid("7");
// tempItem.setTitle("[示例数据]童年动画主题曲");
// tempItem.setPic("http://i0.hdslb.com/320_180/u_user/53cb3e2f7f3efd6464b82c91ea9a1236.jpg");
// tempItem.setAuthor("根号⑨");
// tempItem.setPlay("23333");
// templist.add(tempItem);
initComponent();
if (isLoad == false) {
isLoad = true;
// 加载数据库中的数据
List list = templist;
adapter.setList(list);
adapter.notifyDataSetChanged();
// videoListView.startRefresh(); // 开始刷新
new MainTask().execute(URLUtil.getRefreshBlogListURL(videoType),
"refresh");
} else {
// videoListView.NotRefreshAtBegin(); // 不开始刷新
}
super.onActivityCreated(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e("NewsFrag", "onCreateView");
return inflater.inflate(R.layout.fragment_donghua, null);
}
// 初始化
private void init() {
adapter = new VideoListAdapter(getActivity());
page = new Page();
page.setPageStart();
}
// 初始化组件
private void initComponent() {
ll_loading = (LinearLayout) getView().findViewById(R.id.ll_loading);
videoListView = (ListView) getView().findViewById(R.id.videoListView);
videoListView.setAdapter(adapter);// 设置适配器
videoListView.setOnScrollListener(this);
// videoListView.setPullRefreshEnable(this);// 设置可下拉刷新
// videoListView.setPullLoadEnable(this);// 设置可上拉加载
// 设置列表项点击事件
videoListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view,
int position, long id) {
// 获得博客列表项
VideoItem item = (VideoItem) adapter.getItem(position - 1);
Intent i = new Intent();
Bundle bundle = new Bundle();
bundle.putSerializable("videoItemdata", item);
i.setClass(getActivity(), VideoInfoActivity.class);
i.putExtras(bundle);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
});
noBlogView = getView().findViewById(R.id.noBlogLayout);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
/**
* 处理listView加载更多
* @param view
* @param firstVisibleItem
* @param visibleItemCount
* @param totalItemCount
*/
private int mListViewPreLast = 0;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount) {
if (mListViewPreLast != lastItem) { /**防止多次调用*/
new MainTask()
.execute(
URLUtil.getVideoListURL(videoType),
"load");
mListViewPreLast = lastItem;
}
}
}
private class MainTask extends AsyncTask {
@Override
protected Integer doInBackground(String... params) {
List list=new ArrayList();
try {
JSONObject donghuajson = new JSONObject(HttpUtil.getHtmlString(params[0]));
//动画数据解析
JSONArray dougaarray=donghuajson.getJSONArray("list");
for (int i=0;i", "--->"+item.getTitle());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return Constants.DEF_RESULT_CODE.ERROR;
}
// // 获取网页json数据
// String temp = HttpUtil.httpGet(params[0]);
// if (temp == null) {
// return Constants.DEF_RESULT_CODE.ERROR;
// }
// // 解析json获取列表
// List list = JsoupUtil.getBlogItemList(blogType, temp);
if (list.size() == 0) {
return Constants.DEF_RESULT_CODE.NO_DATA;
}
// 刷新动作
if (params[1].equals("refresh")) {
adapter.setList(list);
return Constants.DEF_RESULT_CODE.REFRESH;
} else {// 加载更多
adapter.addList(list);
return Constants.DEF_RESULT_CODE.LOAD;
}
}
@Override
protected void onPostExecute(Integer result) {
// 通知列表数据更新
adapter.notifyDataSetChanged();
switch (result) {
case Constants.DEF_RESULT_CODE.ERROR: // 错误
Toast.makeText(getActivity(), "网络信号不佳", Toast.LENGTH_LONG).show();
// videoListView.stopRefresh(getDate());
// videoListView.stopLoadMore();
break;
case Constants.DEF_RESULT_CODE.NO_DATA: // 无数据
// Toast.makeText(getActivity(), "无更多加载内容", Toast.LENGTH_LONG)
// .show();
// videoListView.stopLoadMore();
// noBlogView.setVisibility(View.VISIBLE); // 显示无博客
break;
case Constants.DEF_RESULT_CODE.REFRESH: // 刷新
// videoListView.stopRefresh(getDate());
ll_loading.setVisibility(View.GONE);
if (adapter.getCount() == 0) {
noBlogView.setVisibility(View.VISIBLE); // 显示无博客
}
break;
case Constants.DEF_RESULT_CODE.LOAD:
// videoListView.stopLoadMore();
page.addPage();
if (adapter.getCount() == 0) {
noBlogView.setVisibility(View.VISIBLE); // 显示无博客
}
break;
default:
break;
}
super.onPostExecute(result);
}
}
// // 加载更多时调用
// @Override
// public void onLoadMore() {
// System.out.println("loadmore");
// new MainTask()
// .execute(
// URLUtil.getVideoListURL(videoType),
// "load");
// }
//
// @Override
// public void onRefresh() {
// System.out.println("refresh");
// page.setPageStart();
// new MainTask().execute(URLUtil.getRefreshBlogListURL(videoType),
// "refresh");
// }
public String getDate() {
SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 HH:mm",
Locale.CHINA);
return sdf.format(new java.util.Date());
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/FragmentLogin.java
================================================
package com.cjj.bb.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.cjj.bb.R;
/**
* Created by Administrator on 2015/5/26.
*/
public class FragmentLogin extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ImageView iv = new ImageView(getActivity());
iv.setImageResource(R.drawable.login);
return iv;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/FramentTime.java
================================================
package com.cjj.bb.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.cjj.bb.R;
/**
* Created by Administrator on 2015/5/26.
*/
public class FramentTime extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ImageView iv = new ImageView(getActivity());
iv.setImageResource(R.drawable.time);
return iv;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/GamesCenterFragment.java
================================================
package com.cjj.bb.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.ListView;
import com.cjj.bb.R;
import com.cjj.bb.adapter.GameListAdapter;
import com.cjj.bb.model.GameItem;
import java.util.ArrayList;
public class GamesCenterFragment extends Fragment{
private ListView gameListView;
private ArrayList gameList = new ArrayList();
private int[] gameimages = new int[]{R.drawable.hxzj_gamecenter_smallbanner,R.drawable.wcat_list,
R.drawable.xwy_list,R.drawable.mlk,R.drawable.img_bh2,
R.drawable.w};
private String[] gametexts = new String[]{"幻想战姬","白猫计划","侠物语","梅露可物语","崩坏学院2","世界2"};
private String[] gamepaths = new String[]{"http://hxzj.biligame.com/","http://bmjh.biligame.com/",
"http://xwy.biligame.com/","http://mlk.biligame.com/","http://teos2.biligame.com/",
"http://sj2.biligame.com/"};
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
for (int i = 0; i < gameimages.length; i++) {
GameItem item = new GameItem();
item.setImg(gameimages[i]);
item.setText(gametexts[i]);
item.setPath(gamepaths[i]);
gameList.add(item);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_gamecenter, container, false);
gameListView = (ListView)rootView.findViewById(R.id.GameListView);
gameListView.setAdapter(new GameListAdapter(getActivity(), gameList));
return rootView;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/HomePageFragment.java
================================================
package com.cjj.bb.fragment;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.cjj.bb.R;
import com.cjj.bb.activity.BiliWebviewActivity;
import com.cjj.bb.model.BannerItem;
import com.cjj.bb.model.VideoItem;
import com.cjj.bb.utils.HttpUtil;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;
public class HomePageFragment extends Fragment{
public static String IMAGE_CACHE_PATH = "imageloader/Cache"; // 图片缓存路径
public View rootView;
private ViewPager adViewPager;
private List imageViews;// 滑动的图片集合
private List dots; // 图片标题正文的那些点
private List dotList;
private int currentItem = 0; // 当前图片的索引号
// 定义的五个指示点
private View dot0;
private View dot1;
private View dot2;
private View dot3;
private View dot4;
private View dot5;
//新番区控件
ImageView bangumiImageView01;
TextView bagumiTextView_title01;
TextView bagumiTextView01_baofang;
TextView bagumiTextView01_danmugu;
ImageView bangumiImageView02;
TextView bagumiTextView_title02;
TextView bagumiTextView02_baofang;
TextView bagumiTextView02_danmugu;
ImageView bangumiImageView03;
TextView bagumiTextView_title03;
TextView bagumiTextView03_baofang;
TextView bagumiTextView03_danmugu;
ImageView bangumiImageView04;
TextView bagumiTextView_title04;
TextView bagumiTextView04_baofang;
TextView bagumiTextView04_danmugu;
private List videoItemList;
private ScheduledExecutorService scheduledExecutorService;
// 异步加载图片
private ImageLoader mImageLoader;
private DisplayImageOptions options;
// 轮播banner的数据
private List adList;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
adViewPager.setCurrentItem(currentItem);
};
};
public HomePageFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initImageLoader();
// 获取图片加载实例
mImageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.top_banner_android)
.showImageForEmptyUri(R.drawable.top_banner_android)
.showImageOnFail(R.drawable.top_banner_android)
.cacheInMemory(true).cacheOnDisc(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY).build();
}
private void initImageLoader() {
File cacheDir = com.nostra13.universalimageloader.utils.StorageUtils
.getOwnCacheDirectory(this.getActivity().getApplicationContext(),
IMAGE_CACHE_PATH);
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisc(true).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
this.getActivity()).defaultDisplayImageOptions(defaultOptions)
.memoryCache(new LruMemoryCache(12 * 1024 * 1024))
.memoryCacheSize(12 * 1024 * 1024)
.discCacheSize(32 * 1024 * 1024).discCacheFileCount(100)
.discCache(new UnlimitedDiscCache(cacheDir))
.threadPriority(Thread.NORM_PRIORITY - 2)
.tasksProcessingOrder(QueueProcessingType.LIFO).build();
ImageLoader.getInstance().init(config);
}
private void initAdData() {
// 广告数据
//adList = getBannerAd();
imageViews = new ArrayList();
// 点
dots = new ArrayList();
dotList = new ArrayList();
dot0 = rootView.findViewById(R.id.v_dot0);
dot1 = rootView.findViewById(R.id.v_dot1);
dot2 = rootView.findViewById(R.id.v_dot2);
dot3 = rootView.findViewById(R.id.v_dot3);
dot4 = rootView.findViewById(R.id.v_dot4);
dot5 = rootView.findViewById(R.id.v_dot5);
dots.add(dot0);
dots.add(dot1);
dots.add(dot2);
dots.add(dot3);
dots.add(dot4);
dots.add(dot5);
addDynamicView();
adViewPager = (ViewPager) rootView.findViewById(R.id.vp);
adViewPager.setAdapter(new HomePageADAdapter());// 设置填充ViewPager页面的适配器
// 设置一个监听器,当ViewPager中的页面改变时调用
adViewPager.setOnPageChangeListener(new HomePageADChangeListener());
}
private void initBangumiData() {
bangumiImageView01 = (ImageView) rootView.findViewById(R.id.BangumiImageView01);
bagumiTextView_title01 = (TextView) rootView.findViewById(R.id.BangumiTextView01);
bagumiTextView01_baofang = (TextView) rootView.findViewById(R.id.BangumiImageView01_baofang);
bagumiTextView01_danmugu = (TextView) rootView.findViewById(R.id.BangumiImageView01_danmugu);
bangumiImageView02 = (ImageView) rootView.findViewById(R.id.BangumiImageView02);
bagumiTextView_title02 = (TextView) rootView.findViewById(R.id.BangumiTextView02);
bagumiTextView02_baofang = (TextView) rootView.findViewById(R.id.BangumiImageView02_baofang);
bagumiTextView02_danmugu = (TextView) rootView.findViewById(R.id.BangumiImageView02_danmugu);
bangumiImageView03 = (ImageView) rootView.findViewById(R.id.BangumiImageView03);
bagumiTextView_title03 = (TextView) rootView.findViewById(R.id.BangumiTextView03);
bagumiTextView03_baofang = (TextView) rootView.findViewById(R.id.BangumiImageView03_baofang);
bagumiTextView03_danmugu = (TextView) rootView.findViewById(R.id.BangumiImageView03_danmugu);
bangumiImageView04 = (ImageView) rootView.findViewById(R.id.BangumiImageView04);
bagumiTextView_title04 = (TextView) rootView.findViewById(R.id.BangumiTextView04);
bagumiTextView04_baofang = (TextView) rootView.findViewById(R.id.BangumiImageView04_baofang);
bagumiTextView04_danmugu = (TextView) rootView.findViewById(R.id.BangumiImageView04_danmugu);
mImageLoader.displayImage(videoItemList.get(0).getPic(), bangumiImageView01,options);
bagumiTextView_title01.setText(videoItemList.get(0).getTitle().toString());
bagumiTextView01_baofang.setText(videoItemList.get(0).getPlay().toString());
bagumiTextView01_danmugu.setText(videoItemList.get(0).getVideo_review().toString());
mImageLoader.displayImage(videoItemList.get(1).getPic(), bangumiImageView02,options);
bagumiTextView_title02.setText(videoItemList.get(1).getTitle().toString());
bagumiTextView02_baofang.setText(videoItemList.get(1).getPlay().toString());
bagumiTextView02_danmugu.setText(videoItemList.get(1).getVideo_review().toString());
mImageLoader.displayImage(videoItemList.get(2).getPic(), bangumiImageView03,options);
bagumiTextView_title03.setText(videoItemList.get(2).getTitle().toString());
bagumiTextView03_baofang.setText(videoItemList.get(2).getPlay().toString());
bagumiTextView03_danmugu.setText(videoItemList.get(2).getVideo_review().toString());
mImageLoader.displayImage(videoItemList.get(3).getPic(), bangumiImageView04,options);
bagumiTextView_title04.setText(videoItemList.get(3).getTitle().toString());
bagumiTextView04_baofang.setText(videoItemList.get(3).getPlay().toString());
bagumiTextView04_danmugu.setText(videoItemList.get(3).getVideo_review().toString());
}
private void addDynamicView() {
// 动态添加图片和下面指示的圆点
// 初始化图片资源
for (int i = 0; i < adList.size(); i++) {
ImageView imageView = new ImageView(this.getActivity());
// 异步加载图片
mImageLoader.displayImage(adList.get(i).getImg(), imageView,
options);
imageView.setScaleType(ScaleType.CENTER_CROP);
imageViews.add(imageView);
dots.get(i).setVisibility(View.VISIBLE);
dotList.add(dots.get(i));
}
}
private void startAd() {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
// 当Activity显示出来后,每两秒切换一次图片显示
scheduledExecutorService.scheduleAtFixedRate(new ScrollTask(), 1, 2,
TimeUnit.SECONDS);
}
private class ScrollTask implements Runnable {
@Override
public void run() {
synchronized (adViewPager) {
currentItem = (currentItem + 1) % imageViews.size();
handler.obtainMessage().sendToTarget();
}
}
}
@Override
public void onStop() {
super.onStop();
// 当Activity不可见的时候停止切换
scheduledExecutorService.shutdown();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
Log.d("win","hhhhhhhhhhhh");
new MainTask().execute("0");
return rootView;
}
private class HomePageADAdapter extends PagerAdapter{
@Override
public int getCount() {
return adList.size();
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
ImageView iv = imageViews.get(position);
((ViewPager) container).addView(iv);
// 在这个方法里面设置图片的点击事件
iv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
BannerItem item = (BannerItem) adList.get(position);
Intent i = new Intent();
i.setClass(getActivity(), BiliWebviewActivity.class);
i.putExtra("bannerLink", item.getLink());
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
Log.e("position", "" + position);
}
});
return iv;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
}
@Override
public void finishUpdate(View arg0) {
}
}
private class HomePageADChangeListener implements OnPageChangeListener {
private int oldPosition = 0;
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int position) {
currentItem = position;
dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
dots.get(position).setBackgroundResource(R.drawable.dot_focused);
oldPosition = position;
}
}
private class MainTask extends AsyncTask {
ArrayList Listtemp = new ArrayList();
ArrayList bangumiListtemp = new ArrayList();
@Override
protected Integer doInBackground(String... params) {
JSONObject bannerjson;
JSONObject bangumijson;
try {
bannerjson = new JSONObject(HttpUtil.getHtmlString("http://www.bilibili.com/index/slideshow.json"));
JSONArray array=bannerjson.getJSONArray("list");
for (int i=0;i imageViews;// 滑动的图片集合
private List dots; // 图片标题正文的那些点
private List dotList;
private int currentItem = 0; // 当前图片的索引号
// 定义的六个指示点
private View dot0;
private View dot1;
private View dot2;
private View dot3;
private View dot4;
private View dot5;
private List videoItemList;
private List dougaItemList;
private List musicItemList;
private List danceItemList;
private List entItemList;
private List movieItemList;
private List kejiItemList;
private ScheduledExecutorService scheduledExecutorService;
// 异步加载图片
private ImageLoader mImageLoader;
private DisplayImageOptions options;
// 轮播banner的数据
private List adList;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
adViewPager.setCurrentItem(currentItem);
};
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initImageLoader();
// 获取图片加载实例
mImageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.top_banner_android)
.showImageForEmptyUri(R.drawable.top_banner_android)
.showImageOnFail(R.drawable.top_banner_android)
.cacheInMemory(true).cacheOnDisc(true)
.bitmapConfig(Bitmap.Config.ARGB_8888)
.imageScaleType(ImageScaleType.EXACTLY).build();
initTestData();
MainTask homePageTask = new MainTask();
homePageTask.execute("0");
}
private void initTestData() {
videoItemList = new ArrayList();
for (int i = 0; i < 4; i++) {
VideoItem tempItem = new VideoItem();
tempItem.setAid("7");
tempItem.setTitle("[示例数据]童年动画主题曲");
tempItem.setPic("http://i0.hdslb.com/320_180/u_user/53cb3e2f7f3efd6464b82c91ea9a1236.jpg");
tempItem.setAuthor("根号⑨");
tempItem.setPlay("23333");
tempItem.setVideo_review("23333");
videoItemList.add(tempItem);
}
dougaItemList = videoItemList;
musicItemList = videoItemList;
danceItemList = videoItemList;
entItemList = videoItemList;
movieItemList = videoItemList;
kejiItemList = videoItemList;
ArrayList Listtemp = new ArrayList();
for (int i = 0; i < 6; i++) {
BannerItem tempItem = new BannerItem();
tempItem.setAd(false);
tempItem.setImg("http://i0.hdslb.com/promote/1f451b6b07a1984be5619f865edd5449.jpg");
tempItem.setLink("http://www.bilibili.com");
tempItem.setTitle("[示例数据]");
Listtemp.add(tempItem);
}
Listtemp.get(0).setAd(true);
adList = Listtemp;
}
private void initImageLoader() {
File cacheDir = com.nostra13.universalimageloader.utils.StorageUtils
.getOwnCacheDirectory(this.getActivity().getApplicationContext(),
IMAGE_CACHE_PATH);
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisc(true).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
this.getActivity()).defaultDisplayImageOptions(defaultOptions)
.memoryCache(new LruMemoryCache(12 * 1024 * 1024))
.memoryCacheSize(12 * 1024 * 1024)
.discCacheSize(32 * 1024 * 1024).discCacheFileCount(100)
.discCache(new UnlimitedDiscCache(cacheDir))
.threadPriority(Thread.NORM_PRIORITY - 2)
.tasksProcessingOrder(QueueProcessingType.LIFO).build();
ImageLoader.getInstance().init(config);
}
private void initAdData() {
// 广告数据
//adList = getBannerAd();
imageViews = new ArrayList();
// 点
dots = new ArrayList();
dotList = new ArrayList();
dot0 = rootView.findViewById(R.id.v_dot0);
dot1 = rootView.findViewById(R.id.v_dot1);
dot2 = rootView.findViewById(R.id.v_dot2);
dot3 = rootView.findViewById(R.id.v_dot3);
dot4 = rootView.findViewById(R.id.v_dot4);
dot5 = rootView.findViewById(R.id.v_dot5);
dots.add(dot0);
dots.add(dot1);
dots.add(dot2);
dots.add(dot3);
dots.add(dot4);
dots.add(dot5);
adViewPager = (ViewPager) rootView.findViewById(R.id.vp);
bangumiGridView = (GridView)rootView.findViewById(R.id.BangumiGridView);
dougaGridView = (GridView)rootView.findViewById(R.id.DonghuaGridView);
kejiGridView = (GridView)rootView.findViewById(R.id.KejiGridView);
movieGridView = (GridView)rootView.findViewById(R.id.MovieGridView);
entGridView = (GridView)rootView.findViewById(R.id.EntGridView);
danceGridView = (GridView)rootView.findViewById(R.id.DanceGridView);
musicGridView = (GridView)rootView.findViewById(R.id.MusicGridView);
addDynamicView();
adViewPager.setAdapter(new HomePageADAdapter());// 设置填充ViewPager页面的适配器
// 设置一个监听器,当ViewPager中的页面改变时调用
adViewPager.setOnPageChangeListener(new HomePageADChangeListener());
GridAdapter bangumiAdapter = new GridAdapter(getActivity(), videoItemList, mImageLoader);
bangumiGridView.setAdapter(bangumiAdapter);
dougaGridView.setAdapter(new GridAdapter(getActivity(), dougaItemList, mImageLoader));
musicGridView.setAdapter(new GridAdapter(getActivity(), musicItemList, mImageLoader));
danceGridView.setAdapter(new GridAdapter(getActivity(), danceItemList, mImageLoader));
entGridView.setAdapter(new GridAdapter(getActivity(), entItemList, mImageLoader));
movieGridView.setAdapter(new GridAdapter(getActivity(), movieItemList, mImageLoader));
kejiGridView.setAdapter(new GridAdapter(getActivity(), kejiItemList, mImageLoader));
donghuaView = rootView.findViewById(R.id.DonghuaView);
donghuaView.setOnClickListener(mDonghuaViewListener);
bankumiView = rootView.findViewById(R.id.BangumiView);
bankumiView.setOnClickListener(mBankumiViewListener);
musicView = rootView.findViewById(R.id.MusicView);
musicView.setOnClickListener(mMusicViewListener);
gameView = rootView.findViewById(R.id.DanceView);
gameView.setOnClickListener(mGameViewListener);
yuleView = rootView.findViewById(R.id.EntView);
yuleView.setOnClickListener(mYuleViewListener);
dianyingView = rootView.findViewById(R.id.MovieView);
dianyingView.setOnClickListener(mDianyingViewListener);
kejiView = rootView.findViewById(R.id.KejiView);
kejiView.setOnClickListener(mKejiViewListener);
}
private void addDynamicView() {
// 动态添加图片和下面指示的圆点
// 初始化图片资源
for (int i = 0; i < adList.size(); i++) {
ImageView imageView = new ImageView(this.getActivity());
// 异步加载图片
mImageLoader.displayImage(adList.get(i).getImg(), imageView,
options);
imageView.setScaleType(ScaleType.CENTER_CROP);
imageViews.add(imageView);
dots.get(i).setVisibility(View.VISIBLE);
dotList.add(dots.get(i));
}
}
private void startAd() {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
// 当Activity显示出来后,每两秒切换一次图片显示
scheduledExecutorService.scheduleAtFixedRate(new ScrollTask(), 1, 2,
TimeUnit.SECONDS);
}
private class ScrollTask implements Runnable {
@Override
public void run() {
synchronized (adViewPager) {
currentItem = (currentItem + 1) % imageViews.size();
handler.obtainMessage().sendToTarget();
}
}
}
@Override
public void onStop() {
super.onStop();
// 当Activity不可见的时候停止切换
//scheduledExecutorService.shutdown();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_homepage, container, false);
Log.d("win","hhhhhhhhhhhh");
initAdData();
return rootView;
}
private class HomePageADAdapter extends PagerAdapter{
@Override
public int getCount() {
return adList.size();
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
ImageView iv = imageViews.get(position);
((ViewPager) container).addView(iv);
// 在这个方法里面设置图片的点击事件
iv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
BannerItem item = (BannerItem) adList.get(position);
Intent i = new Intent();
i.setClass(getActivity(), BiliWebviewActivity.class);
i.putExtra("bannerLink", item.getLink());
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
Log.e("position", "" + position);
}
});
return iv;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
}
@Override
public void finishUpdate(View arg0) {
}
}
private class HomePageADChangeListener implements OnPageChangeListener {
private int oldPosition = 0;
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int position) {
currentItem = position;
dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
dots.get(position).setBackgroundResource(R.drawable.dot_focused);
oldPosition = position;
}
}
private class MainTask extends AsyncTask {
ArrayList Listtemp = new ArrayList();
ArrayList bangumiListtemp = new ArrayList();
ArrayList dougaListtemp = new ArrayList();
ArrayList musicListtemp = new ArrayList();
ArrayList danceListtemp = new ArrayList();
ArrayList entListtemp = new ArrayList();
ArrayList movieListtemp = new ArrayList();
ArrayList kejiListtemp = new ArrayList();
public MainTask() {
// TODO Auto-generated constructor stub
Log.d("T^T","----->MainTask");
}
@Override
protected Integer doInBackground(String... params) {
Log.d("T^T","----->doinbackgroud");
JSONObject bannerjson;
JSONObject bangumijson;
try {
bannerjson = new JSONObject(HttpUtil.getHtmlString("http://www.bilibili.com/index/slideshow.json"));
JSONArray array=bannerjson.getJSONArray("list");
for (int i=0;ionpostexcute");
adList = Listtemp;
videoItemList = bangumiListtemp;
dougaItemList = dougaListtemp;
musicItemList = musicListtemp;
danceItemList = danceListtemp;
entItemList = entListtemp;
movieItemList = movieListtemp;
kejiItemList = kejiListtemp;
initAdData();
// initBangumiData();
startAd();
// adViewPager.notifyAll();
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
mImageLoader.destroy();
super.onDestroy();
}
private OnClickListener mDonghuaViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",2);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
private OnClickListener mBankumiViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",1);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
private OnClickListener mMusicViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",3);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
private OnClickListener mKejiViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",5);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
private OnClickListener mYuleViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",6);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
private OnClickListener mDianyingViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",7);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
private OnClickListener mGameViewListener = new OnClickListener() {
@Override
public void onClick(View v) {
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",4);
i.setClass(getActivity(), DonghuaActivity.class);
startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,
R.anim.push_no);
}
};
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/OnlineFragment.java
================================================
package com.cjj.bb.fragment;
import java.util.ArrayList;
import java.util.List;
import com.cjj.bb.R;
import com.cjj.bb.activity.VideoViewActivity;
import com.cjj.bb.adapter.ArrayAdapter;
import com.cjj.bb.model.OnlineVideo;
import com.cjj.bb.utils.XmlReaderHelper;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class OnlineFragment extends Fragment implements OnItemClickListener {
/** 缓存视频列表 */
private static ArrayList mOnlineList = new ArrayList();
/** 缓存视频LOGO列表 */
private static ArrayList mOnlineLogoList = new ArrayList();
private ListView mListView;
/** 历史记录 */
private List mHistory = new ArrayList();
/** 显示当前正在加载的url */
private TextView mUrl;
private String mTitle;
private ArrayList tvs;
private int level = 1;
private DataAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
tvs = XmlReaderHelper.getAllCategory(getActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mView = inflater.inflate(R.layout.fragment_online, container,false);
mListView = (ListView) mView.findViewById(android.R.id.list);
mListView.setOnItemClickListener(this);
mAdapter = new DataAdapter(getActivity(),tvs);
mListView.setAdapter(mAdapter);
return mView;
}
@Override
public void onItemClick(AdapterView> parent, View view, int position,
long id) {
final OnlineVideo item = mAdapter.getItem(position);
switch (level) {
case 1:// 顶级
level = 2;
mAdapter.replace(XmlReaderHelper.getVideos(getActivity(),item.id));
mListView.setAdapter(mAdapter);
break;
case 2:
// clearAndLoad(item.url);
Intent intent = new Intent(getActivity(), VideoViewActivity.class);
intent.setData(Uri.parse(item.url));
//intent.putExtra("path", item.url);
intent.putExtra("displayName",item.title);
startActivity(intent);
break;
}
}
public boolean onBackPressed() {
switch (level) {
case 1:
return false;
case 2://
level = 1;
mAdapter.replace(tvs);
break;
}
mListView.setAdapter(mAdapter);
return true;
}
/** 数据适配 */
private class DataAdapter extends ArrayAdapter {
private ImageLoader imageLoader = ImageLoader.getInstance();// 得到图片加载器
private DisplayImageOptions options; // 显示图像设置
public DataAdapter(Context ctx,ArrayList root) {
super(ctx, root);
// 图片加载器初始化
imageLoader.init(ImageLoaderConfiguration.createDefault(getActivity()));
// 使用DisplayImageOptions.Builder()创建DisplayImageOptions
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ica_light_ic_action_important) // 设置图片下载期间显示的图片
.showImageForEmptyUri(R.drawable.ica_light_ic_action_important) // 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.ica_light_ic_action_important) // 设置图片加载或解码过程中发生错误显示的图片
.cacheInMemory() // 设置下载的图片是否缓存在内存中
.cacheOnDisc() // 设置下载的图片是否缓存在SD卡中
.build(); // 创建配置过得DisplayImageOption对象
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final OnlineVideo item = getItem(position);
if (convertView == null) {
final LayoutInflater mInflater = getActivity()
.getLayoutInflater();
convertView = mInflater.inflate(R.layout.fragment_online_item,
null);
}
ImageView thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);
if (item.iconId > 0)
thumbnail.setImageResource(item.iconId);
else
{
thumbnail.setImageDrawable(null);
// 异步加载图片
imageLoader.displayImage(item.icon_url, thumbnail, options);
}
((TextView) convertView.findViewById(R.id.title))
.setText(item.title);
return convertView;
}
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onResume() {
super.onResume();
}
}
/*
* private boolean loadVideo(final String url) { if (StringUtils.isEmpty(url))
* return false;
*
* mCurrentUrl = url;
*
* new AsyncTask() {
*
* @Override protected OnlineVideo doInBackground(Void... params) {
* Log.d("Youku", url); if (url.startsWith("http://m.youku.com")) { return
* VideoHelper.getYoukuVideo(url); } return null; }
*
* @Override protected void onPostExecute(OnlineVideo result) {
* super.onPostExecute(result); if (result != null) { Intent intent = new
* Intent(getActivity(), VideoPlayerActivity.class); intent.putExtra("path",
* result.url); intent.putExtra("title", result.title); startActivity(intent); }
* else { mWebView.loadUrl(url); } } }.execute(); return true; }
*/
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/PersonCenterFragment.java
================================================
package com.cjj.bb.fragment;
import android.support.v4.app.Fragment;
public class PersonCenterFragment extends Fragment{
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/RankFragment.java
================================================
package com.cjj.bb.fragment;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;
/**
* Fragment页面
*
* @author wwj_748
* @date 2014/8/9
*/
public class RankFragment extends Fragment {
// private XListView videoListView;// 视频列表
// private View noBlogView; // 无数据时显示
// private VideoListAdapter adapter;// 列表适配器
// private List templist;
//
// private boolean isLoad = false; // 是否加载
private int videoType = 1; // 视频类别
// private Page page; // 页面引用
//
// private String refreshDate = ""; // 刷新日期
//
public RankFragment(int videoType) {
this.videoType = videoType;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init();
}
// @Override
// public void onActivityCreated(Bundle savedInstanceState) {
// templist = new ArrayList();
// VideoItem tempItem = new VideoItem();
// tempItem.setAid("7");
// tempItem.setTitle("[示例数据]童年动画主题曲");
// tempItem.setPic("http://i0.hdslb.com/320_180/u_user/53cb3e2f7f3efd6464b82c91ea9a1236.jpg");
// tempItem.setAuthor("根号⑨");
// tempItem.setPlay("23333");
// templist.add(tempItem);
// initComponent();
// if (isLoad == false) {
// isLoad = true;
// // 加载数据库中的数据
// List list = templist;
// adapter.setList(list);
// adapter.notifyDataSetChanged();
//
// videoListView.startRefresh(); // 开始刷新
//
// } else {
// videoListView.NotRefreshAtBegin(); // 不开始刷新
// }
// super.onActivityCreated(savedInstanceState);
// }
//
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState) {
// Log.e("NewsFrag", "onCreateView");
// return inflater.inflate(R.layout.fragment_donghua, null);
// }
//
// // 初始化
// private void init() {
//
// adapter = new VideoListAdapter(getActivity());
// page = new Page();
// page.setPageStart();
// }
//
// // 初始化组件
// private void initComponent() {
// videoListView = (XListView) getView().findViewById(R.id.videoListView);
// videoListView.setAdapter(adapter);// 设置适配器
// videoListView.setPullRefreshEnable(this);// 设置可下拉刷新
// //videoListView.setPullLoadEnable(this);// 设置可上拉加载
// // 设置列表项点击事件
// videoListView.setOnItemClickListener(new OnItemClickListener() {
//
// @Override
// public void onItemClick(AdapterView> parent, View view,
// int position, long id) {
// // 获得博客列表项
// VideoItem item = (VideoItem) adapter.getItem(position - 1);
// Intent i = new Intent();
// Bundle bundle = new Bundle();
// bundle.putSerializable("videoItemdata", item);
// i.setClass(getActivity(), VideoInfoActivity.class);
// i.putExtras(bundle);
// startActivity(i);
// // 动画过渡
// getActivity().overridePendingTransition(R.anim.push_left_in,
// R.anim.push_no);
// }
// });
//
// noBlogView = getView().findViewById(R.id.noBlogLayout);
// }
//
// private class MainTask extends AsyncTask {
//
// @Override
// protected Integer doInBackground(String... params) {
// List list=new ArrayList();
// try {
// JSONObject donghuajson = new JSONObject(HttpUtil.getHtmlString(params[0]));
// //动画数据解析
// donghuajson =donghuajson.getJSONObject("rank");
// JSONArray dougaarray=donghuajson.getJSONArray("list");
// for (int i=0;i<20;i++) {
// VideoItem item = new VideoItem();
// item.setAid(dougaarray.getJSONObject(i).getString("aid").toString());
// item.setTitle(dougaarray.getJSONObject(i).getString("title").toString());
// item.setPlay(dougaarray.getJSONObject(i).getString("play").toString());
// item.setVideo_review(dougaarray.getJSONObject(i).getString("video_review").toString());
// item.setMid(dougaarray.getJSONObject(i).getString("mid").toString());
// item.setAuthor(dougaarray.getJSONObject(i).getString("author").toString());
// item.setDescription(dougaarray.getJSONObject(i).getString("description").toString());
// item.setCreate(dougaarray.getJSONObject(i).getString("create").toString());
// item.setPic(dougaarray.getJSONObject(i).getString("pic").toString());
// item.setCoins(dougaarray.getJSONObject(i).getString("coins").toString());
// list.add(item);
// //Log.d("TAG--->", "--->"+item.getTitle());
// }
//
// } catch (JSONException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// return Constants.DEF_RESULT_CODE.ERROR;
// }
//// // 获取网页json数据
//// String temp = HttpUtil.httpGet(params[0]);
//// if (temp == null) {
//// return Constants.DEF_RESULT_CODE.ERROR;
//// }
//// // 解析json获取列表
//// List list = JsoupUtil.getBlogItemList(blogType, temp);
//
// if (list.size() == 0) {
// return Constants.DEF_RESULT_CODE.NO_DATA;
// }
// // 刷新动作
// if (params[1].equals("refresh")) {
// adapter.setList(list);
// return Constants.DEF_RESULT_CODE.REFRESH;
// } else {// 加载更多
// adapter.addList(list);
// return Constants.DEF_RESULT_CODE.LOAD;
// }
//
// }
//
// @Override
// protected void onPostExecute(Integer result) {
// // 通知列表数据更新
// adapter.notifyDataSetChanged();
// switch (result) {
// case Constants.DEF_RESULT_CODE.ERROR: // 错误
// Toast.makeText(getActivity(), "网络信号不佳", Toast.LENGTH_LONG).show();
// videoListView.stopRefresh(getDate());
// videoListView.stopLoadMore();
// break;
// case Constants.DEF_RESULT_CODE.NO_DATA: // 无数据
// // Toast.makeText(getActivity(), "无更多加载内容", Toast.LENGTH_LONG)
// // .show();
// videoListView.stopLoadMore();
// // noBlogView.setVisibility(View.VISIBLE); // 显示无博客
// break;
// case Constants.DEF_RESULT_CODE.REFRESH: // 刷新
// videoListView.stopRefresh(getDate());
// if (adapter.getCount() == 0) {
// noBlogView.setVisibility(View.VISIBLE); // 显示无博客
// }
// break;
// case Constants.DEF_RESULT_CODE.LOAD:
// videoListView.stopLoadMore();
// page.addPage();
// if (adapter.getCount() == 0) {
// noBlogView.setVisibility(View.VISIBLE); // 显示无博客
// }
// break;
// default:
// break;
// }
// super.onPostExecute(result);
// }
//
// }
//
// // 加载更多时调用
// @Override
// public void onLoadMore() {
// System.out.println("loadmore");
//
// }
//
// @Override
// public void onRefresh() {
// System.out.println("refresh");
// page.setPageStart();
// new MainTask().execute(URLUtil.getRefreshBlogListURL(videoType),
// "refresh");
// }
//
// public String getDate() {
// SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 HH:mm",
// Locale.CHINA);
// return sdf.format(new java.util.Date());
// }
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/RelevantVideoFragment.java
================================================
package com.cjj.bb.fragment;
import android.support.v4.app.Fragment;
public class RelevantVideoFragment extends Fragment{
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/SubareaFragment.java
================================================
package com.cjj.bb.fragment;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.GridView;
import com.cjj.bb.R;
import com.cjj.bb.activity.DonghuaActivity;
import com.cjj.bb.adapter.AreaGridAdapter;
import com.cjj.bb.model.AreaItem;
import java.util.ArrayList;
public class SubareaFragment extends Fragment{
private GridView areaGridView;
private View rankView;
private ArrayList areaList = new ArrayList();
private int[] areaimages = new int[]{R.drawable.ic_cate_bangumi,R.drawable.ic_cate_animation,
R.drawable.ic_cate_music,R.drawable.ic_cate_game,R.drawable.ic_cate_science,
R.drawable.ic_cate_entertainment,R.drawable.ic_cate_movie,R.drawable.ic_cate_tv};
private String[] areatexts = new String[]{"番剧","动画","音乐","游戏","科学","娱乐","电影","电视"};
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
for (int i = 0; i < areaimages.length; i++) {
AreaItem item = new AreaItem();
item.setImg(areaimages[i]);
item.setText(areatexts[i]);
areaList.add(item);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_subarea, container, false);
areaGridView = (GridView)rootView.findViewById(R.id.AreaGridView);
areaGridView.setAdapter(new AreaGridAdapter(getActivity(), areaList));
rankView = rootView.findViewById(R.id.RankView);
rankView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// 处理跳转逻辑
Intent i = new Intent();
i.putExtra("AreaType",8);
i.setClass(getActivity(), DonghuaActivity.class);
getActivity().startActivity(i);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,R.anim.push_no);
}
});
return rootView;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/fragment/VideoInfoFragment.java
================================================
package com.cjj.bb.fragment;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.cjj.bb.R;
import com.cjj.bb.activity.BiliVideoViewActivity;
import com.cjj.bb.adapter.VideoInfoListAdapter;
import com.cjj.bb.model.VideoItem;
import com.cjj.bb.utils.HttpUtil;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class VideoInfoFragment extends Fragment{
public static String IMAGE_CACHE_PATH = "imageloader/Cache"; // 图片缓存路径
private String page = "1";
boolean isClickable = true;
private View rootView;
private VideoItem videoinfo;
private ImageView videoImgaeView;
private TextView titleTextView;
private TextView upTextView;
private TextView bofangTextView;
private TextView danmaguTextView;
private Button bofangButton;
private TextView labelTextView;
private TextView durationTextView;
private ListView videoInfoListView;
private ImageView arrowButton;
private TextView videoNum;
private ArrayList videoInfoList = new ArrayList();
private ImageLoader mImageLoader;
private DisplayImageOptions options;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
videoinfo = (VideoItem) getActivity().getIntent().getSerializableExtra("videoItemdata");
initImageLoader();
// 获取图片加载实例
mImageLoader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.top_banner_android)
.showImageForEmptyUri(R.drawable.top_banner_android)
.showImageOnFail(R.drawable.top_banner_android)
.cacheInMemory(true).cacheOnDisc(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY).build();
}
private void initImageLoader() {
File cacheDir = com.nostra13.universalimageloader.utils.StorageUtils
.getOwnCacheDirectory(this.getActivity().getApplicationContext(),
IMAGE_CACHE_PATH);
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisc(true).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
this.getActivity()).defaultDisplayImageOptions(defaultOptions)
.memoryCache(new LruMemoryCache(12 * 1024 * 1024))
.memoryCacheSize(12 * 1024 * 1024)
.discCacheSize(32 * 1024 * 1024).discCacheFileCount(100)
.discCache(new UnlimitedDiscCache(cacheDir))
.threadPriority(Thread.NORM_PRIORITY - 2)
.tasksProcessingOrder(QueueProcessingType.LIFO).build();
ImageLoader.getInstance().init(config);
}
final class InJavaScriptLocalObj {
public void showSource(String html) {
System.out.println("====>html="+html);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_videoinfo, container, false);
initData();
Log.d("T^T","----->onCreateView");
new VideoInfoTask().execute();
return rootView;
}
private void initData() {
videoImgaeView = (ImageView) rootView.findViewById(R.id.imageView);
titleTextView = (TextView) rootView.findViewById(R.id.titleTextView);
upTextView= (TextView) rootView.findViewById(R.id.authorTextView);
bofangTextView= (TextView) rootView.findViewById(R.id.playTextView);
danmaguTextView= (TextView) rootView.findViewById(R.id.video_reviewTextView);
bofangButton = (Button) rootView.findViewById(R.id.playButton);
labelTextView= (TextView) rootView.findViewById(R.id.labelTextView);
durationTextView = (TextView) rootView.findViewById(R.id.durationTextView);
videoInfoListView = (ListView) rootView.findViewById(R.id.video_info_list);
arrowButton = (ImageView) rootView.findViewById(R.id.arrowButton);
videoNum = (TextView) rootView.findViewById(R.id.videoNumTextView);
mImageLoader.displayImage(videoinfo.getPic(), videoImgaeView,options);
titleTextView.setText(videoinfo.getTitle());
upTextView.setText("Up主:"+videoinfo.getAuthor());
bofangTextView.setText("播放:"+videoinfo.getPlay());
danmaguTextView.setText("弹幕:"+videoinfo.getVideo_review());
//labelTextView.setText(videoinfo.getVideo_review());
durationTextView.setText(" "+videoinfo.getDescription());
bofangButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(bofangButton.getText().equals("点击播放")){
Log.d("T^T","----->点击播放");
// 处理跳转逻辑
// Intent i = new Intent();
// i.setClass(getActivity(), VideoViewActivity.class);
// i.putExtra("videoPath", videopath);
// i.putExtra("title", videoinfo.getTitle());
// startActivity(i);
Intent intent = new Intent(getActivity(), BiliVideoViewActivity.class);
// intent.putExtra("path", item.url);
intent.putExtra("displayName",videoinfo.getTitle());
intent.putExtra("av",videoinfo.getAid());
page = "1";
intent.putExtra("page",page);
startActivity(intent);
// 动画过渡
getActivity().overridePendingTransition(R.anim.push_left_in,R.anim.push_no);
}
}
});
arrowButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (isClickable) {
durationTextView.setMaxLines(durationTextView.getLineCount());
isClickable = false;
arrowButton.setImageResource(R.drawable.abcp__expander_close_holo_light);
} else {
durationTextView.setMaxLines(2);
isClickable = true;
arrowButton.setImageResource(R.drawable.abcp__expander_open_holo_light);
}
}
});
}
@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
private class VideoInfoTask extends AsyncTask {
String label;
@Override
protected Integer doInBackground(String... arg0) {
// String videoHTML = HttpUtil.sendPost("http://www.iippcc.com/bilibili/", "text=av"+videoinfo.getAid()+"&submit=搜索菌");
//
// Document doc = Jsoup.parse(videoHTML);
// Elements links = doc.select("a[href]");
// for (Element link : links) {
// if(link.text().equals("分段1")){
// videopath = link.attr("href");
// }
// }
//
// Elements labels = doc.getElementsByClass("col-md-7");
// labels = labels.select("button");
// //label = labels.get(3).text();
// cID = labels.get(6).text().substring(4);
//
//
String listHTML = HttpUtil.getHtmlString("http://www.bilibili.com/mobile/video/av" + videoinfo.getAid() + ".html");
Log.d("QAQ--->","===>列表加载中");
Document listDoc = Jsoup.parse(listHTML);
Elements listElements = listDoc.getElementsByClass("li-wrap-content");
for (int i = 0; i < listElements.size(); i++) {
Log.d("QAQ--->","===>"+listElements.get(i).text());
videoInfoList.add(listElements.get(i).text());
}
Elements labelElements = listDoc.select("[name=keywords]");
Log.d("QAQ--->","===>"+labelElements.attr("content"));
label = labelElements.attr("content");
return null;
}
@Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stubs
super.onPostExecute(result);
if(label != null){
bofangButton.setText("点击播放");
}else{
bofangButton.setText("加载失败");
}
if(label != null){
label = label.substring(20);
labelTextView.setText("标签:"+label);
if(videoInfoList != null){
videoInfoListView.setAdapter(new VideoInfoListAdapter(getActivity(),videoInfoList,videoinfo.getAid()));
videoNum.setText("共有"+videoInfoList.size()+"段视频");
}
}
if(durationTextView.getLineCount() > 2){
arrowButton.setVisibility(View.VISIBLE);
}
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/AreaItem.java
================================================
package com.cjj.bb.model;
public class AreaItem {
private int img; //图标
private String text; //文字
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/BannerItem.java
================================================
package com.cjj.bb.model;
public class BannerItem {
private String title; //广告条标题
private String link; //广告条链接
private String img; //广告条封面地址
private boolean isAd;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public boolean isAd() {
return isAd;
}
public void setAd(boolean isAd) {
this.isAd = isAd;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/GameItem.java
================================================
package com.cjj.bb.model;
public class GameItem {
private int img; //图标
private String text; //文字
private String path; //网址
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/OnlineVideo.java
================================================
package com.cjj.bb.model;
import java.util.ArrayList;
public class OnlineVideo {
public String id;
/** 标题 */
public String title;
public String desc;
/** LOGO */
public int iconId = 0;
public String icon_url;
/** 播放地址 */
public String url;
/** 备用链接 */
public ArrayList backup_url;
/** 是否目录 */
public boolean is_category = false;
/** 0视频 1电视 */
public int category;
/** */
public int level = 1;
public OnlineVideo() {
}
public OnlineVideo(String title, int iconId, int category) {
this.title = title;
this.iconId = iconId;
this.category = category;
}
public OnlineVideo(String title, int iconId, int category, String url) {
this.title = title;
this.iconId = iconId;
this.category = category;
this.url = url;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/Page.java
================================================
package com.cjj.bb.model;
/**
* 页面实体类
*
* @author wwj_748
* @date 2014/8/9
*/
public class Page {
private int page = 1; // 记录页面数
public boolean contentFirstPage = true; // 内容第一页
// 设置开始页面
public void setPageStart() {
page = 2;
}
// 设置页
public void setPage(int num) {
page = num;
}
// 获取当前页
public String getCurrentPage() {
return page + "";
}
// 添加页面
public void addPage() {
page++;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/User.java
================================================
package com.cjj.bb.model;
public class User {
private String mid;
private String name;
private Boolean isApprove = false; //是否是认证账号
private String spaceName;
private String sex;
private String rank;
private String avatar;
private String follow ; //关注好友数目
private String fans; //粉丝数目
private String article; //投稿数
private String place; //所在地
private String description; //认证用户为认证信息 普通用户为交友宣言
private String followlist; //关注的好友列表
public String getMid() {
return mid;
}
public void setMid(String mid) {
this.mid = mid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getIsApprove() {
return isApprove;
}
public void setIsApprove(Boolean isApprove) {
this.isApprove = isApprove;
}
public String getSpaceName() {
return spaceName;
}
public void setSpaceName(String spaceName) {
this.spaceName = spaceName;
}
/**
* @return the sex
*/
public String getSex() {
return sex;
}
/**
* @param sex the sex to set
*/
public void setSex(String sex) {
this.sex = sex;
}
public String getRank() {
return rank;
}
public void setRank(String rank) {
this.rank = rank;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getFollow() {
return follow;
}
public void setFollow(String follow) {
this.follow = follow;
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
}
public String getFans() {
return fans;
}
public void setFans(String fans) {
this.fans = fans;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getFollowlist() {
return followlist;
}
public void setFollowlist(String followlist) {
this.followlist = followlist;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/Video.java
================================================
package com.cjj.bb.model;
public class Video {
private String aid; //视频av号
private String title; //视频标题
private String bofang; //视频播放数
private String shoucang; //视频收藏数
private String danmu; //视频弹幕数
private String date; //发布时间
private String cover; //视频封面地址
private String commentNumber; //视频评论数
private String description; //视频描述
private String tag; //视频TAG
private String author; //up主
private String credit; //视频评分
private String coin; //视频硬币数
private String spid; //专题ID
private String cid; //视频内部ID
private String offsite; //Flash播放调用地址
private String duration; //视频长度
private String episode; //视频分段数
private String arcurl; //网页地址
private String src; //视频播放地址
public String getAid() {
return aid;
}
public void setAid(String aid) {
this.aid = aid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBofang() {
return bofang;
}
public void setBofang(String bofang) {
this.bofang = bofang;
}
public String getShoucang() {
return shoucang;
}
public void setShoucang(String shoucang) {
this.shoucang = shoucang;
}
public String getDanmu() {
return danmu;
}
public void setDanmu(String danmu) {
this.danmu = danmu;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public String getCommentNumber() {
return commentNumber;
}
public void setCommentNumber(String commentNumber) {
this.commentNumber = commentNumber;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getCredit() {
return credit;
}
public void setCredit(String credit) {
this.credit = credit;
}
public String getCoin() {
return coin;
}
public void setCoin(String coin) {
this.coin = coin;
}
public String getSpid() {
return spid;
}
public void setSpid(String spid) {
this.spid = spid;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getOffsite() {
return offsite;
}
public void setOffsite(String offsite) {
this.offsite = offsite;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getEpisode() {
return episode;
}
public void setEpisode(String episode) {
this.episode = episode;
}
public String getArcurl() {
return arcurl;
}
public void setArcurl(String arcurl) {
this.arcurl = arcurl;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/model/VideoItem.java
================================================
package com.cjj.bb.model;
import java.io.Serializable;
public class VideoItem implements Serializable{
private String aid;//视频av号
private String typeid;//视频类型
private String title;//视频标题
private String sbutitle;
private String play;//视频播放数
private String review;//评论数
private String video_review;//视频弹幕数
private String favorites;//视频收藏数
private String mid;
private String author;//Up主
private String description;//视频简介
private String create;//视频发布时间
private String pic;//视频封面地址
private String credit;
private String coins;//视频硬币数
private String duration;//视频长度
public String getAid() {
return aid;
}
public void setAid(String aid) {
this.aid = aid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTypeid() {
return typeid;
}
public void setTypeid(String typeid) {
this.typeid = typeid;
}
public String getPlay() {
return play;
}
public void setPlay(String play) {
this.play = play;
}
public String getSbutitle() {
return sbutitle;
}
public void setSbutitle(String sbutitle) {
this.sbutitle = sbutitle;
}
public String getReview() {
return review;
}
public void setReview(String review) {
this.review = review;
}
public String getVideo_review() {
return video_review;
}
public void setVideo_review(String video_review) {
this.video_review = video_review;
}
public String getFavorites() {
return favorites;
}
public void setFavorites(String favorites) {
this.favorites = favorites;
}
public String getMid() {
return mid;
}
public void setMid(String mid) {
this.mid = mid;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCreate() {
return create;
}
public void setCreate(String create) {
this.create = create;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getCredit() {
return credit;
}
public void setCredit(String credit) {
this.credit = credit;
}
public String getCoins() {
return coins;
}
public void setCoins(String coins) {
this.coins = coins;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/ArrayUtils.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.utils;
import java.lang.reflect.Array;
public class ArrayUtils {
public static T[] concat(T[] A, T[] B) {
final Class> typeofA = A.getClass().getComponentType();
@SuppressWarnings("unchecked")
T[] C = (T[]) Array.newInstance(typeofA, A.length + B.length);
System.arraycopy(A, 0, C, 0, A.length);
System.arraycopy(B, 0, C, A.length, B.length);
return C;
}
public static int indexOf(T[] array, T s) {
for (int i = 0; i < array.length; i++) {
if (array[i].equals(s)) {
return i;
}
}
return -1;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/CompressionTools.java
================================================
package com.cjj.bb.utils;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.DataFormatException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class CompressionTools {
// Export only static methods
private CompressionTools() {}
public static byte[] compress(byte[] value, int offset, int length, int compressionLevel) {
ByteArrayOutputStream bos = new ByteArrayOutputStream(length);
Deflater compressor = new Deflater();
try {
compressor.setLevel(compressionLevel); //将当前压缩级别设置为指定值。
compressor.setInput(value, offset, length);
compressor.finish(); //调用时,指示压缩应当以输入缓冲区的当前内容结尾。
// Compress the data
final byte[] buf = new byte[1024];
while (!compressor.finished()) {
//如果已到达压缩数据输出流的结尾,则返回 true。
int count = compressor.deflate(buf);
// 使用压缩数据填充指定缓冲区。
bos.write(buf, 0, count);
}
} finally {
compressor.end(); //关闭解压缩器并放弃所有未处理的输入。
}
return bos.toByteArray();
}
public static byte[] compress(byte[] value, int offset, int length) {
return compress(value, offset, length, Deflater.BEST_COMPRESSION);
// 最佳压缩的压缩级别
}
public static byte[] compress(byte[] value) {
return compress(value, 0, value.length, Deflater.BEST_COMPRESSION);
}
public static byte[] decompress(byte[] value) throws DataFormatException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(value.length);
Inflater decompressor = new Inflater();
try {
decompressor.setInput(value);
final byte[] buf = new byte[1024];
while (!decompressor.finished()) {
int count = decompressor.inflate(buf);
bos.write(buf, 0, count);
}
} finally {
decompressor.end();
}
return bos.toByteArray();
}
public static byte[] decompressXML(byte[] data) throws DataFormatException
{
byte[] dest = new byte[data.length+2];
System.arraycopy(data, 0, dest, 2, data.length);
dest[0] = 0x78;
dest[1] = 0x01;
data = dest;
Inflater decompresser = new Inflater();
decompresser.setInput(data);
byte[] bufferArray = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
try
{
int i = 1;
while (i != 0)
{
i = decompresser.inflate(bufferArray);
baos.write(bufferArray, 0, i);
}
data = baos.toByteArray();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
baos.flush();
baos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
decompresser.end();
return data;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/Constants.java
================================================
package com.cjj.bb.utils;
/**
* 常量类
*
* @author wwj_748
*
*/
public class Constants {
// 博客每一项的类型
public class DEF_BLOG_ITEM_TYPE {
public static final int TITLE = 1; // 标题
public static final int SUMMARY = 2; // 摘要
public static final int CONTENT = 3; // 内容
public static final int IMG = 4; // 图片
public static final int BOLD_TITLE = 5; // 加粗标题
public static final int CODE = 6; // 代码
}
public class DEF_NEWS_TYPE {
public static final int YEJIE = 1;
public static final int YIDONG = 2;
public static final int YANFA = 3;
public static final int ZAZHI = 4;
public static final int YUNJISUAN = 5;
}
// 评论类型
public class DEF_COMMENT_TYPE {
public static final int PARENT = 1;
public static final int CHILD = 2;
}
// 操作结果类型
public class DEF_RESULT_CODE {
public static final int ERROR = 1; // 错误
public static final int NO_DATA = 2;// 无数据
public static final int REFRESH = 3;// 刷新
public static final int LOAD = 4; // 加载
public static final int FIRST = 5;// 第一次加载
}
// 任务类型
public class DEF_TASK_TYPE {
public static final String FIRST = "first";
public static final String NOR_FIRST = "not_first";
public static final String REFRESH = "REFRESH";
public static final String LOAD = "LOAD";
}
/**
* 视频类型
*/
public class DEF_VIDEO_TYPE {
public static final int DONG_HUA = 1; // 动画区
public static final int MAD_AMV = 24; // MAD.AMV
public static final int MMD_3D = 25; // MMD.3D
public static final int DONG_HUA_DUAN_PIAN = 47; // 动画短片
public static final int DONG_HUA_ZONG_HE = 27; // 动画综合
public static final int LIAN_ZAI_DONG_HUA = 33; // 连载动画
public static final int WAN_JIE_DONG_HUA = 32; // 完结动画
public static final int ZHI_XUN = 51; // 资讯
public static final int GUAN_FANG_YAN_SHEN = 152; // 官方延伸
public static final int GUO_CHAN_DONG_HUA = 153; // 国产动画
public static final int YIN_YUE = 3; // 音乐区
public static final int FAN_CHANG = 31; // 翻唱
public static final int VOCALOID_UTAU = 30; // VOCALOID-UTAU
public static final int YAN_ZOU = 59; // 演奏
public static final int YIN_YUE_XUAN_JI = 130; //音乐选集
public static final int KE_JI = 36; //科技-全区
public static final int JI_LU_PIAN = 37; //纪录片
public static final int KE_PU_REN_WEN = 124; //科普人文
public static final int YE_SHENG_JI_SHU = 122; //野生技术
public static final int YAN_JIANG = 39; //演讲·公开课
public static final int JUN_SHI = 96; //军事
public static final int SHU_MA = 95; //数码
public static final int YU_LE = 5; //娱乐
public static final int GAO_XIAO = 138; //搞笑
public static final int SHENG_HUO = 21; //生活
public static final int ZONG_YI = 71; //综艺
public static final int DIAN_YIN = 23; //电影
public static final int OU_MEI_DIAN_YIN = 145; //欧美电影
public static final int RI_BEN_DIAN_YIN = 146; //日本电影
public static final int GUO_CHAN_DIAN_YIN = 147; //国产电影
public static final int DIAN_YIN_XIANG_GUAN = 82; //电影相关
public static final int YOU_XI = 4; //游戏
public static final int DIAN_JI = 17; //单机联机
public static final int WANG_LUO_DIAN_YIN = 65; //网络游戏
public static final int DIAN_ZI_JING_JI = 60; //电子竞技
}
/**
* 分区类型
*/
public class DEF_AREA_TYPE {
public static final int DONG_HUA_QU = 1; // 动画区
public static final int FAN_JU_QU = 2; // 番剧区
public static final int YIN_YUE_QU = 3; // 音乐区
public static final int KE_JI_QU = 4; // 科技区
public static final int YU_LE_QU = 5; // 娱乐区
public static final int YOU_XI_QU = 6; // 游戏区
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/DeviceUtils.java
================================================
package com.cjj.bb.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
/**
* 系统版本信息类
*
* @author tangjun
*
*/
public class DeviceUtils {
/** >=2.2 */
public static boolean hasFroyo() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
/** >=2.3 */
public static boolean hasGingerbread() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
}
/** >=3.0 LEVEL:11 */
public static boolean hasHoneycomb() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
}
/** >=3.1 */
public static boolean hasHoneycombMR1() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
}
/** >=4.0 14 */
public static boolean hasICS() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}
public static int getSDKVersionInt() {
return Build.VERSION.SDK_INT;
}
@SuppressWarnings("deprecation")
public static String getSDKVersion() {
return Build.VERSION.SDK;
}
/**
* 判断是否是平板电脑
*
* @param context
* @return
*/
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
public static boolean isHoneycombTablet(Context context) {
return hasHoneycomb() && isTablet(context);
}
/**
* 获得设备型号
*
* @return
*/
public static String getDeviceModel() {
return StringUtils.trim(Build.MODEL);
}
/** 检测是否魅族手机 */
public static boolean isMeizu() {
return getDeviceModel().toLowerCase().indexOf("meizu") != -1;
}
/** 检测是否HTC手机 */
public static boolean isHTC() {
return getDeviceModel().toLowerCase().indexOf("htc") != -1;
}
public static boolean isXiaomi() {
return getDeviceModel().toLowerCase().indexOf("xiaomi") != -1;
}
/**
* 获得设备制造商
*
* @return
*/
public static String getManufacturer() {
return StringUtils.trim(Build.MANUFACTURER);
}
@SuppressWarnings("deprecation")
public static int getScreenHeight(Context context) {
Display display = ((WindowManager) context
.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
return display.getHeight();
}
/** 获取屏幕宽度 */
@SuppressWarnings("deprecation")
public static int getScreenWidth(Context context) {
Display display = ((WindowManager) context
.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
return display.getWidth();
}
/**
* 获得设备屏幕密度
*/
public static float getScreenDensity(Context context) {
DisplayMetrics metrics = context.getApplicationContext().getResources()
.getDisplayMetrics();
return metrics.density;
}
public static int[] getScreenSize(int w, int h, Context context) {
int phoneW = getScreenWidth(context);
int phoneH = getScreenHeight(context);
if (w * phoneH > phoneW * h) {
phoneH = phoneW * h / w;
} else if (w * phoneH < phoneW * h) {
phoneW = phoneH * w / h;
}
return new int[] { phoneW, phoneH };
}
public static int[] getScreenSize(int w, int h, int phoneW, int phoneH) {
if (w * phoneH > phoneW * h) {
phoneH = phoneW * h / w;
} else if (w * phoneH < phoneW * h) {
phoneW = phoneH * w / h;
}
return new int[] { phoneW, phoneH };
}
/** 设置屏幕亮度 */
public static void setBrightness(final Activity context, float f) {
WindowManager.LayoutParams lp = context.getWindow().getAttributes();
lp.screenBrightness = f;
if (lp.screenBrightness > 1.0f)
lp.screenBrightness = 1.0f;
else if (lp.screenBrightness < 0.01f)
lp.screenBrightness = 0.01f;
context.getWindow().setAttributes(lp);
}
// private static final long NO_STORAGE_ERROR = -1L;
private static final long CANNOT_STAT_ERROR = -2L;
/** 检测磁盘状态 */
// public static int getStorageStatus(boolean mayHaveSd) {
// long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR;
// if (remaining == NO_STORAGE_ERROR) {
// return CommonStatus.STORAGE_STATUS_NONE;
// }
// return remaining < CommonConstants.LOW_STORAGE_THRESHOLD ?
// CommonStatus.STORAGE_STATUS_LOW : CommonStatus.STORAGE_STATUS_OK;
// }
public static long getAvailableStorage() {
try {
String storageDirectory = Environment.getExternalStorageDirectory()
.toString();
StatFs stat = new StatFs(storageDirectory);
return (long) stat.getAvailableBlocks()
* (long) stat.getBlockSize();
} catch (RuntimeException ex) {
// if we can't stat the filesystem then we don't know how many
// free bytes exist. It might be zero but just leave it
// blank since we really don't know.
return CANNOT_STAT_ERROR;
}
}
/** 隐藏软键盘 */
public static void hideSoftInput(Context ctx, View v) {
InputMethodManager imm = (InputMethodManager) ctx
.getSystemService(Context.INPUT_METHOD_SERVICE);
// 这个方法可以实现输入法在窗口上切换显示,如果输入法在窗口上已经显示,则隐藏,如果隐藏,则显示输入法到窗口上
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
/** 显示软键盘 */
public static void showSoftInput(Context ctx) {
InputMethodManager imm = (InputMethodManager) ctx
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);// (v,
// InputMethodManager.SHOW_FORCED);
}
/**
* 软键盘是否已经打开
*
* @return
*/
protected boolean isHardKeyboardOpen(Context ctx) {
return ctx.getResources().getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
}
public static String getCpuInfo() {
String cpuInfo = "";
try {
if (new File("/proc/cpuinfo").exists()) {
FileReader fr = new FileReader("/proc/cpuinfo");
BufferedReader localBufferedReader = new BufferedReader(fr,
8192);
cpuInfo = localBufferedReader.readLine();
localBufferedReader.close();
if (cpuInfo != null) {
cpuInfo = cpuInfo.split(":")[1].trim().split(" ")[0];
}
}
} catch (IOException e) {
} catch (Exception e) {
}
return cpuInfo;
}
public static void startApkActivity(final Context ctx, String packageName) {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(packageName, 0);
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(pi.packageName);
List apps = pm.queryIntentActivities(intent, 0);
ResolveInfo ri = apps.iterator().next();
if (ri != null) {
String className = ri.activityInfo.name;
intent.setComponent(new ComponentName(packageName, className));
ctx.startActivity(intent);
}
} catch (NameNotFoundException e) {
Logger.e(e);
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/DownUtil.java
================================================
/**
*
*/
package com.cjj.bb.utils;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Description:
* 网站: 疯狂Java联盟
* Copyright (C), 2001-2014, Yeeku.H.Lee
* This program is protected by copyright laws.
* Program Name:
* Date:
* @author Yeeku.H.Lee kongyeeku@163.com
* @version 1.0
*/
public class DownUtil
{
// 定义下载资源的路径
private String path;
// 指定所下载的文件的保存位置
private String targetFile;
// 定义需要使用多少线程下载资源
private int threadNum;
// 定义下载的线程对象
private DownThread[] threads;
// 定义下载的文件的总大小
private int fileSize;
public DownUtil(String path, String targetFile, int threadNum)
{
this.path = path;
this.threadNum = threadNum;
// 初始化threads数组
threads = new DownThread[threadNum];
this.targetFile = targetFile;
}
public void download() throws Exception
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
// 得到文件大小
fileSize = conn.getContentLength();
conn.disconnect();
int currentPartSize = fileSize / threadNum + 1;
RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
// 设置本地文件的大小
file.setLength(fileSize);
file.close();
for (int i = 0; i < threadNum; i++)
{
// 计算每条线程的下载的开始位置
int startPos = i * currentPartSize;
// 每个线程使用一个RandomAccessFile进行下载
RandomAccessFile currentPart = new RandomAccessFile(targetFile,
"rw");
// 定位该线程的下载位置
currentPart.seek(startPos);
// 创建下载线程
threads[i] = new DownThread(startPos, currentPartSize,
currentPart);
// 启动下载线程
threads[i].start();
}
}
// 获取下载的完成百分比
public double getCompleteRate()
{
// 统计多条线程已经下载的总大小
int sumSize = 0;
for (int i = 0; i < threadNum; i++)
{
sumSize += threads[i].length;
}
// 返回已经完成的百分比
return sumSize * 1.0 / fileSize;
}
private class DownThread extends Thread
{
// 当前线程的下载位置
private int startPos;
// 定义当前线程负责下载的文件大小
private int currentPartSize;
// 当前线程需要下载的文件块
private RandomAccessFile currentPart;
// 定义已经该线程已下载的字节数
public int length;
public DownThread(int startPos, int currentPartSize,
RandomAccessFile currentPart)
{
this.startPos = startPos;
this.currentPartSize = currentPartSize;
this.currentPart = currentPart;
}
@Override
public void run()
{
try
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url
.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
InputStream inStream = conn.getInputStream();
// 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。
inStream.skip(this.startPos);
byte[] buffer = new byte[1024];
int hasRead = 0;
// 读取网络数据,并写入本地文件
while (length < currentPartSize
&& (hasRead = inStream.read(buffer)) > 0)
{
currentPart.write(buffer, 0, hasRead);
// 累计该线程下载的总大小
length += hasRead;
}
currentPart.close();
inStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/FileUitl.java
================================================
package com.cjj.bb.utils;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.os.Environment;
/**
* 文件管理类 在以后的开发中也可以使用这个工具类,提高代码的利用性
* 只要是对SD卡的操作
* 1、获取SD卡路径 getSDPATH
* 2、在SD卡上根据传入的目录名创建目录 createSDDir
* 3、在创建上目录后可以在该目录上创建文件 createSDFile
* 4、检测文件是否存在 isFileExist
* 5、将一个InputStream写入到SD卡中 write2SDFromInput
* 6、将一个字符流写入到SD卡 write2SDFromWrite
* 注:如果要写入SD卡,只要调用write2SDFromInput函数即可
* @author Administrator
*
*/
public class FileUitl {
private static String SDPATH;
public FileUitl(){
//得到当前设备外部存储设备的目录
SDPATH = Environment.getExternalStorageDirectory() + File.separator;
}
/**
* 获取当前SD卡的根目录
* @return
*/
public String getSDPATH(){
return SDPATH;
}
/**
* SD卡上创建目录
*/
public File createSDDir(String dirName){
File dir = new File(SDPATH + dirName);
System.out.println("createSDDir " + SDPATH + dirName);
dir.mkdir();
return dir;
}
/**
* SD卡上创建文件
*/
public File createSDFile(String fileName)throws IOException{
File file = new File(SDPATH + fileName);
System.out.println("createSDFile " + SDPATH + fileName);
file.createNewFile();
return file;
}
/**
* 判断SD卡上的文件是否存在
*/
public boolean isFileExist(String fileName){
File file = new File(SDPATH + fileName);
return file.exists();
}
/**
* 将一个InputStream字节流写入到SD卡中
*/
public File write2SDFromInput(String Path, String FileName, InputStream input){
File file = null;
OutputStream output = null; //创建一个写入字节流对象
try{
createSDDir(Path); //根据传入的路径创建目录
file = createSDFile(Path + FileName); //根据传入的文件名创建
output = new FileOutputStream(file);
byte buffer[] = new byte[4 * 1024]; //每次读取4K
int num = 0; //需要根据读取的字节大小写入文件
while((num = (input.read(buffer))) != -1){
output.write(buffer, 0, num);
}
output.flush(); //清空缓存
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally{
try{
output.close();
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return file;
}
/**
* 把传入的字符流写入到SD卡中
* @param Path
* @param FileName
* @param input
* @return
*/
public File write2SDFromWrite(String Path, String FileName, BufferedReader input){
File file = null;
FileWriter output = null; //创建一个写入字符流对象
BufferedWriter bufw = null;
try{
createSDDir(Path); //根据传入的路径创建目录
file = createSDFile(Path + FileName); //根据传入的文件名创建
output = new FileWriter(file);
bufw = new BufferedWriter(output);
String line = null;
while((line = (input.readLine())) != null){
System.out.println("line = " + line);
bufw.write(line);
bufw.newLine();
}
bufw.flush(); //清空缓存
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally{
try{
bufw.close();
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return file;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/FileUtils.java
================================================
package com.cjj.bb.utils;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
public class FileUtils {
// http://www.fileinfo.com/filetypes/video , "dat" , "bin" , "rms"
public static final String[] VIDEO_EXTENSIONS = { "264", "3g2", "3gp",
"3gp2", "3gpp", "3gpp2", "3mm", "3p2", "60d", "aep", "ajp", "amv",
"amx", "arf", "asf", "asx", "avb", "avd", "avi", "avs", "avs",
"axm", "bdm", "bdmv", "bik", "bix", "bmk", "box", "bs4", "bsf",
"byu", "camre", "clpi", "cpi", "cvc", "d2v", "d3v", "dav", "dce",
"dck", "ddat", "dif", "dir", "divx", "dlx", "dmb", "dmsm", "dmss",
"dnc", "dpg", "dream", "dsy", "dv", "dv-avi", "dv4", "dvdmedia",
"dvr-ms", "dvx", "dxr", "dzm", "dzp", "dzt", "evo", "eye", "f4p",
"f4v", "fbr", "fbr", "fbz", "fcp", "flc", "flh", "fli", "flv",
"flx", "gl", "grasp", "gts", "gvi", "gvp", "hdmov", "hkm", "ifo",
"imovi", "imovi", "iva", "ivf", "ivr", "ivs", "izz", "izzy", "jts",
"lsf", "lsx", "m15", "m1pg", "m1v", "m21", "m21", "m2a", "m2p",
"m2t", "m2ts", "m2v", "m4e", "m4u", "m4v", "m75", "meta", "mgv",
"mj2", "mjp", "mjpg", "mkv", "mmv", "mnv", "mod", "modd", "moff",
"moi", "moov", "mov", "movie", "mp21", "mp21", "mp2v", "mp4",
"mp4v", "mpe", "mpeg", "mpeg4", "mpf", "mpg", "mpg2", "mpgin",
"mpl", "mpls", "mpv", "mpv2", "mqv", "msdvd", "msh", "mswmm",
"mts", "mtv", "mvb", "mvc", "mvd", "mve", "mvp", "mxf", "mys",
"ncor", "nsv", "nvc", "ogm", "ogv", "ogx", "osp", "par", "pds",
"pgi", "piv", "playlist", "pmf", "prel", "pro", "prproj", "psh",
"pva", "pvr", "pxv", "qt", "qtch", "qtl", "qtm", "qtz",
"rcproject", "rdb", "rec", "rm", "rmd", "rmp", "rmvb", "roq", "rp",
"rts", "rts", "rum", "rv", "sbk", "sbt", "scm", "scm", "scn",
"sec", "seq", "sfvidcap", "smil", "smk", "sml", "smv", "spl",
"ssm", "str", "stx", "svi", "swf", "swi", "swt", "tda3mt", "tivo",
"tix", "tod", "tp", "tp0", "tpd", "tpr", "trp", "ts", "tvs", "vc1",
"vcr", "vcv", "vdo", "vdr", "veg", "vem", "vf", "vfw", "vfz",
"vgz", "vid", "viewlet", "viv", "vivo", "vlab", "vob", "vp3",
"vp6", "vp7", "vpj", "vro", "vsp", "w32", "wcp", "webm", "wm",
"wmd", "wmmp", "wmv", "wmx", "wp3", "wpl", "wtv", "wvx", "xfl",
"xvid", "yuv", "zm1", "zm2", "zm3", "zmv" };
// http://www.fileinfo.com/filetypes/audio , "spx" , "mid" , "sf"
public static final String[] AUDIO_EXTENSIONS = { "4mp", "669", "6cm",
"8cm", "8med", "8svx", "a2m", "aa", "aa3", "aac", "aax", "abc",
"abm", "ac3", "acd", "acd-bak", "acd-zip", "acm", "act", "adg",
"afc", "agm", "ahx", "aif", "aifc", "aiff", "ais", "akp", "al",
"alaw", "all", "amf", "amr", "ams", "ams", "aob", "ape", "apf",
"apl", "ase", "at3", "atrac", "au", "aud", "aup", "avr", "awb",
"band", "bap", "bdd", "box", "bun", "bwf", "c01", "caf", "cda",
"cdda", "cdr", "cel", "cfa", "cidb", "cmf", "copy", "cpr", "cpt",
"csh", "cwp", "d00", "d01", "dcf", "dcm", "dct", "ddt", "dewf",
"df2", "dfc", "dig", "dig", "dls", "dm", "dmf", "dmsa", "dmse",
"drg", "dsf", "dsm", "dsp", "dss", "dtm", "dts", "dtshd", "dvf",
"dwd", "ear", "efa", "efe", "efk", "efq", "efs", "efv", "emd",
"emp", "emx", "esps", "f2r", "f32", "f3r", "f4a", "f64", "far",
"fff", "flac", "flp", "fls", "frg", "fsm", "fzb", "fzf", "fzv",
"g721", "g723", "g726", "gig", "gp5", "gpk", "gsm", "gsm", "h0",
"hdp", "hma", "hsb", "ics", "iff", "imf", "imp", "ins", "ins",
"it", "iti", "its", "jam", "k25", "k26", "kar", "kin", "kit",
"kmp", "koz", "koz", "kpl", "krz", "ksc", "ksf", "kt2", "kt3",
"ktp", "l", "la", "lqt", "lso", "lvp", "lwv", "m1a", "m3u", "m4a",
"m4b", "m4p", "m4r", "ma1", "mdl", "med", "mgv", "midi", "miniusf",
"mka", "mlp", "mmf", "mmm", "mmp", "mo3", "mod", "mp1", "mp2",
"mp3", "mpa", "mpc", "mpga", "mpu", "mp_", "mscx", "mscz", "msv",
"mt2", "mt9", "mte", "mti", "mtm", "mtp", "mts", "mus", "mws",
"mxl", "mzp", "nap", "nki", "nra", "nrt", "nsa", "nsf", "nst",
"ntn", "nvf", "nwc", "odm", "oga", "ogg", "okt", "oma", "omf",
"omg", "omx", "ots", "ove", "ovw", "pac", "pat", "pbf", "pca",
"pcast", "pcg", "pcm", "peak", "phy", "pk", "pla", "pls", "pna",
"ppc", "ppcx", "prg", "prg", "psf", "psm", "ptf", "ptm", "pts",
"pvc", "qcp", "r", "r1m", "ra", "ram", "raw", "rax", "rbs", "rcy",
"rex", "rfl", "rmf", "rmi", "rmj", "rmm", "rmx", "rng", "rns",
"rol", "rsn", "rso", "rti", "rtm", "rts", "rvx", "rx2", "s3i",
"s3m", "s3z", "saf", "sam", "sb", "sbg", "sbi", "sbk", "sc2", "sd",
"sd", "sd2", "sd2f", "sdat", "sdii", "sds", "sdt", "sdx", "seg",
"seq", "ses", "sf2", "sfk", "sfl", "shn", "sib", "sid", "sid",
"smf", "smp", "snd", "snd", "snd", "sng", "sng", "sou", "sppack",
"sprg", "sseq", "sseq", "ssnd", "stm", "stx", "sty", "svx", "sw",
"swa", "syh", "syw", "syx", "td0", "tfmx", "thx", "toc", "tsp",
"txw", "u", "ub", "ulaw", "ult", "ulw", "uni", "usf", "usflib",
"uw", "uwf", "vag", "val", "vc3", "vmd", "vmf", "vmf", "voc",
"voi", "vox", "vpm", "vqf", "vrf", "vyf", "w01", "wav", "wav",
"wave", "wax", "wfb", "wfd", "wfp", "wma", "wow", "wpk", "wproj",
"wrk", "wus", "wut", "wv", "wvc", "wve", "wwu", "xa", "xa", "xfs",
"xi", "xm", "xmf", "xmi", "xmz", "xp", "xrns", "xsb", "xspf", "xt",
"xwb", "ym", "zvd", "zvr" };
private static final HashSet mHashVideo;
private static final HashSet mHashAudio;
private static final double KB = 1024.0;
private static final double MB = KB * KB;
private static final double GB = KB * KB * KB;
static {
mHashVideo = new HashSet(Arrays.asList(VIDEO_EXTENSIONS));
mHashAudio = new HashSet(Arrays.asList(AUDIO_EXTENSIONS));
}
/** 是否是音频或者视频 */
public static boolean isVideoOrAudio(File f) {
final String ext = getFileExtension(f);
return mHashVideo.contains(ext) || mHashAudio.contains(ext);
}
public static boolean isVideoOrAudio(String f) {
final String ext = getUrlExtension(f);
return mHashVideo.contains(ext) || mHashAudio.contains(ext);
}
public static boolean isVideo(File f) {
final String ext = getFileExtension(f);
return mHashVideo.contains(ext);
}
/** 获取文件后缀 */
public static String getFileExtension(File f) {
if (f != null) {
String filename = f.getName();
int i = filename.lastIndexOf('.');
if (i > 0 && i < filename.length() - 1) {
return filename.substring(i + 1).toLowerCase();
}
}
return null;
}
public static String getUrlFileName(String url) {
int slashIndex = url.lastIndexOf('/');
int dotIndex = url.lastIndexOf('.');
String filenameWithoutExtension;
if (dotIndex == -1) {
filenameWithoutExtension = url.substring(slashIndex + 1);
} else {
filenameWithoutExtension = url.substring(slashIndex + 1, dotIndex);
}
return filenameWithoutExtension;
}
public static String getUrlExtension(String url) {
if (!StringUtils.isEmpty(url)) {
int i = url.lastIndexOf('.');
if (i > 0 && i < url.length() - 1) {
return url.substring(i + 1).toLowerCase();
}
}
return "";
}
public static String getFileNameNoEx(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot > -1) && (dot < (filename.length()))) {
return filename.substring(0, dot);
}
}
return filename;
}
public static String showFileSize(long size) {
String fileSize;
if (size < KB)
fileSize = size + "B";
else if (size < MB)
fileSize = String.format("%.1f", size / KB) + "KB";
else if (size < GB)
fileSize = String.format("%.1f", size / MB) + "MB";
else
fileSize = String.format("%.1f", size / GB) + "GB";
return fileSize;
}
/** 显示SD卡剩余空间 */
public static String showFileAvailable() {
String result = "";
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
StatFs sf = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
long blockSize = sf.getBlockSize();
long blockCount = sf.getBlockCount();
long availCount = sf.getAvailableBlocks();
return showFileSize(availCount * blockSize) + " / "
+ showFileSize(blockSize * blockCount);
}
return result;
}
/** 如果不存在就创建 */
public static boolean createIfNoExists(String path) {
File file = new File(path);
boolean mk = false;
if (!file.exists()) {
mk = file.mkdirs();
}
return mk;
}
private static HashMap mMimeType = new HashMap();
static {
mMimeType.put("M1V", "video/mpeg");
mMimeType.put("MP2", "video/mpeg");
mMimeType.put("MPE", "video/mpeg");
mMimeType.put("MPG", "video/mpeg");
mMimeType.put("MPEG", "video/mpeg");
mMimeType.put("MP4", "video/mp4");
mMimeType.put("M4V", "video/mp4");
mMimeType.put("3GP", "video/3gpp");
mMimeType.put("3GPP", "video/3gpp");
mMimeType.put("3G2", "video/3gpp2");
mMimeType.put("3GPP2", "video/3gpp2");
mMimeType.put("MKV", "video/x-matroska");
mMimeType.put("WEBM", "video/x-matroska");
mMimeType.put("MTS", "video/mp2ts");
mMimeType.put("TS", "video/mp2ts");
mMimeType.put("TP", "video/mp2ts");
mMimeType.put("WMV", "video/x-ms-wmv");
mMimeType.put("ASF", "video/x-ms-asf");
mMimeType.put("ASX", "video/x-ms-asf");
mMimeType.put("FLV", "video/x-flv");
mMimeType.put("MOV", "video/quicktime");
mMimeType.put("QT", "video/quicktime");
mMimeType.put("RM", "video/x-pn-realvideo");
mMimeType.put("RMVB", "video/x-pn-realvideo");
mMimeType.put("VOB", "video/dvd");
mMimeType.put("DAT", "video/dvd");
mMimeType.put("AVI", "video/x-divx");
mMimeType.put("OGV", "video/ogg");
mMimeType.put("OGG", "video/ogg");
mMimeType.put("VIV", "video/vnd.vivo");
mMimeType.put("VIVO", "video/vnd.vivo");
mMimeType.put("WTV", "video/wtv");
mMimeType.put("AVS", "video/avs-video");
mMimeType.put("SWF", "video/x-shockwave-flash");
mMimeType.put("YUV", "video/x-raw-yuv");
}
/** 获取MIME */
public static String getMimeType(String path) {
int lastDot = path.lastIndexOf(".");
if (lastDot < 0)
return null;
return mMimeType.get(path.substring(lastDot + 1).toUpperCase());
}
/** 多个SD卡时 取外置SD卡 */
public static String getExternalStorageDirectory() {
// 参考文章
// http://blog.csdn.net/bbmiku/article/details/7937745
Map map = System.getenv();
String[] values = new String[map.values().size()];
map.values().toArray(values);
String path = values[values.length - 1];
Log.e("nmbb", "FileUtils.getExternalStorageDirectory : " + path);
if (path.startsWith("/mnt/")
&& !Environment.getExternalStorageDirectory().getAbsolutePath()
.equals(path))
return path;
else
return null;
}
public static String getCanonical(File f) {
if (f == null)
return null;
try {
return f.getCanonicalPath();
} catch (IOException e) {
return f.getAbsolutePath();
}
}
public static boolean sdAvailable() {
return Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment
.getExternalStorageState())
|| Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState());
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/FractionalTouchDelegate.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.utils;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
/**
* {@link android.view.TouchDelegate} that gates {@link android.view.MotionEvent} instances by comparing
* then against fractional dimensions of the source view.
*
* This is particularly useful when you want to define a rectangle in terms of
* the source dimensions, but when those dimensions might change due to pending
* or future layout passes.
*
* One example is catching touches that occur in the top-right quadrant of
* {@code sourceParent}, and relaying them to {@code targetChild}. This could be
* done with:
* FractionalTouchDelegate.setupDelegate(sourceParent, targetChild, new RectF(0.5f, 0f, 1f, 0.5f));
*
*/
public class FractionalTouchDelegate extends TouchDelegate {
private View mSource;
private View mTarget;
private RectF mSourceFraction;
private Rect mScrap = new Rect();
/** Cached full dimensions of {@link #mSource}. */
private Rect mSourceFull = new Rect();
/** Cached projection of {@link #mSourceFraction} onto {@link #mSource}. */
private Rect mSourcePartial = new Rect();
private boolean mDelegateTargeted;
public FractionalTouchDelegate(View source, View target, RectF sourceFraction) {
super(new Rect(0, 0, 0, 0), target);
mSource = source;
mTarget = target;
mSourceFraction = sourceFraction;
}
/**
* Helper to create and setup a {@link com.cjj.bb.utils.FractionalTouchDelegate} between the
* given {@link android.view.View}.
*
* @param source Larger source {@link android.view.View}, usually a parent, that will be
* assigned {@link android.view.View#setTouchDelegate(android.view.TouchDelegate)}.
* @param target Smaller target {@link android.view.View} which will receive
* {@link android.view.MotionEvent} that land in requested fractional area.
* @param sourceFraction Fractional area projected onto source {@link android.view.View}
* which determines when {@link android.view.MotionEvent} will be passed to
* target {@link android.view.View}.
*/
public static void setupDelegate(View source, View target, RectF sourceFraction) {
source.setTouchDelegate(new FractionalTouchDelegate(source, target, sourceFraction));
}
/**
* Consider updating {@link #mSourcePartial} when {@link #mSource}
* dimensions have changed.
*/
private void updateSourcePartial() {
mSource.getHitRect(mScrap);
if (!mScrap.equals(mSourceFull)) {
// Copy over and calculate fractional rectangle
mSourceFull.set(mScrap);
final int width = mSourceFull.width();
final int height = mSourceFull.height();
mSourcePartial.left = (int) (mSourceFraction.left * width);
mSourcePartial.top = (int) (mSourceFraction.top * height);
mSourcePartial.right = (int) (mSourceFraction.right * width);
mSourcePartial.bottom = (int) (mSourceFraction.bottom * height);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
updateSourcePartial();
// The logic below is mostly copied from the parent class, since we
// can't update private mBounds variable.
// http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;
// f=core/java/android/view/TouchDelegate.java;hb=eclair#l98
final Rect sourcePartial = mSourcePartial;
final View target = mTarget;
int x = (int)event.getX();
int y = (int)event.getY();
boolean sendToDelegate = false;
boolean hit = true;
boolean handled = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (sourcePartial.contains(x, y)) {
mDelegateTargeted = true;
sendToDelegate = true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
sendToDelegate = mDelegateTargeted;
if (sendToDelegate) {
if (!sourcePartial.contains(x, y)) {
hit = false;
}
}
break;
case MotionEvent.ACTION_CANCEL:
sendToDelegate = mDelegateTargeted;
mDelegateTargeted = false;
break;
}
if (sendToDelegate) {
if (hit) {
event.setLocation(target.getWidth() / 2, target.getHeight() / 2);
} else {
event.setLocation(-1, -1);
}
handled = target.dispatchTouchEvent(event);
}
return handled;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/HttpDownloader.java
================================================
package com.cjj.bb.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.http.util.EncodingUtils;
import android.util.Log;
import android.util.Xml.Encoding;
public class HttpDownloader {
private URL url = null;
/**
* 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容
* 1.创建一个URL对象
* 2.通过URL对象,创建一个HttpURLConnection对象
* 3.得到InputStram
* 4.从InputStream当中读取数据
*
* @param urlStr
* @return
*/
public String download(String urlstr) {
StringBuffer sb = new StringBuffer();
String line = null;
BufferedReader buffer = null;
String xmlString = "";
try {
// 创建一个URL对象
url = new URL(urlstr);
// 创建一个Http连接
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection();
// 使用IO流读取数据
buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream(),"utf-8")); // 防止中文出现乱码 gb2312 utf-8
for(String temp = buffer.readLine(); temp != null;xmlString += temp ,temp = buffer.readLine());
// 去除字符串中的换行符,制表符,回车符。
xmlString = xmlString.replaceAll("/n|/t|/r", "");
// while ((line = buffer.readLine()) != null) {
// sb.append(line);
// }
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
buffer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return xmlString;
}
/**
* 可以下载字节流文件到SD卡中
*
* @param urlstr 要下载文件的URI地址
* @param Path 在SD卡上文件夹的路径
* @param FileName 在SD卡上文件的名称
* @return 该函数返回整型:-1代表下载失败,0代表下载成功,1代表文件已经存在
*/
public int download(String urlstr, String Path, String FileName) {
InputStream inputstream = null;
BufferedReader buffer = null;
try {
FileUitl fileUitls = new FileUitl();
System.out.println(Path + FileName);
if (fileUitls.isFileExist(Path + FileName)) {
return 1;
} else {
// 获取URI中的字节流
inputstream = getInputStreamFromUrl(urlstr);
// 把字节流转换成字符流
buffer = new BufferedReader(new InputStreamReader(inputstream,
"gb2312")); // 防止中文出现乱码 UTF-8
File resultFile = fileUitls.write2SDFromWrite(Path, FileName,
buffer);
if (resultFile == null) {
return -1;
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return -1;
} finally {
try {
if(buffer != null)
buffer.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return 0;
}
/**
* 可以下载字符流和字节流文件到SD卡中
*
* @param urlstr
* @param Path
* @param FileName
* @return 该函数返回整型:-1代表下载失败,0代表下载成功,1代表文件已经存在
*/
public int downFile(String urlstr, String Path, String FileName) {
InputStream inputstream = null;
try {
FileUitl fileUitls = new FileUitl();
if (fileUitls.isFileExist(Path + FileName)) {
return 1;
} else {
inputstream = getInputStreamFromUrl(urlstr);
File resultFile = fileUitls.write2SDFromInput(Path, FileName,
inputstream);
if (resultFile == null) {
return -1;
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return -1;
} finally {
try {
inputstream.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return 0;
}
/**
* 根据URL得到输入流
*
* @param urlstr
* @return
* @throws java.net.MalformedURLException
* @throws java.io.IOException
*/
private InputStream getInputStreamFromUrl(String urlstr)
throws MalformedURLException, IOException {
// TODO Auto-generated method stub
url = new URL(urlstr);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConn.getInputStream();
return inputStream;
}
// 以下是测试字符编码的
public static void testCharset(String datastr){
try {
String temp = new String(datastr.getBytes(), "GBK");
Log.v("TestCharset","****** getBytes() -> GBK ******/n"+temp);
temp = new String(datastr.getBytes("GBK"), "UTF-8");
Log.v("TestCharset","****** GBK -> UTF-8 *******/n"+temp);
temp = new String(datastr.getBytes("GBK"), "ISO-8859-1");
Log.v("TestCharset","****** GBK -> ISO-8859-1 *******/n"+temp);
temp = new String(datastr.getBytes("ISO-8859-1"), "UTF-8");
Log.v("TestCharset","****** ISO-8859-1 -> UTF-8 *******/n"+temp);
temp = new String(datastr.getBytes("ISO-8859-1"), "GBK");
Log.v("TestCharset","****** ISO-8859-1 -> GBK *******/n"+temp);
temp = new String(datastr.getBytes("UTF-8"), "GBK");
Log.v("TestCharset","****** UTF-8 -> GBK *******/n"+temp);
temp = new String(datastr.getBytes("UTF-8"), "ISO-8859-1");
Log.v("TestCharset","****** UTF-8 -> ISO-8859-1 *******/n"+temp);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/HttpUtil.java
================================================
package com.cjj.bb.utils;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.DataFormatException;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.http.Header;
import org.apache.http.HttpClientConnection;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ProtocolException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.RedirectHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.ByteArrayBuffer;
import org.apache.http.util.EncodingUtils;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.helper.HttpConnection.Response;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class HttpUtil {
public static String cookieName = "";
public static String cookieValue = "";
public static String hostBase = "";
public static String getHtmlString(String urlString) {
try {
URL url = new URL(urlString);
URLConnection ucon = url.openConnection();
InputStream instr = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(instr);
ByteArrayBuffer baf = new ByteArrayBuffer(500);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
return EncodingUtils.getString(baf.toByteArray(), "utf-8");
} catch (Exception e) {
Log.d("win","lllll"+e.toString());
return "";
}
}
public static String getXmlDecompress(String urlString) {
Response rsp = null;
String temp = "";
try {
rsp = (Response) Jsoup.connect(urlString).execute();
temp = EncodingUtils.getString(CompressionTools.decompressXML(rsp.bodyAsBytes()), "utf-8");
Log.d("TAG","=======>Xml解压成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("TAG","=======>Xml解压失败:"+e.toString());
} catch (DataFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("TAG","=======>Xml解压失败:"+e.toString());
}
return temp;
}
public static String sendPost(String url, String params)
{
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try
{
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(params); //②
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
result += "\n" + line;
}
}
catch (Exception e)
{
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally
{
try
{
if (out != null)
{
out.close();
}
if (in != null)
{
in.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
return result;
}
public static String httpGetHost(String url) {
HttpGet httpget = new HttpGet(url);
String strResult = "";
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpClient httpclient;
try {
httpclient = new DefaultHttpClient(httpParams);
HttpResponse response = httpclient.execute(httpget);
System.out.println(response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(response.getEntity(),
HTTP.UTF_8);
}
} catch (ConnectException e) {
e.printStackTrace();
System.out.println("hosterror");
} catch (ClientProtocolException e) {
System.out.println("Client");
e.printStackTrace();
} catch (IOException e) {
System.out.println("IO");
e.printStackTrace();
}
return strResult;
}
public static String httpGet(String url) {
System.out.println("httpGet" + url);
HttpGet httpget = new HttpGet(url);
String strResult = null;
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient httpclient;
try {
httpclient = new DefaultHttpClient(httpParams);
httpget.setHeader("Cookie", cookieName + "=" + cookieValue);
HttpResponse response = httpclient.execute(httpget);
System.out.println(response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(response.getEntity(),
HTTP.UTF_8);
// System.out.println(strResult);
System.out.println("getFinish");
}
} catch (ConnectException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
System.out.println("Client");
e.printStackTrace();
} catch (IOException e) {
System.out.println("IO");
e.printStackTrace();
}
return strResult;
}
public static String httpGetNoResult(String url) {
System.out.println("httpGetNo" + url);
HttpGet httpget = new HttpGet(hostBase + url);
String strResult = "";
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient httpclient;
try {
httpclient = new DefaultHttpClient(httpParams);
httpget.setHeader("Cookie", cookieName + "=" + cookieValue);
HttpResponse response = httpclient.execute(httpget);
System.out.println(response.getStatusLine().getStatusCode());
/*
* if(response.getStatusLine().getStatusCode() == 200){ strResult =
* EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
* System.out.println(strResult); System.out.println("getFinish"); }
*/
} catch (Exception e) {
e.printStackTrace();
strResult = "error";
}
return strResult;
}
public static Bitmap HttpGetBmp(String url) {
HttpGet httpget = new HttpGet(url);
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
Bitmap bitmap = null;
try {
HttpClient httpclient = new DefaultHttpClient(httpParams);
HttpResponse response = httpclient.execute(httpget);
InputStream is = response.getEntity().getContent();
byte[] bytes = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int count = 0;
while ((count = is.read(bytes)) != -1) {
System.out.println("readBitmap");
bos.write(bytes, 0, count);
}
byte[] byteArray = bos.toByteArray();
bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
byteArray.length);
is.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
public static InputStream HttpGetBmpInputStream(String url) {
HttpGet httpget = new HttpGet(url);
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
InputStream is = null;
try {
HttpClient httpclient = new DefaultHttpClient(httpParams);
HttpResponse response = httpclient.execute(httpget);
is = response.getEntity().getContent();
} catch (Exception e) {
e.printStackTrace();
}
return is;
}
public static Integer GetCookie(String url, String number, String pw,
String select, String host) {
System.out.println("GetCookie");
int result = 4;
HttpPost httpPost = new HttpPost(hostBase + url);
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("number", number));
nvps.add(new BasicNameValuePair("passwd", pw));
nvps.add(new BasicNameValuePair("select", select));
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
try {
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
httpClient.setRedirectHandler(new RedirectHandler() {
@Override
public boolean isRedirectRequested(HttpResponse response,
HttpContext context) {
return false;
}
@Override
public URI getLocationURI(HttpResponse response,
HttpContext context) throws ProtocolException {
return null;
}
});
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = httpClient.execute(httpPost);
System.out.println(response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == 200) {
return 2;
} else if (response.getStatusLine().getStatusCode() == 302) {
Header[] headers = response.getHeaders("Location");
if (headers != null && headers.length > 0) {
List list = httpClient.getCookieStore()
.getCookies();
for (Cookie c : list) {
cookieName = c.getName();
cookieValue = c.getValue();
}
System.out.println(cookieName + cookieValue);
return 3;
}
} else if (response.getStatusLine().getStatusCode() == 404) {
return -1;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String httpGetCookie(String url) {
System.out.println("httpGetCookie" + url);
HttpGet httpget = new HttpGet(hostBase + url);
String strResult = "";
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 15000);
HttpConnectionParams.setSoTimeout(httpParams, 15000);
try {
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
httpClient.setRedirectHandler(new RedirectHandler() {
@Override
public boolean isRedirectRequested(HttpResponse response,
HttpContext context) {
return false;
}
@Override
public URI getLocationURI(HttpResponse response,
HttpContext context) throws ProtocolException {
return null;
}
});
httpget.setHeader("Cookie", cookieName + "=" + cookieValue);
HttpResponse response = httpClient.execute(httpget);
if (response.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(response.getEntity(),
HTTP.UTF_8);
} else if (response.getStatusLine().getStatusCode() == 302) {
strResult = "302"; // cookieʧЧ�������ض����־�������µ�¼��ȡ
} else if (response.getStatusLine().getStatusCode() == 404) {
strResult = "-1";
}
} catch (Exception e) {
e.printStackTrace();
strResult = "4";
}
return strResult;
}
public static String httpPostCookie(String url, String id, String data) {
System.out.println("httpPostCookie" + url);
String result = "4";
HttpPost httpPost = new HttpPost(hostBase + url);
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("marc_no", id));
nvps.add(new BasicNameValuePair("r_content", data));
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
try {
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
httpClient.setRedirectHandler(new RedirectHandler() {
@Override
public boolean isRedirectRequested(HttpResponse response,
HttpContext context) {
return false;
}
@Override
public URI getLocationURI(HttpResponse response,
HttpContext context) throws ProtocolException {
return null;
}
});
httpPost.setHeader("Cookie", cookieName + "=" + cookieValue);
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = httpClient.execute(httpPost);
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(EntityUtils.toString(response.getEntity(),
HTTP.UTF_8) + "add");
if (response.getStatusLine().getStatusCode() == 200) {
return "2";
} else if (response.getStatusLine().getStatusCode() == 302) {
Header[] headers = response.getHeaders("Location");
if (headers != null && headers.length > 0) {
System.out.println(headers[0].getValue());
return "3";
}
} else if (response.getStatusLine().getStatusCode() == 404) {
return "-1";
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static int getCookie(String url) {
System.out.println("getCookie" + url);
HttpGet httpGet = new HttpGet(hostBase + url);
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.setRedirectHandler(new RedirectHandler() {
@Override
public boolean isRedirectRequested(HttpResponse response,
HttpContext context) {
return false;
}
@Override
public URI getLocationURI(HttpResponse response,
HttpContext context) throws ProtocolException {
return null;
}
});
HttpResponse response = httpClient.execute(httpGet);
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(EntityUtils.toString(response.getEntity(),
HTTP.UTF_8) + "add");
if (response.getStatusLine().getStatusCode() == 200) {
Header[] heads = response.getAllHeaders();
System.out.println(heads.length);
for (Header header : heads) {
System.out.println(header.getName() + " = "
+ header.getValue());
}
return 2;
} else if (response.getStatusLine().getStatusCode() == 302) {
Header[] headers = response.getHeaders("Location");
if (headers != null && headers.length > 0) {
System.out.println(headers[0].getValue());
return 3;
}
} else if (response.getStatusLine().getStatusCode() == 404) {
return -1;
}
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/ImageUtils.java
================================================
package com.cjj.bb.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
public class ImageUtils {
// http://zhuixinjian.javaeye.com/blog/743672
// 图片圆角
// 图片叠加
// 图片缩放
// 图片旋转
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public static int getBitmapSize(Bitmap bitmap) {
if (DeviceUtils.hasHoneycombMR1()) {
return bitmap.getByteCount();
}
// Pre HC-MR1
return bitmap.getRowBytes() * bitmap.getHeight();
}
/** 旋转图片 */
public static Bitmap rotate(Bitmap b, int degrees) {
if (degrees != 0 && b != null) {
Matrix m = new Matrix();
m.setRotate(degrees, (float) b.getWidth() / 2,
(float) b.getHeight() / 2);
try {
Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
b.getHeight(), m, true);
if (b != b2) {
b.recycle();
b = b2;
}
} catch (OutOfMemoryError ex) {
Logger.e(ex);
} catch (Exception ex) {
Logger.e(ex);
}
}
return b;
}
/**
* Decode and sample down a bitmap from a file to the requested width and
* height.
*
* @param filename
* The full path of the file to decode
* @param reqWidth
* The requested width of the resulting bitmap
* @param reqHeight
* The requested height of the resulting bitmap
* @return A bitmap sampled down from the original with the same aspect
* ratio and dimensions that are equal to or greater than the
* requested width and height
*/
public static synchronized Bitmap decodeSampledBitmapFromFile(
String filename, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
/**
* Calculate an inSampleSize for use in a
* {@link android.graphics.BitmapFactory.Options} object when decoding
* bitmaps using the decode* methods from {@link android.graphics.BitmapFactory}. This
* implementation calculates the closest inSampleSize that will result in
* the final decoded bitmap having a width and height equal to or larger
* than the requested width and height. This implementation does not ensure
* a power of 2 is returned for inSampleSize which can be faster when
* decoding but results in a larger bitmap which isn't as useful for caching
* purposes.
*
* @param options
* An options object with out* params already populated (run
* through a decode* method with inJustDecodeBounds==true
* @param reqWidth
* The requested width of the resulting bitmap
* @param reqHeight
* The requested height of the resulting bitmap
* @return The value to be used for inSampleSize
*/
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger
// inSampleSize).
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down
// further.
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
public static boolean saveBitmap(String path, Bitmap bitmap) {
return saveBitmap(new File(path), bitmap);
}
/** 保存图片到文件 */
public static boolean saveBitmap(File f, Bitmap bitmap) {
if (bitmap == null || bitmap.isRecycled())
return false;
FileOutputStream fOut = null;
try {
if (f.exists())
f.createNewFile();
fOut = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
return true;
} catch (FileNotFoundException e) {
Logger.e(e);
} catch (IOException e) {
Logger.e(e);
} catch (Exception e) {
Logger.e(e);
} finally {
if (fOut != null) {
try {
fOut.close();
} catch (IOException e) {
Logger.e(e);
}
}
}
return false;
}
public static Bitmap decodeUriAsBitmap(Context ctx, Uri uri) {
Bitmap bitmap = null;
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// options.outWidth = reqWidth;
// options.outHeight = reqHeight;
BitmapFactory.decodeStream(ctx.getContentResolver()
.openInputStream(uri), null, options);
Logger.i("orgi:" + options.outWidth + "x" + options.outHeight);
int be = (int) (options.outHeight / (float) 350);
if (be <= 0)
be = 1;
options.inSampleSize = be;// calculateInSampleSize(options,
// reqWidth, reqHeight);
Logger.i("inSampleSize:" + options.inSampleSize);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(ctx.getContentResolver()
.openInputStream(uri), null, options);
} catch (FileNotFoundException e) {
Logger.e(e);
} catch (OutOfMemoryError e) {
Logger.e(e);
}
return bitmap;
}
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
matrix, true);
return newbmp;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888
: Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
/**
* 获取图片圆角
*
* @param bitmap
* @param roundPx
* 圆角度数
* @return
*/
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* 转行Drawable为Bitmap对象
*
* @param drawable
* @return
*/
public static Bitmap toBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888
: Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
/**
* 缩放图片
*
* @param src
* 缩放原图
* @param dstWidth
* 缩放后宽
* @param dstHeight
* 缩放后高
* @return
*/
public static Bitmap scaledBitmap(Bitmap src, int dstWidth, int dstHeight) {
// 原图不能为空也不能已经被回收掉了
Bitmap result = null;
if (src != null && !src.isRecycled()) {
if (src.getWidth() == dstWidth && src.getHeight() == dstHeight) {
result = src;
} else {
result = Bitmap.createScaledBitmap(src, dstWidth, dstHeight,
true);
}
}
// ThumbnailUtils.extractThumbnail(source, width, height)
return result;
}
/**
* 按比例缩放图片
*
* @param src
* @param scale
* 例如2 就是二分之一
* @return
*/
public static Bitmap scaledBitmap(Bitmap src, int scale) {
if (src == null || src.isRecycled()) {
return null;
}
int dstWidth = src.getWidth() / scale;
int dstHeight = src.getHeight() / scale;
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);
}
/**
* 将图片转换成字节数组
*
* @param bitmap
* @return
*/
public static byte[] toBytes(Bitmap bitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
return outputStream.toByteArray();
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/IntentHelper.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.utils;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Parcelable;
import android.text.Html;
import io.vov.vitamio.utils.Log;
public final class IntentHelper {
public static final String MEDIA_PATTERN = "(http[s]?://)+([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?";
private static final Pattern mMediaPattern;
static {
mMediaPattern = Pattern.compile(MEDIA_PATTERN);
}
public static Uri getIntentUri(Intent intent) {
Uri result = null;
if (intent != null) {
result = intent.getData();
if (result == null) {
final String type = intent.getType();
String sharedUrl = intent.getStringExtra(Intent.EXTRA_TEXT);
if (!StringUtils.isEmpty(sharedUrl)) {
if ("text/plain".equals(type) && sharedUrl != null) {
result = getTextUri(sharedUrl);
} else if ("text/html".equals(type) && sharedUrl != null) {
result = getTextUri(Html.fromHtml(sharedUrl).toString());
}
} else {
Parcelable parce = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (parce != null)
result = (Uri) parce;
}
}
}
return result;
}
private static Uri getTextUri(String sharedUrl) {
Matcher matcher = mMediaPattern.matcher(sharedUrl);
if (matcher.find()) {
sharedUrl = matcher.group();
if (!StringUtils.isEmpty(sharedUrl)) {
return Uri.parse(sharedUrl);
}
}
return null;
}
public static boolean existPackage(final Context ctx, String packageName) {
if (!StringUtils.isEmpty(packageName)) {
for (PackageInfo p : ctx.getPackageManager().getInstalledPackages(0)) {
if (packageName.equals(p.packageName))
return true;
}
}
return false;
}
public static void startApkActivity(final Context ctx, String packageName) {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(packageName, 0);
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setPackage(pi.packageName);
List apps = pm.queryIntentActivities(intent, 0);
ResolveInfo ri = apps.iterator().next();
if (ri != null) {
String className = ri.activityInfo.name;
intent.setComponent(new ComponentName(packageName, className));
ctx.startActivity(intent);
}
} catch (NameNotFoundException e) {
Log.e("startActivity", e);
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/JsoupUtil.java
================================================
package com.cjj.bb.utils;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
*
* @author wwj_748
* @date 2014/8/10
*/
public class JsoupUtil {
public static boolean contentFirstPage = true; // 第一页
public static boolean contentLastPage = true; // 最后一页
public static boolean multiPages = false; // 多页
private static final String BILIBILI_HOMEPAGE_URL = "http://www.bilibili.com/mobile/index.html"; // bilibili首页地址
public static void resetPages() {
contentFirstPage = true;
contentLastPage = true;
multiPages = false;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/Logger.java
================================================
package com.cjj.bb.utils;
import android.util.Log;
public class Logger {
private static boolean isLog = true;
private static final String TAG = "ABPlayer";
public static void setLog(boolean isLog) {
Logger.isLog = isLog;
}
public static boolean getIsLog() {
return isLog;
}
public static void d(String tag, String msg) {
if (isLog) {
Log.d(tag, msg);
}
}
public static void d(String msg) {
Log.d(TAG, msg);
}
/**
* Send a {@link #DEBUG} log message and log the exception.
*
* @param tag Used to identify the source of a log message. It usually
* identifies the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void d(String tag, String msg, Throwable tr) {
if (isLog) {
Log.d(tag, msg, tr);
}
}
public static void e(Throwable tr) {
if (isLog) {
Log.e(TAG, "", tr);
}
}
public static void i(String msg) {
if (isLog) {
Log.i(TAG, msg);
}
}
public static void i(String tag, String msg) {
if (isLog) {
Log.i(tag, msg);
}
}
/**
* Send a {@link #INFO} log message and log the exception.
*
* @param tag Used to identify the source of a log message. It usually
* identifies the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void i(String tag, String msg, Throwable tr) {
if (isLog) {
Log.i(tag, msg, tr);
}
}
/**
* Send an {@link #ERROR} log message.
*
* @param tag Used to identify the source of a log message. It usually
* identifies the class or activity where the log call occurs.
* @param msg The message you would like logged.
*/
public static void e(String tag, String msg) {
if (isLog) {
Log.e(tag, msg);
}
}
public static void e(String msg) {
if (isLog) {
Log.e(TAG, msg);
}
}
/**
* Send a {@link #ERROR} log message and log the exception.
*
* @param tag Used to identify the source of a log message. It usually
* identifies the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static void e(String tag, String msg, Throwable tr) {
if (isLog) {
Log.e(tag, msg, tr);
}
}
public static void e(String msg, Throwable tr) {
if (isLog) {
Log.e(TAG, msg, tr);
}
}
public static void systemErr(String msg) {
// if (true) {
if (isLog) {
if (msg != null) {
Log.e(TAG, msg);
}
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/MediaUtils.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.utils;
import java.io.File;
import java.util.regex.Pattern;
import android.net.Uri;
public final class MediaUtils {
public static final String[] EXTENSIONS;
// http://www.fileinfo.com/filetypes/video
public static final String[] VIDEO_EXTENSIONS = { "\\.264", "\\.3g2", "\\.3gp", "\\.3gp2", "\\.3gpp", "\\.3gpp2", "\\.3mm", "\\.3p2", "\\.60d", "\\.aep", "\\.ajp", "\\.amv", "\\.amx", "\\.arf", "\\.asf", "\\.asx", "\\.avb", "\\.avd", "\\.avi", "\\.avs", "\\.avs", "\\.axm", "\\.bdm", "\\.bdmv", "\\.bik", "\\.bin", "\\.bix", "\\.bmk", "\\.box", "\\.bs4", "\\.bsf", "\\.byu", "\\.camre", "\\.clpi", "\\.cpi", "\\.cvc", "\\.d2v", "\\.d3v", "\\.dat", "\\.dav", "\\.dce", "\\.dck", "\\.ddat", "\\.dif", "\\.dir", "\\.divx", "\\.dlx", "\\.dmb", "\\.dmsm", "\\.dmss", "\\.dnc", "\\.dpg", "\\.dream", "\\.dsy", "\\.dv", "\\.dv-avi", "\\.dv4", "\\.dvdmedia", "\\.dvr-ms", "\\.dvx", "\\.dxr", "\\.dzm", "\\.dzp", "\\.dzt", "\\.evo", "\\.eye", "\\.f4p", "\\.f4v", "\\.fbr", "\\.fbr", "\\.fbz", "\\.fcp", "\\.flc", "\\.flh", "\\.fli", "\\.flv", "\\.flx", "\\.gl", "\\.grasp", "\\.gts", "\\.gvi", "\\.gvp", "\\.hdmov", "\\.hkm", "\\.ifo", "\\.imovi", "\\.imovi", "\\.iva", "\\.ivf", "\\.ivr", "\\.ivs", "\\.izz", "\\.izzy", "\\.jts", "\\.lsf", "\\.lsx", "\\.m15", "\\.m1pg", "\\.m1v", "\\.m21", "\\.m21", "\\.m2a", "\\.m2p", "\\.m2t", "\\.m2ts", "\\.m2v", "\\.m4e", "\\.m4u", "\\.m4v", "\\.m75", "\\.meta", "\\.mgv", "\\.mj2", "\\.mjp", "\\.mjpg", "\\.mkv", "\\.mmv", "\\.mnv", "\\.mod", "\\.modd", "\\.moff", "\\.moi", "\\.moov", "\\.mov", "\\.movie", "\\.mp21", "\\.mp21", "\\.mp2v", "\\.mp4", "\\.mp4v", "\\.mpe", "\\.mpeg", "\\.mpeg4", "\\.mpf", "\\.mpg", "\\.mpg2", "\\.mpgin", "\\.mpl", "\\.mpls", "\\.mpv", "\\.mpv2", "\\.mqv", "\\.msdvd", "\\.msh", "\\.mswmm", "\\.mts", "\\.mtv", "\\.mvb", "\\.mvc", "\\.mvd", "\\.mve", "\\.mvp", "\\.mxf", "\\.mys", "\\.ncor", "\\.nsv", "\\.nvc", "\\.ogm", "\\.ogv", "\\.ogx", "\\.osp", "\\.par", "\\.pds", "\\.pgi", "\\.piv", "\\.playlist", "\\.pmf", "\\.prel", "\\.pro", "\\.prproj", "\\.psh", "\\.pva", "\\.pvr", "\\.pxv", "\\.qt", "\\.qtch", "\\.qtl", "\\.qtm", "\\.qtz", "\\.rcproject", "\\.rdb", "\\.rec", "\\.rm", "\\.rmd", "\\.rmp", "\\.rms", "\\.rmvb", "\\.roq", "\\.rp", "\\.rts", "\\.rts", "\\.rum", "\\.rv", "\\.sbk", "\\.sbt", "\\.scm", "\\.scm", "\\.scn", "\\.sec", "\\.seq", "\\.sfvidcap", "\\.smil", "\\.smk", "\\.sml", "\\.smv", "\\.spl", "\\.ssm", "\\.str", "\\.stx", "\\.svi", "\\.swf", "\\.swi", "\\.swt", "\\.tda3mt", "\\.tivo", "\\.tix", "\\.tod", "\\.tp", "\\.tp0", "\\.tpd", "\\.tpr", "\\.trp", "\\.ts", "\\.tvs", "\\.vc1", "\\.vcr", "\\.vcv", "\\.vdo", "\\.vdr", "\\.veg", "\\.vem", "\\.vf", "\\.vfw", "\\.vfz", "\\.vgz", "\\.vid", "\\.viewlet", "\\.viv", "\\.vivo", "\\.vlab", "\\.vob", "\\.vp3", "\\.vp6", "\\.vp7", "\\.vpj", "\\.vro", "\\.vsp", "\\.w32", "\\.wcp", "\\.webm", "\\.wm", "\\.wmd", "\\.wmmp", "\\.wmv", "\\.wmx", "\\.wp3", "\\.wpl", "\\.wtv", "\\.wvx", "\\.xfl", "\\.xvid", "\\.yuv", "\\.zm1", "\\.zm2", "\\.zm3", "\\.zmv" };
// http://www.fileinfo.com/filetypes/audio
public static final String[] AUDIO_EXTENSIONS = { "\\.4mp", "\\.669", "\\.6cm", "\\.8cm", "\\.8med", "\\.8svx", "\\.a2m", "\\.aa", "\\.aa3", "\\.aac", "\\.aax", "\\.abc", "\\.abm", "\\.ac3", "\\.acd", "\\.acd-bak", "\\.acd-zip", "\\.acm", "\\.act", "\\.adg", "\\.afc", "\\.agm", "\\.ahx", "\\.aif", "\\.aifc", "\\.aiff", "\\.ais", "\\.akp", "\\.al", "\\.alaw", "\\.all", "\\.amf", "\\.amr", "\\.ams", "\\.ams", "\\.aob", "\\.ape", "\\.apf", "\\.apl", "\\.ase", "\\.at3", "\\.atrac", "\\.au", "\\.aud", "\\.aup", "\\.avr", "\\.awb", "\\.band", "\\.bap", "\\.bdd", "\\.box", "\\.bun", "\\.bwf", "\\.c01", "\\.caf", "\\.cda", "\\.cdda", "\\.cdr", "\\.cel", "\\.cfa", "\\.cidb", "\\.cmf", "\\.copy", "\\.cpr", "\\.cpt", "\\.csh", "\\.cwp", "\\.d00", "\\.d01", "\\.dcf", "\\.dcm", "\\.dct", "\\.ddt", "\\.dewf", "\\.df2", "\\.dfc", "\\.dig", "\\.dig", "\\.dls", "\\.dm", "\\.dmf", "\\.dmsa", "\\.dmse", "\\.drg", "\\.dsf", "\\.dsm", "\\.dsp", "\\.dss", "\\.dtm", "\\.dts", "\\.dtshd", "\\.dvf", "\\.dwd", "\\.ear", "\\.efa", "\\.efe", "\\.efk", "\\.efq", "\\.efs", "\\.efv", "\\.emd", "\\.emp", "\\.emx", "\\.esps", "\\.f2r", "\\.f32", "\\.f3r", "\\.f4a", "\\.f64", "\\.far", "\\.fff", "\\.flac", "\\.flp", "\\.fls", "\\.frg", "\\.fsm", "\\.fzb", "\\.fzf", "\\.fzv", "\\.g721", "\\.g723", "\\.g726", "\\.gig", "\\.gp5", "\\.gpk", "\\.gsm", "\\.gsm", "\\.h0", "\\.hdp", "\\.hma", "\\.hsb", "\\.ics", "\\.iff", "\\.imf", "\\.imp", "\\.ins", "\\.ins", "\\.it", "\\.iti", "\\.its", "\\.jam", "\\.k25", "\\.k26", "\\.kar", "\\.kin", "\\.kit", "\\.kmp", "\\.koz", "\\.koz", "\\.kpl", "\\.krz", "\\.ksc", "\\.ksf", "\\.kt2", "\\.kt3", "\\.ktp", "\\.l", "\\.la", "\\.lqt", "\\.lso", "\\.lvp", "\\.lwv", "\\.m1a", "\\.m3u", "\\.m4a", "\\.m4b", "\\.m4p", "\\.m4r", "\\.ma1", "\\.mdl", "\\.med", "\\.mgv", "\\.mid", "\\.midi", "\\.miniusf", "\\.mka", "\\.mlp", "\\.mmf", "\\.mmm", "\\.mmp", "\\.mo3", "\\.mod", "\\.mp1", "\\.mp2", "\\.mp3", "\\.mpa", "\\.mpc", "\\.mpga", "\\.mpu", "\\.mp_", "\\.mscx", "\\.mscz", "\\.msv", "\\.mt2", "\\.mt9", "\\.mte", "\\.mti", "\\.mtm", "\\.mtp", "\\.mts", "\\.mus", "\\.mws", "\\.mxl", "\\.mzp", "\\.nap", "\\.nki", "\\.nra", "\\.nrt", "\\.nsa", "\\.nsf", "\\.nst", "\\.ntn", "\\.nvf", "\\.nwc", "\\.odm", "\\.oga", "\\.ogg", "\\.okt", "\\.oma", "\\.omf", "\\.omg", "\\.omx", "\\.ots", "\\.ove", "\\.ovw", "\\.pac", "\\.pat", "\\.pbf", "\\.pca", "\\.pcast", "\\.pcg", "\\.pcm", "\\.peak", "\\.phy", "\\.pk", "\\.pla", "\\.pls", "\\.pna", "\\.ppc", "\\.ppcx", "\\.prg", "\\.prg", "\\.psf", "\\.psm", "\\.ptf", "\\.ptm", "\\.pts", "\\.pvc", "\\.qcp", "\\.r", "\\.r1m", "\\.ra", "\\.ram", "\\.raw", "\\.rax", "\\.rbs", "\\.rcy", "\\.rex", "\\.rfl", "\\.rmf", "\\.rmi", "\\.rmj", "\\.rmm", "\\.rmx", "\\.rng", "\\.rns", "\\.rol", "\\.rsn", "\\.rso", "\\.rti", "\\.rtm", "\\.rts", "\\.rvx", "\\.rx2", "\\.s3i", "\\.s3m", "\\.s3z", "\\.saf", "\\.sam", "\\.sb", "\\.sbg", "\\.sbi", "\\.sbk", "\\.sc2", "\\.sd", "\\.sd", "\\.sd2", "\\.sd2f", "\\.sdat", "\\.sdii", "\\.sds", "\\.sdt", "\\.sdx", "\\.seg", "\\.seq", "\\.ses", "\\.sf", "\\.sf2", "\\.sfk", "\\.sfl", "\\.shn", "\\.sib", "\\.sid", "\\.sid", "\\.smf", "\\.smp", "\\.snd", "\\.snd", "\\.snd", "\\.sng", "\\.sng", "\\.sou", "\\.sppack", "\\.sprg", "\\.spx", "\\.sseq", "\\.sseq", "\\.ssnd", "\\.stm", "\\.stx", "\\.sty", "\\.svx", "\\.sw", "\\.swa", "\\.syh", "\\.syw", "\\.syx", "\\.td0", "\\.tfmx", "\\.thx", "\\.toc", "\\.tsp", "\\.txw", "\\.u", "\\.ub", "\\.ulaw", "\\.ult", "\\.ulw", "\\.uni", "\\.usf", "\\.usflib", "\\.uw", "\\.uwf", "\\.vag", "\\.val", "\\.vc3", "\\.vmd", "\\.vmf", "\\.vmf", "\\.voc", "\\.voi", "\\.vox", "\\.vpm", "\\.vqf", "\\.vrf", "\\.vyf", "\\.w01", "\\.wav", "\\.wav", "\\.wave", "\\.wax", "\\.wfb", "\\.wfd", "\\.wfp", "\\.wma", "\\.wow", "\\.wpk", "\\.wproj", "\\.wrk", "\\.wus", "\\.wut", "\\.wv", "\\.wvc", "\\.wve", "\\.wwu", "\\.xa", "\\.xa", "\\.xfs", "\\.xi", "\\.xm", "\\.xmf", "\\.xmi", "\\.xmz", "\\.xp", "\\.xrns", "\\.xsb", "\\.xspf", "\\.xt", "\\.xwb", "\\.ym", "\\.zvd", "\\.zvr" };
public static final String[] SUBTRACK_EXTENSIONS = { ".srt", ".ssa", ".smi", ".txt", ".sub", ".ass" };
public static final Pattern VIDEO_EXTENSIONS_PATTERN;
public static final Pattern AUDIO_EXTENSIONS_PATTERN;
public static final Pattern EXTENSIONS_PATTERN;
public static final Pattern SUBTRACK_EXTENSIONS_PATTERN;
static {
EXTENSIONS = ArrayUtils.concat(VIDEO_EXTENSIONS, AUDIO_EXTENSIONS);
EXTENSIONS_PATTERN = generatePattern(EXTENSIONS);
VIDEO_EXTENSIONS_PATTERN = generatePattern(VIDEO_EXTENSIONS);
AUDIO_EXTENSIONS_PATTERN = generatePattern(AUDIO_EXTENSIONS);
SUBTRACK_EXTENSIONS_PATTERN = generatePattern(SUBTRACK_EXTENSIONS);
}
public static boolean isVideoOrAudio(String url) {
return EXTENSIONS_PATTERN.matcher(url.trim()).find();
}
public static boolean isVideoOrAudio(File file) {
return EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isVideo(String url) {
return VIDEO_EXTENSIONS_PATTERN.matcher(url.trim()).find();
}
public static boolean isVideo(File file) {
return VIDEO_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isAudio(String url) {
return AUDIO_EXTENSIONS_PATTERN.matcher(url.trim()).find();
}
public static boolean isAudio(File file) {
return AUDIO_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isSubTrack(File file) {
return SUBTRACK_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isNative(String uri) {
uri = Uri.decode(uri);
return uri != null && (uri.startsWith("/") || uri.startsWith("content:") || uri.startsWith("file:"));
}
private static Pattern generatePattern(String[] args) {
StringBuffer sb = new StringBuffer();
for (String ext : args) {
if (sb.length() > 0)
sb.append("|");
sb.append(ext);
}
return Pattern.compile("(" + sb.toString() + ")$", Pattern.CASE_INSENSITIVE);
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/MultiMemberGZIPInputStream.java
================================================
package com.cjj.bb.utils;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
public
class MultiMemberGZIPInputStream extends GZIPInputStream {
public MultiMemberGZIPInputStream(InputStream in, int size) throws IOException
{
// Wrap the stream in a PushbackInputStream…
super(new PushbackInputStream(in, size), size);
this.size=size;
}
public MultiMemberGZIPInputStream(InputStream in) throws IOException
{
// Wrap the stream in a PushbackInputStream…
super(new PushbackInputStream(in, 1024));
this.size=-1;
}
private MultiMemberGZIPInputStream(MultiMemberGZIPInputStream parent) throws IOException
{
super(parent.in);
this.size=-1;
this.parent=parent.parent==null ? parent : parent.parent;
this.parent.child=this;
}
private MultiMemberGZIPInputStream(MultiMemberGZIPInputStream parent, int size) throws IOException
{
super(parent.in, size);
this.size=size;
this.parent=parent.parent==null ? parent : parent.parent;
this.parent.child=this;
}
private MultiMemberGZIPInputStream parent;
private MultiMemberGZIPInputStream child;
private int size;
private boolean eos;
public int read(byte[] inputBuffer, int inputBufferOffset, int inputBufferLen) throws IOException {
if (eos) { return -1;}
if (this.child!=null)
return this.child.read(inputBuffer, inputBufferOffset, inputBufferLen);
int charsRead=super.read(inputBuffer, inputBufferOffset, inputBufferLen);
if (charsRead==-1)
{
// Push any remaining buffered data back onto the stream
// If the stream is then not empty, use it to construct
// a new instance of this class and delegate this and any
// future calls to it…
int n = inf.getRemaining()-8;
if (n > 0)
{
// More than 8 bytes remaining in deflater
// First 8 are gzip trailer. Add the rest to
// any un-read data…
((PushbackInputStream)this.in).unread(buf, len-n, n);
}
else
{
// Nothing in the buffer. We need to know whether or not
// there is unread data available in the underlying stream
// since the base class will not handle an empty file.
// Read a byte to see if there is data and if so,
// push it back onto the stream…
byte[] b=new byte[1];
int ret=in.read(b,0,1);
if (ret==-1)
{
eos=true;
return -1;
}
else
((PushbackInputStream)this.in).unread(b, 0, 1);
}
MultiMemberGZIPInputStream child;
if (this.size==-1)
child=new MultiMemberGZIPInputStream(this);
else
child=new MultiMemberGZIPInputStream(this, this.size);
return child.read(inputBuffer, inputBufferOffset, inputBufferLen);
}
else
return charsRead;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/PreferenceUtils.java
================================================
package com.cjj.bb.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.preference.PreferenceManager;
import com.cjj.bb.activity.ABPlayerApplication;
public final class PreferenceUtils {
/** 清空数据 */
public static void reset(final Context ctx) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(ctx).edit();
edit.clear();
edit.commit();
}
public static String getString(String key, String defValue) {
return PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext()).getString(key, defValue);
}
public static long getLong(String key, long defValue) {
return PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext()).getLong(key, defValue);
}
public static float getFloat(String key, float defValue) {
return PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext()).getFloat(key, defValue);
}
public static void put(String key, String value) {
putString(key, value);
}
public static void put(String key, int value) {
putInt(key, value);
}
public static void put(String key, float value) {
putFloat(key, value);
}
public static void put(String key, boolean value) {
putBoolean(key, value);
}
public static void putFloat(String key, float value) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
Editor editor = sharedPreferences.edit();
editor.putFloat(key, value);
editor.commit();
}
public static SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
}
public static int getInt(String key, int defValue) {
return PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext()).getInt(key, defValue);
}
public static boolean getBoolean(String key, boolean defValue) {
return PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext()).getBoolean(key, defValue);
}
public static void putStringProcess(String key, String value) {
SharedPreferences sharedPreferences = ABPlayerApplication.getContext().getSharedPreferences("preference_mu", Context.MODE_MULTI_PROCESS);
Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
public static String getStringProcess(String key, String defValue) {
SharedPreferences sharedPreferences = ABPlayerApplication.getContext().getSharedPreferences("preference_mu", Context.MODE_MULTI_PROCESS);
return sharedPreferences.getString(key, defValue);
}
public static boolean hasString(String key) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
return sharedPreferences.contains(key);
}
public static void putString(String key, String value) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
public static void putLong(String key, long value) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
Editor editor = sharedPreferences.edit();
editor.putLong(key, value);
editor.commit();
}
public static void putBoolean(String key, boolean value) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
Editor editor = sharedPreferences.edit();
editor.putBoolean(key, value);
editor.commit();
}
public static void putInt(String key, int value) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
Editor editor = sharedPreferences.edit();
editor.putInt(key, value);
editor.commit();
}
public static void remove(String... keys) {
if (keys != null) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ABPlayerApplication.getContext());
Editor editor = sharedPreferences.edit();
for (String key : keys) {
editor.remove(key);
}
editor.commit();
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/StringUtils.java
================================================
package com.cjj.bb.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;
import android.text.TextPaint;
/**
* 字符串工具类
*
* @author tangjun
*
*/
public class StringUtils {
public static final String EMPTY = "";
private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
private static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd hh:mm:ss";
/** 用于生成文件 */
private static final String DEFAULT_FILE_PATTERN = "yyyy-MM-dd-HH-mm-ss";
private static final double KB = 1024.0;
private static final double MB = 1048576.0;
private static final double GB = 1073741824.0;
public static final SimpleDateFormat DATE_FORMAT_PART = new SimpleDateFormat(
"HH:mm");
public static String currentTimeString() {
return DATE_FORMAT_PART.format(Calendar.getInstance().getTime());
}
public static char chatAt(String pinyin, int index) {
if (pinyin != null && pinyin.length() > 0)
return pinyin.charAt(index);
return ' ';
}
/** 获取字符串宽度 */
public static float GetTextWidth(String Sentence, float Size) {
if (isEmpty(Sentence))
return 0;
TextPaint FontPaint = new TextPaint();
FontPaint.setTextSize(Size);
return FontPaint.measureText(Sentence.trim()) + (int) (Size * 0.1); // 留点余地
}
/**
* 格式化日期字符串
*
* @param date
* @param pattern
* @return
*/
public static String formatDate(Date date, String pattern) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
return format.format(date);
}
/**
* 格式化日期字符串
*
* @param date
* @return 例如2011-3-24
*/
public static String formatDate(Date date) {
return formatDate(date, DEFAULT_DATE_PATTERN);
}
public static String formatDate(long date) {
return formatDate(new Date(date), DEFAULT_DATE_PATTERN);
}
/**
* 获取当前时间 格式为yyyy-MM-dd 例如2011-07-08
*
* @return
*/
public static String getDate() {
return formatDate(new Date(), DEFAULT_DATE_PATTERN);
}
/** 生成一个文件名,不含后缀 */
public static String createFileName() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat format = new SimpleDateFormat(DEFAULT_FILE_PATTERN);
return format.format(date);
}
/**
* 获取当前时间
*
* @return
*/
public static String getDateTime() {
return formatDate(new Date(), DEFAULT_DATETIME_PATTERN);
}
/**
* 格式化日期时间字符串
*
* @param date
* @return 例如2011-11-30 16:06:54
*/
public static String formatDateTime(Date date) {
return formatDate(date, DEFAULT_DATETIME_PATTERN);
}
public static String formatDateTime(long date) {
return formatDate(new Date(date), DEFAULT_DATETIME_PATTERN);
}
/**
* 格林威时间转换
*
* @param gmt
* @return
*/
public static String formatGMTDate(String gmt) {
TimeZone timeZoneLondon = TimeZone.getTimeZone(gmt);
return formatDate(Calendar.getInstance(timeZoneLondon)
.getTimeInMillis());
}
/**
* 拼接数组
*
* @param array
* @param separator
* @return
*/
public static String join(final ArrayList array,
final String separator) {
StringBuffer result = new StringBuffer();
if (array != null && array.size() > 0) {
for (String str : array) {
result.append(str);
result.append(separator);
}
result.delete(result.length() - 1, result.length());
}
return result.toString();
}
public static String join(final Iterator iter,
final String separator) {
StringBuffer result = new StringBuffer();
if (iter != null) {
while (iter.hasNext()) {
String key = iter.next();
result.append(key);
result.append(separator);
}
if (result.length() > 0)
result.delete(result.length() - 1, result.length());
}
return result.toString();
}
/**
* 判断字符串是否为空
*
* @param str
* @return
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
*
* @param str
* @return
*/
public static String trim(String str) {
return str == null ? EMPTY : str.trim();
}
/**
* 转换时间显示
*
* @param time
* 毫秒
* @return
*/
public static String generateTime(long time) {
int totalSeconds = (int) (time / 1000);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes,
seconds) : String.format("%02d:%02d", minutes, seconds);
}
/** 根据秒速获取时间格式 */
public static String gennerTime(int totalSeconds) {
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
return String.format("%02d:%02d", minutes, seconds);
}
/**
* 转换文件大小
*
* @param size
* @return
*/
public static String generateFileSize(long size) {
String fileSize;
if (size < KB)
fileSize = size + "B";
else if (size < MB)
fileSize = String.format("%.1f", size / KB) + "KB";
else if (size < GB)
fileSize = String.format("%.1f", size / MB) + "MB";
else
fileSize = String.format("%.1f", size / GB) + "GB";
return fileSize;
}
public static String getTimeDiff(long time) {
// Calendar cal = Calendar.getInstance();
long diff = 0;
// Date dnow = cal.getTime();
String str = "";
diff = System.currentTimeMillis() - time;
if (diff > 2592000000L) {// 30 * 24 * 60 * 60 * 1000=2592000000 毫秒
str = "1个月前";
} else if (diff > 1814400000) {// 21 * 24 * 60 * 60 * 1000=1814400000 毫秒
str = "3周前";
} else if (diff > 1209600000) {// 14 * 24 * 60 * 60 * 1000=1209600000 毫秒
str = "2周前";
} else if (diff > 604800000) {// 7 * 24 * 60 * 60 * 1000=604800000 毫秒
str = "1周前";
} else if (diff > 86400000) { // 24 * 60 * 60 * 1000=86400000 毫秒
// System.out.println("X天前");
str = (int) Math.floor(diff / 86400000f) + "天前";
} else if (diff > 18000000) {// 5 * 60 * 60 * 1000=18000000 毫秒
// System.out.println("X小时前");
str = (int) Math.floor(diff / 18000000f) + "小时前";
} else if (diff > 60000) {// 1 * 60 * 1000=60000 毫秒
// System.out.println("X分钟前");
str = (int) Math.floor(diff / 60000) + "分钟前";
} else {
str = (int) Math.floor(diff / 1000) + "秒前";
}
return str;
}
/**
* 截取字符串
*
* @param search
* 待搜索的字符串
* @param start
* 起始字符串 例如:
* @param end
* 结束字符串 例如:
* @param defaultValue
* @return
*/
public static String substring(String search, String start, String end,
String defaultValue) {
int start_len = start.length();
int start_pos = StringUtils.isEmpty(start) ? 0 : search.indexOf(start);
if (start_pos > -1) {
int end_pos = StringUtils.isEmpty(end) ? -1 : search.indexOf(end,
start_pos + start_len);
if (end_pos > -1)
return search.substring(start_pos + start.length(), end_pos);
else
return search.substring(start_pos + start.length());
}
return defaultValue;
}
/**
* 截取字符串
*
* @param search
* 待搜索的字符串
* @param start
* 起始字符串 例如:
* @param end
* 结束字符串 例如:
* @return
*/
public static String substring(String search, String start, String end) {
return substring(search, start, end, "");
}
/**
* 拼接字符串
*
* @param strs
* @return
*/
public static String concat(String... strs) {
StringBuffer result = new StringBuffer();
if (strs != null) {
for (String str : strs) {
if (str != null)
result.append(str);
}
}
return result.toString();
}
/** 获取中文字符个数 */
public static int getChineseCharCount(String str) {
String tempStr;
int count = 0;
for (int i = 0; i < str.length(); i++) {
tempStr = String.valueOf(str.charAt(i));
if (tempStr.getBytes().length == 3) {
count++;
}
}
return count;
}
/** 获取英文字符个数 */
public static int getEnglishCount(String str) {
String tempStr;
int count = 0;
for (int i = 0; i < str.length(); i++) {
tempStr = String.valueOf(str.charAt(i));
if (!(tempStr.getBytes().length == 3)) {
count++;
}
}
return count;
}
public static String encode(String url) {
try {
return URLEncoder.encode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
Logger.e(e);
}
return url;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/ToastUtils.java
================================================
package com.cjj.bb.utils;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.Toast;
import com.cjj.bb.R;
import com.cjj.bb.activity.ABPlayerApplication;
public class ToastUtils {
public static void showToast(int resID) {
showToast(ABPlayerApplication.getContext(), Toast.LENGTH_SHORT, resID);
}
public static void showToast(String text) {
showToast(ABPlayerApplication.getContext(), Toast.LENGTH_SHORT, text);
}
public static void showToast(Context ctx, int resID) {
showToast(ctx, Toast.LENGTH_SHORT, resID);
}
public static void showToast(Context ctx, String text) {
showToast(ctx, Toast.LENGTH_SHORT, text);
}
public static void showLongToast(Context ctx, int resID) {
showToast(ctx, Toast.LENGTH_LONG, resID);
}
public static void showLongToast(int resID) {
showToast(ABPlayerApplication.getContext(), Toast.LENGTH_LONG, resID);
}
public static void showLongToast(Context ctx, String text) {
showToast(ctx, Toast.LENGTH_LONG, text);
}
public static void showLongToast(String text) {
showToast(ABPlayerApplication.getContext(), Toast.LENGTH_LONG, text);
}
public static void showToast(Context ctx, int duration, int resID) {
showToast(ctx, duration, ctx.getString(resID));
}
public static void showToast(Context ctx, int duration, String text) {
Toast toast = Toast.makeText(ctx, text, duration);
View mNextView = toast.getView();
if (mNextView != null)
// mNextView.setBackgroundResource(R.drawable.toast_frame);
toast.show();
// Toast.makeText(ctx, text, duration).show();
}
// public static void showToastOnUiThread(final String text) {
// showToastOnUiThread(FSAppliction.getCurrentActivity(), text);
// }
/** 在UI线程运行弹出 */
public static void showToastOnUiThread(final Activity ctx, final String text) {
if (ctx != null) {
ctx.runOnUiThread(new Runnable() {
@Override
public void run() {
showToast(ctx, text);
}
});
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/URLUtil.java
================================================
package com.cjj.bb.utils;
/**
*
* @author wwj_748
* @date 2014/8/10
*/
public class URLUtil {
// BILIBILI_DATA_URL
public static String URL_DONG_HUA = "http://www.bilibili.com/index/ding/1.json";
public static String URL_MAD_MAV = "http://www.bilibili.com/index/ding/24.json";
public static String URL_MAD_3D = "http://www.bilibili.com/index/ding/25.json";
public static String URL_DONG_HUA_DUAN_PIAN = "http://www.bilibili.com/index/ding/47.json";
public static String URL_DONG_HUA_ZONG_HE = "http://www.bilibili.com/index/ding/27.json";
public static String URL_LIAN_ZAI_DONG_HUA = "http://www.bilibili.com/index/ding/33.json";
public static String URL_WAN_JIE_DONG_HUA = "http://www.bilibili.com/index/ding/32.json";
public static String URL_ZHI_XUN = "http://www.bilibili.com/index/ding/51.json";
public static String URL_GUAN_FANG_YAN_SHEN = "http://www.bilibili.com/index/ding/152.json";
public static String URL_GUO_CHAN_DONG_HUA = "http://www.bilibili.com/index/ding/153.json";
public static String URL_YIN_YUE = "http://www.bilibili.com/index/ding/3.json";
public static String URL_FAN_CHANG = "http://www.bilibili.com/index/ding/31.json";
public static String URL_VOCALOID_UTAU = "http://www.bilibili.com/index/ding/30.json";
public static String URL_YAN_ZOU= "http://www.bilibili.com/index/ding/59.json";
public static String URL_YIN_YUE_XUAN_JI = "http://www.bilibili.com/index/ding/130.json";
public static String URL_KE_JI = "http://www.bilibili.com/index/ding/36.json";
public static String URL_JI_LU_PIAN = "http://www.bilibili.com/index/ding/37.json";
public static String URL_KE_PU_REN_WEN = "http://www.bilibili.com/index/ding/124.json";
public static String URL_YE_SHENG_JI_SHU= "http://www.bilibili.com/index/ding/122.json";
public static String URL_YAN_JIANG = "http://www.bilibili.com/index/ding/39.json";
public static String URL_JUN_SHI = "http://www.bilibili.com/index/ding/96.json";
public static String URL_SHU_MA = "http://www.bilibili.com/index/ding/95.json";
public static String URL_YU_LE = "http://www.bilibili.com/index/ding/5.json";
public static String URL_GAO_XIAO = "http://www.bilibili.com/index/ding/138.json";
public static String URL_SHENG_HUO = "http://www.bilibili.com/index/ding/21.json";
public static String URL_ZONG_YI = "http://www.bilibili.com/index/ding/71.json";
public static String URL_DIAN_YIN = "http://www.bilibili.com/index/ding/23.json";
public static String URL_OU_MEI_DIAN_YIN = "http://www.bilibili.com/index/ding/145.json";
public static String URL_RI_BEN_DIAN_YIN = "http://www.bilibili.com/index/ding/146.json";
public static String URL_GUO_CHAN_DIAN_YIN = "http://www.bilibili.com/index/ding/147.json";
public static String URL_DIAN_YIN_XIANG_GUAN = "http://www.bilibili.com/index/ding/82.json";
public static String URL_YOU_XI = "http://www.bilibili.com/index/ding/4.json";
public static String URL_DIAN_JI = "http://www.bilibili.com/index/ding/17.json";
public static String URL_WANG_LUO_DIAN_YIN = "http://www.bilibili.com/index/ding/65.json";
public static String URL_DIAN_ZI_JING_JI = "http://www.bilibili.com/index/ding/60.json";
public static String URL_RANK_QUAN_QU = "http://www.bilibili.com/index/rank/all-7-0.json";//全区
public static String URL_RANK_XIN_FAN = "http://www.bilibili.com/index/rank/all-7-33.json";//新番
public static String URL_RANK_DONG_HUA = "http://www.bilibili.com/index/rank/all-7-1.json";//动画
public static String URL_RANK_YIN_YUE = "http://www.bilibili.com/index/rank/all-7-3.json";//音乐
public static String URL_RANK_YOU_XI = "http://www.bilibili.com/index/rank/all-7-4.json";//游戏
public static String URL_RANK_KE_JI = "http://www.bilibili.com/index/rank/all-7-36.json";//科技
public static String URL_RANK_YU_LE = "http://www.bilibili.com/index/rank/all-7-5.json";//娱乐
public static String URL_RANK_DIAN_YING = "http://www.bilibili.com/index/rank/all-7-23.json";//电影
/**
* 获取博客列表的URL
*
* @param blogType
* 博客类型
* @param page
* 页数
* @return
*/
public static String getVideoListURL(int videoType) {
String url = "";
switch (videoType) {
case Constants.DEF_VIDEO_TYPE.DONG_HUA:
url = URL_DONG_HUA;
break;
case Constants.DEF_VIDEO_TYPE.MAD_AMV:
url = URL_MAD_MAV;
break;
case Constants.DEF_VIDEO_TYPE.MMD_3D:
url = URL_MAD_3D;
break;
case Constants.DEF_VIDEO_TYPE.DONG_HUA_DUAN_PIAN:
url = URL_DONG_HUA_DUAN_PIAN;
break;
case Constants.DEF_VIDEO_TYPE.DONG_HUA_ZONG_HE:
url = URL_DONG_HUA_ZONG_HE;
break;
case Constants.DEF_VIDEO_TYPE.LIAN_ZAI_DONG_HUA:
url = URL_LIAN_ZAI_DONG_HUA;
break;
case Constants.DEF_VIDEO_TYPE.WAN_JIE_DONG_HUA:
url = URL_WAN_JIE_DONG_HUA;
break;
case Constants.DEF_VIDEO_TYPE.ZHI_XUN:
url = URL_ZHI_XUN;
break;
case Constants.DEF_VIDEO_TYPE.GUAN_FANG_YAN_SHEN:
url = URL_GUAN_FANG_YAN_SHEN;
break;
case Constants.DEF_VIDEO_TYPE.GUO_CHAN_DONG_HUA:
url = URL_GUO_CHAN_DONG_HUA;
break;
//<------------音乐区------------->
case Constants.DEF_VIDEO_TYPE.YIN_YUE:
url = URL_YIN_YUE;
break;
case Constants.DEF_VIDEO_TYPE.FAN_CHANG:
url = URL_FAN_CHANG;
break;
case Constants.DEF_VIDEO_TYPE.VOCALOID_UTAU:
url = URL_VOCALOID_UTAU;
break;
case Constants.DEF_VIDEO_TYPE.YAN_ZOU:
url = URL_YAN_ZOU;
break;
case Constants.DEF_VIDEO_TYPE.YIN_YUE_XUAN_JI:
url = URL_YIN_YUE_XUAN_JI;
break;
//<------------科技区------------->
case Constants.DEF_VIDEO_TYPE.KE_JI:
url = URL_KE_JI;
break;
case Constants.DEF_VIDEO_TYPE.JI_LU_PIAN:
url = URL_JI_LU_PIAN;
break;
case Constants.DEF_VIDEO_TYPE.KE_PU_REN_WEN:
url = URL_KE_PU_REN_WEN;
break;
case Constants.DEF_VIDEO_TYPE.YE_SHENG_JI_SHU:
url = URL_YE_SHENG_JI_SHU;
break;
case Constants.DEF_VIDEO_TYPE.YAN_JIANG:
url = URL_YAN_JIANG;
break;
case Constants.DEF_VIDEO_TYPE.JUN_SHI:
url = URL_JUN_SHI;
break;
case Constants.DEF_VIDEO_TYPE.SHU_MA:
url = URL_SHU_MA;
break;
//<------------娱乐区------------->
case Constants.DEF_VIDEO_TYPE.YU_LE:
url = URL_YU_LE;
break;
case Constants.DEF_VIDEO_TYPE.GAO_XIAO:
url = URL_GAO_XIAO;
break;
case Constants.DEF_VIDEO_TYPE.SHENG_HUO:
url = URL_SHENG_HUO;
break;
case Constants.DEF_VIDEO_TYPE.ZONG_YI:
url = URL_ZONG_YI;
break;
//<------------电影区------------->
case Constants.DEF_VIDEO_TYPE.DIAN_YIN:
url = URL_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.OU_MEI_DIAN_YIN:
url = URL_OU_MEI_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.RI_BEN_DIAN_YIN:
url = URL_RI_BEN_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.GUO_CHAN_DIAN_YIN:
url = URL_GUO_CHAN_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.DIAN_YIN_XIANG_GUAN:
url = URL_DIAN_YIN_XIANG_GUAN;
break;
//<------------游戏区------------->
case Constants.DEF_VIDEO_TYPE.YOU_XI:
url = URL_YOU_XI;
break;
case Constants.DEF_VIDEO_TYPE.DIAN_JI:
url = URL_DIAN_JI;
break;
case Constants.DEF_VIDEO_TYPE.WANG_LUO_DIAN_YIN:
url = URL_WANG_LUO_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.DIAN_ZI_JING_JI:
url = URL_DIAN_ZI_JING_JI;
break;
//<------------排行榜------------->
case 10070:
url = URL_RANK_QUAN_QU;
break;
case 100733:
url = URL_RANK_XIN_FAN;
break;
case 10071:
url = URL_RANK_DONG_HUA;
break;
case 10073:
url = URL_RANK_YIN_YUE;
break;
case 10074:
url = URL_RANK_YOU_XI;
break;
case 100736:
url = URL_RANK_KE_JI;
break;
case 10075:
url = URL_RANK_YU_LE;
break;
case 100723:
url = URL_RANK_DIAN_YING;
break;
default:
break;
}
return url;
}
/**
* 获取刷新博客的URL
*
* @param blogType
* 博客类型
* @return
*/
public static String getRefreshBlogListURL(int blogType) {
String url = "";
switch (blogType) {
case Constants.DEF_VIDEO_TYPE.DONG_HUA:
url = URL_DONG_HUA;
break;
case Constants.DEF_VIDEO_TYPE.MAD_AMV:
url = URL_MAD_MAV;
break;
case Constants.DEF_VIDEO_TYPE.MMD_3D:
url = URL_MAD_3D;
break;
case Constants.DEF_VIDEO_TYPE.DONG_HUA_DUAN_PIAN:
url = URL_DONG_HUA_DUAN_PIAN;
break;
case Constants.DEF_VIDEO_TYPE.DONG_HUA_ZONG_HE:
url = URL_DONG_HUA_ZONG_HE;
break;
case Constants.DEF_VIDEO_TYPE.LIAN_ZAI_DONG_HUA:
url = URL_LIAN_ZAI_DONG_HUA;
break;
case Constants.DEF_VIDEO_TYPE.WAN_JIE_DONG_HUA:
url = URL_WAN_JIE_DONG_HUA;
break;
case Constants.DEF_VIDEO_TYPE.ZHI_XUN:
url = URL_ZHI_XUN;
break;
case Constants.DEF_VIDEO_TYPE.GUAN_FANG_YAN_SHEN:
url = URL_GUAN_FANG_YAN_SHEN;
break;
case Constants.DEF_VIDEO_TYPE.GUO_CHAN_DONG_HUA:
url = URL_GUO_CHAN_DONG_HUA;
break;
//<------------音乐区------------->
case Constants.DEF_VIDEO_TYPE.YIN_YUE:
url = URL_YIN_YUE;
break;
case Constants.DEF_VIDEO_TYPE.FAN_CHANG:
url = URL_FAN_CHANG;
break;
case Constants.DEF_VIDEO_TYPE.VOCALOID_UTAU:
url = URL_VOCALOID_UTAU;
break;
case Constants.DEF_VIDEO_TYPE.YAN_ZOU:
url = URL_YAN_ZOU;
break;
case Constants.DEF_VIDEO_TYPE.YIN_YUE_XUAN_JI:
url = URL_YIN_YUE_XUAN_JI;
break;
//<------------科技区------------->
case Constants.DEF_VIDEO_TYPE.KE_JI:
url = URL_KE_JI;
break;
case Constants.DEF_VIDEO_TYPE.JI_LU_PIAN:
url = URL_JI_LU_PIAN;
break;
case Constants.DEF_VIDEO_TYPE.KE_PU_REN_WEN:
url = URL_KE_PU_REN_WEN;
break;
case Constants.DEF_VIDEO_TYPE.YE_SHENG_JI_SHU:
url = URL_YE_SHENG_JI_SHU;
break;
case Constants.DEF_VIDEO_TYPE.YAN_JIANG:
url = URL_YAN_JIANG;
break;
case Constants.DEF_VIDEO_TYPE.JUN_SHI:
url = URL_JUN_SHI;
break;
case Constants.DEF_VIDEO_TYPE.SHU_MA:
url = URL_SHU_MA;
break;
//<------------娱乐区------------->
case Constants.DEF_VIDEO_TYPE.YU_LE:
url = URL_YU_LE;
break;
case Constants.DEF_VIDEO_TYPE.GAO_XIAO:
url = URL_GAO_XIAO;
break;
case Constants.DEF_VIDEO_TYPE.SHENG_HUO:
url = URL_SHENG_HUO;
break;
case Constants.DEF_VIDEO_TYPE.ZONG_YI:
url = URL_ZONG_YI;
break;
//<------------电影区------------->
case Constants.DEF_VIDEO_TYPE.DIAN_YIN:
url = URL_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.OU_MEI_DIAN_YIN:
url = URL_OU_MEI_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.RI_BEN_DIAN_YIN:
url = URL_RI_BEN_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.GUO_CHAN_DIAN_YIN:
url = URL_GUO_CHAN_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.DIAN_YIN_XIANG_GUAN:
url = URL_DIAN_YIN_XIANG_GUAN;
break;
//<------------游戏区------------->
case Constants.DEF_VIDEO_TYPE.YOU_XI:
url = URL_YOU_XI;
break;
case Constants.DEF_VIDEO_TYPE.DIAN_JI:
url = URL_DIAN_JI;
break;
case Constants.DEF_VIDEO_TYPE.WANG_LUO_DIAN_YIN:
url = URL_WANG_LUO_DIAN_YIN;
break;
case Constants.DEF_VIDEO_TYPE.DIAN_ZI_JING_JI:
url = URL_DIAN_ZI_JING_JI;
break;
//<------------排行榜------------->
case 10070:
url = URL_RANK_QUAN_QU;
break;
case 100733:
url = URL_RANK_XIN_FAN;
break;
case 10071:
url = URL_RANK_DONG_HUA;
break;
case 10073:
url = URL_RANK_YIN_YUE;
break;
case 10074:
url = URL_RANK_YOU_XI;
break;
case 100736:
url = URL_RANK_KE_JI;
break;
case 10075:
url = URL_RANK_YU_LE;
break;
case 100723:
url = URL_RANK_DIAN_YING;
break;
default:
break;
}
return url;
}
/**
* 返回博文评论列表链接
*
* @param filename
* 文件名
* @param pageIndex
* 页数
* @return
*/
public static String getCommentListURL(String filename, String pageIndex) {
return "http://blog.csdn.net/wwj_748/comment/list/" + filename
+ "?page=" + pageIndex;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/utils/XmlReaderHelper.java
================================================
package com.cjj.bb.utils;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.content.Context;
import com.cjj.bb.model.OnlineVideo;
/** 从XML读取电视台节目 */
public class XmlReaderHelper {
/** 获取所有电视分类 */
public static ArrayList getAllCategory(final Context context) {
ArrayList result = new ArrayList();
DocumentBuilderFactory docBuilderFactory = null;
DocumentBuilder docBuilder = null;
Document doc = null;
try {
docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilder = docBuilderFactory.newDocumentBuilder();
// xml file 放到 assets目录中的
doc = docBuilder.parse(context.getResources().getAssets()
.open("online.xml"));
// root element
Element root = doc.getDocumentElement();
NodeList nodeList = root.getElementsByTagName("category");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);// category
OnlineVideo ov = new OnlineVideo();
NamedNodeMap attr = node.getAttributes();
ov.title = attr.getNamedItem("name").getNodeValue();
ov.id = attr.getNamedItem("id").getNodeValue();
ov.category = 1;
ov.level = 2;
ov.is_category = true;
result.add(ov);
// Read Node
}
} catch (IOException e) {
} catch (SAXException e) {
} catch (ParserConfigurationException e) {
} finally {
doc = null;
docBuilder = null;
docBuilderFactory = null;
}
return result;
}
/** 读取分类下所有电视地址 */
public static ArrayList getVideos(final Context context,
String categoryId) {
ArrayList result = new ArrayList();
DocumentBuilderFactory docBuilderFactory = null;
DocumentBuilder docBuilder = null;
Document doc = null;
try {
docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilder = docBuilderFactory.newDocumentBuilder();
// xml file 放到 assets目录中的
doc = docBuilder.parse(context.getResources().getAssets()
.open("online.xml"));
// root element
Element root = doc.getElementById(categoryId);
if (root != null) {
NodeList nodeList = root.getChildNodes();
for (int i = 0, j = nodeList.getLength(); i < j; i++) {
Node baseNode = nodeList.item(i);
if (!"item".equals(baseNode.getNodeName()))
continue;
String id = baseNode.getFirstChild().getNodeValue();
if (id == null)
continue;
OnlineVideo ov = new OnlineVideo();
ov.id = id;
Element el = doc.getElementById(ov.id);
if (el != null) {
ov.title = el.getAttribute("title");
ov.icon_url = el.getAttribute("image");
ov.level = 3;
ov.category = 1;
NodeList nodes = el.getChildNodes();
for (int m = 0, n = nodes.getLength(); m < n; m++) {
Node node = nodes.item(m);
if (!"ref".equals(node.getNodeName()))
continue;
String href = node.getAttributes()
.getNamedItem("href").getNodeValue();
if (ov.url == null) {
ov.url = href;
} else {
if (ov.backup_url == null)
ov.backup_url = new ArrayList();
ov.backup_url.add(href);
}
}
if (ov.url != null)
result.add(ov);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} finally {
doc = null;
docBuilder = null;
docBuilderFactory = null;
}
return result;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/ApplicationUtils.java
================================================
package com.cjj.bb.view;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;
import android.widget.Toast;
public class ApplicationUtils {
/**
* 备份App 首先无需提升权限就就可以复制APK,查看权限你就会知道,在data/app下的APK权限如下:-rw-r--r-- system
* system 5122972 2012-12-13 10:38 com.taobao.taobao-1.apk 我们是有读取权限的。
*
* @param packageName
* @param mActivity
* @throws java.io.IOException
*/
public static void backupApp(String packageName, Activity mActivity)
throws IOException {
// 存放位置
String newFile = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator;
String oldFile = null;
try {
// 原始位置
oldFile = mActivity.getPackageManager().getApplicationInfo(
packageName, 0).sourceDir;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
System.out.println(newFile);
System.out.println(oldFile);
File in = new File(oldFile);
File out = new File(newFile + packageName + ".apk");
if (!out.exists()) {
out.createNewFile();
Toast.makeText(mActivity, "文件备份成功!" + "存放于" + newFile + "目录下", 1)
.show();
} else {
Toast.makeText(mActivity, "文件已经存在!" + "查看" + newFile + "目录下", 1)
.show();
}
FileInputStream fis = new FileInputStream(in);
FileOutputStream fos = new FileOutputStream(out);
int count;
// 文件太大的话,我觉得需要修改
byte[] buffer = new byte[256 * 1024];
while ((count = fis.read(buffer)) > 0) {
fos.write(buffer, 0, count);
}
fis.close();
fos.flush();
fos.close();
}
/**
* 获取当前Apk版本号 android:versionCode
*
* @param context
* @return
*/
public static int getVerCode(Context context) {
int verCode = -1;
try {
verCode = context.getPackageManager().getPackageInfo(
context.getPackageName(), 0).versionCode;
} catch (NameNotFoundException e) {
}
return verCode;
}
public static String getVerName(Context context) {
try {
return context.getPackageManager().getPackageInfo(
context.getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
}
return "";
}
/**
* 返回当前的应用是否处于前台显示状态 不需要android.permission.GET_TASKS权限
* http://zengrong.net/post/1680.htm
*
* @param packageName
* @return
*/
public static boolean isTopActivity(Context context, String packageName) {
// _context是一个保存的上下文
ActivityManager am = (ActivityManager) context.getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
List list = am
.getRunningAppProcesses();
if (list.size() == 0)
return false;
for (ActivityManager.RunningAppProcessInfo process : list) {
// Log.d(getTAG(), Integer.toString(__process.importance));
// Log.d(getTAG(), __process.processName);
if (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& process.processName.equals(packageName)) {
return true;
}
}
return false;
}
/**
* 检测APP是否存在
* @param context
* @param packageName
* @return
*/
public static boolean checkAppExist(Context context, String packageName) {
try {
ApplicationInfo info = context.getPackageManager()
.getApplicationInfo(packageName, 0);
return info != null && info.packageName.equals(packageName);
} catch (NameNotFoundException e) {
} catch (Exception e) {
}
return false;
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/CircleImageView.java
================================================
package com.cjj.bb.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.cjj.bb.R;
public class CircleImageView extends ImageView {
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 1;
private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
private final Paint mBorderPaint = new Paint();
private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private Bitmap mBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;
private float mDrawableRadius;
private float mBorderRadius;
private boolean mReady;
private boolean mSetupPending;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
a.recycle();
init();
}
private void init() {
super.setScaleType(SCALE_TYPE);
mReady = true;
if (mSetupPending) {
setup();
mSetupPending = false;
}
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}
@Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
if (mBorderWidth != 0) {
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setup();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mBitmap = bm;
setup();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
setup();
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
return null;
}
}
private void setup() {
if (!mReady) {
mSetupPending = true;
return;
}
if (mBitmap == null) {
return;
}
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
mBorderRect.set(0, 0, getWidth(), getHeight());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);
mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
updateShaderMatrix();
invalidate();
}
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/CommonGestures.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.view;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import com.cjj.bb.utils.DeviceUtils;
public class CommonGestures {
public static final int SCALE_STATE_BEGIN = 0;
public static final int SCALE_STATE_SCALEING = 1;
public static final int SCALE_STATE_END = 2;
private boolean mGestureEnabled;
private GestureDetectorCompat mDoubleTapGestureDetector;
private GestureDetectorCompat mTapGestureDetector;
private ScaleGestureDetector mScaleDetector;
private Activity mContext;
public CommonGestures(Activity ctx) {
mContext = ctx;
mDoubleTapGestureDetector = new GestureDetectorCompat(mContext, new DoubleTapGestureListener());
mTapGestureDetector = new GestureDetectorCompat(mContext, new TapGestureListener());
mScaleDetector = new ScaleGestureDetector(mContext, new ScaleDetectorListener());
}
public boolean onTouchEvent(MotionEvent event) {
if (mListener == null)
return false;
if (mTapGestureDetector.onTouchEvent(event))
return true;
if (event.getPointerCount() > 1) {
try {
if (mScaleDetector != null && mScaleDetector.onTouchEvent(event))
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
if (mDoubleTapGestureDetector.onTouchEvent(event))
return true;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
mListener.onGestureEnd();
break;
}
return false;
}
private class TapGestureListener extends SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
if (mListener != null)
mListener.onSingleTap();
return true;
}
@Override
public void onLongPress(MotionEvent e) {
if (mListener != null && mGestureEnabled)
mListener.onLongPress();
}
}
@SuppressLint("NewApi")
private class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (mListener != null && mGestureEnabled)
mListener.onScale(detector.getScaleFactor(), SCALE_STATE_SCALEING);
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
if (mListener != null && mGestureEnabled)
mListener.onScale(0F, SCALE_STATE_END);
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
if (mListener != null && mGestureEnabled)
mListener.onScale(0F, SCALE_STATE_BEGIN);
return true;
}
}
private class DoubleTapGestureListener extends SimpleOnGestureListener {
private boolean mDown = false;
@Override
public boolean onDown(MotionEvent event) {
mDown = true;
return super.onDown(event);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (mListener != null && mGestureEnabled && e1 != null && e2 != null) {
if (mDown) {
mListener.onGestureBegin();
mDown = false;
}
float mOldX = e1.getX(), mOldY = e1.getY();
int windowWidth = DeviceUtils.getScreenWidth(mContext);
int windowHeight = DeviceUtils.getScreenHeight(mContext);
if (Math.abs(e2.getY(0) - mOldY) * 2 > Math.abs(e2.getX(0) - mOldX)) {
if (mOldX > windowWidth * 4.0 / 5) {
mListener.onRightSlide((mOldY - e2.getY(0)) / windowHeight);
} else if (mOldX < windowWidth / 5.0) {
mListener.onLeftSlide((mOldY - e2.getY(0)) / windowHeight);
}
}
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onDoubleTap(MotionEvent event) {
if (mListener != null && mGestureEnabled)
mListener.onDoubleTap();
return super.onDoubleTap(event);
}
}
public void setTouchListener(TouchListener l, boolean enable) {
mListener = l;
mGestureEnabled = enable;
}
private TouchListener mListener;
public interface TouchListener {
public void onGestureBegin();
public void onGestureEnd();
public void onLeftSlide(float percent);
public void onRightSlide(float percent);
public void onSingleTap();
public void onDoubleTap();
public void onScale(float scaleFactor, int state);
public void onLongPress();
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/FileUtils.java
================================================
package com.cjj.bb.view;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import com.cjj.bb.utils.StringUtils;
public class FileUtils {
// http://www.fileinfo.com/filetypes/video , "dat" , "bin" , "rms"
public static final String[] VIDEO_EXTENSIONS = { "264", "3g2", "3gp",
"3gp2", "3gpp", "3gpp2", "3mm", "3p2", "60d", "aep", "ajp", "amv",
"amx", "arf", "asf", "asx", "avb", "avd", "avi", "avs", "avs",
"axm", "bdm", "bdmv", "bik", "bix", "bmk", "box", "bs4", "bsf",
"byu", "camre", "clpi", "cpi", "cvc", "d2v", "d3v", "dav", "dce",
"dck", "ddat", "dif", "dir", "divx", "dlx", "dmb", "dmsm", "dmss",
"dnc", "dpg", "dream", "dsy", "dv", "dv-avi", "dv4", "dvdmedia",
"dvr-ms", "dvx", "dxr", "dzm", "dzp", "dzt", "evo", "eye", "f4p",
"f4v", "fbr", "fbr", "fbz", "fcp", "flc", "flh", "fli", "flv",
"flx", "gl", "grasp", "gts", "gvi", "gvp", "hdmov", "hkm", "ifo",
"imovi", "imovi", "iva", "ivf", "ivr", "ivs", "izz", "izzy", "jts",
"lsf", "lsx", "m15", "m1pg", "m1v", "m21", "m21", "m2a", "m2p",
"m2t", "m2ts", "m2v", "m4e", "m4u", "m4v", "m75", "meta", "mgv",
"mj2", "mjp", "mjpg", "mkv", "mmv", "mnv", "mod", "modd", "moff",
"moi", "moov", "mov", "movie", "mp21", "mp21", "mp2v", "mp4",
"mp4v", "mpe", "mpeg", "mpeg4", "mpf", "mpg", "mpg2", "mpgin",
"mpl", "mpls", "mpv", "mpv2", "mqv", "msdvd", "msh", "mswmm",
"mts", "mtv", "mvb", "mvc", "mvd", "mve", "mvp", "mxf", "mys",
"ncor", "nsv", "nvc", "ogm", "ogv", "ogx", "osp", "par", "pds",
"pgi", "piv", "playlist", "pmf", "prel", "pro", "prproj", "psh",
"pva", "pvr", "pxv", "qt", "qtch", "qtl", "qtm", "qtz",
"rcproject", "rdb", "rec", "rm", "rmd", "rmp", "rmvb", "roq", "rp",
"rts", "rts", "rum", "rv", "sbk", "sbt", "scm", "scm", "scn",
"sec", "seq", "sfvidcap", "smil", "smk", "sml", "smv", "spl",
"ssm", "str", "stx", "svi", "swf", "swi", "swt", "tda3mt", "tivo",
"tix", "tod", "tp", "tp0", "tpd", "tpr", "trp", "ts", "tvs", "vc1",
"vcr", "vcv", "vdo", "vdr", "veg", "vem", "vf", "vfw", "vfz",
"vgz", "vid", "viewlet", "viv", "vivo", "vlab", "vob", "vp3",
"vp6", "vp7", "vpj", "vro", "vsp", "w32", "wcp", "webm", "wm",
"wmd", "wmmp", "wmv", "wmx", "wp3", "wpl", "wtv", "wvx", "xfl",
"xvid", "yuv", "zm1", "zm2", "zm3", "zmv" };
// http://www.fileinfo.com/filetypes/audio , "spx" , "mid" , "sf"
public static final String[] AUDIO_EXTENSIONS = { "4mp", "669", "6cm",
"8cm", "8med", "8svx", "a2m", "aa", "aa3", "aac", "aax", "abc",
"abm", "ac3", "acd", "acd-bak", "acd-zip", "acm", "act", "adg",
"afc", "agm", "ahx", "aif", "aifc", "aiff", "ais", "akp", "al",
"alaw", "all", "amf", "amr", "ams", "ams", "aob", "ape", "apf",
"apl", "ase", "at3", "atrac", "au", "aud", "aup", "avr", "awb",
"band", "bap", "bdd", "box", "bun", "bwf", "c01", "caf", "cda",
"cdda", "cdr", "cel", "cfa", "cidb", "cmf", "copy", "cpr", "cpt",
"csh", "cwp", "d00", "d01", "dcf", "dcm", "dct", "ddt", "dewf",
"df2", "dfc", "dig", "dig", "dls", "dm", "dmf", "dmsa", "dmse",
"drg", "dsf", "dsm", "dsp", "dss", "dtm", "dts", "dtshd", "dvf",
"dwd", "ear", "efa", "efe", "efk", "efq", "efs", "efv", "emd",
"emp", "emx", "esps", "f2r", "f32", "f3r", "f4a", "f64", "far",
"fff", "flac", "flp", "fls", "frg", "fsm", "fzb", "fzf", "fzv",
"g721", "g723", "g726", "gig", "gp5", "gpk", "gsm", "gsm", "h0",
"hdp", "hma", "hsb", "ics", "iff", "imf", "imp", "ins", "ins",
"it", "iti", "its", "jam", "k25", "k26", "kar", "kin", "kit",
"kmp", "koz", "koz", "kpl", "krz", "ksc", "ksf", "kt2", "kt3",
"ktp", "l", "la", "lqt", "lso", "lvp", "lwv", "m1a", "m3u", "m4a",
"m4b", "m4p", "m4r", "ma1", "mdl", "med", "mgv", "midi", "miniusf",
"mka", "mlp", "mmf", "mmm", "mmp", "mo3", "mod", "mp1", "mp2",
"mp3", "mpa", "mpc", "mpga", "mpu", "mp_", "mscx", "mscz", "msv",
"mt2", "mt9", "mte", "mti", "mtm", "mtp", "mts", "mus", "mws",
"mxl", "mzp", "nap", "nki", "nra", "nrt", "nsa", "nsf", "nst",
"ntn", "nvf", "nwc", "odm", "oga", "ogg", "okt", "oma", "omf",
"omg", "omx", "ots", "ove", "ovw", "pac", "pat", "pbf", "pca",
"pcast", "pcg", "pcm", "peak", "phy", "pk", "pla", "pls", "pna",
"ppc", "ppcx", "prg", "prg", "psf", "psm", "ptf", "ptm", "pts",
"pvc", "qcp", "r", "r1m", "ra", "ram", "raw", "rax", "rbs", "rcy",
"rex", "rfl", "rmf", "rmi", "rmj", "rmm", "rmx", "rng", "rns",
"rol", "rsn", "rso", "rti", "rtm", "rts", "rvx", "rx2", "s3i",
"s3m", "s3z", "saf", "sam", "sb", "sbg", "sbi", "sbk", "sc2", "sd",
"sd", "sd2", "sd2f", "sdat", "sdii", "sds", "sdt", "sdx", "seg",
"seq", "ses", "sf2", "sfk", "sfl", "shn", "sib", "sid", "sid",
"smf", "smp", "snd", "snd", "snd", "sng", "sng", "sou", "sppack",
"sprg", "sseq", "sseq", "ssnd", "stm", "stx", "sty", "svx", "sw",
"swa", "syh", "syw", "syx", "td0", "tfmx", "thx", "toc", "tsp",
"txw", "u", "ub", "ulaw", "ult", "ulw", "uni", "usf", "usflib",
"uw", "uwf", "vag", "val", "vc3", "vmd", "vmf", "vmf", "voc",
"voi", "vox", "vpm", "vqf", "vrf", "vyf", "w01", "wav", "wav",
"wave", "wax", "wfb", "wfd", "wfp", "wma", "wow", "wpk", "wproj",
"wrk", "wus", "wut", "wv", "wvc", "wve", "wwu", "xa", "xa", "xfs",
"xi", "xm", "xmf", "xmi", "xmz", "xp", "xrns", "xsb", "xspf", "xt",
"xwb", "ym", "zvd", "zvr" };
private static final HashSet mHashVideo;
private static final HashSet mHashAudio;
private static final double KB = 1024.0;
private static final double MB = KB * KB;
private static final double GB = KB * KB * KB;
static {
mHashVideo = new HashSet(Arrays.asList(VIDEO_EXTENSIONS));
mHashAudio = new HashSet(Arrays.asList(AUDIO_EXTENSIONS));
}
/** 是否是音频或者视频 */
public static boolean isVideoOrAudio(File f) {
final String ext = getFileExtension(f);
return mHashVideo.contains(ext) || mHashAudio.contains(ext);
}
public static boolean isVideoOrAudio(String f) {
final String ext = getUrlExtension(f);
return mHashVideo.contains(ext) || mHashAudio.contains(ext);
}
public static boolean isVideo(File f) {
final String ext = getFileExtension(f);
return mHashVideo.contains(ext);
}
/** 获取文件后缀 */
public static String getFileExtension(File f) {
if (f != null) {
String filename = f.getName();
int i = filename.lastIndexOf('.');
if (i > 0 && i < filename.length() - 1) {
return filename.substring(i + 1).toLowerCase();
}
}
return null;
}
public static String getUrlFileName(String url) {
int slashIndex = url.lastIndexOf('/');
int dotIndex = url.lastIndexOf('.');
String filenameWithoutExtension;
if (dotIndex == -1) {
filenameWithoutExtension = url.substring(slashIndex + 1);
} else {
filenameWithoutExtension = url.substring(slashIndex + 1, dotIndex);
}
return filenameWithoutExtension;
}
public static String getUrlExtension(String url) {
if (!StringUtils.isEmpty(url)) {
int i = url.lastIndexOf('.');
if (i > 0 && i < url.length() - 1) {
return url.substring(i + 1).toLowerCase();
}
}
return "";
}
public static String getFileNameNoEx(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot > -1) && (dot < (filename.length()))) {
return filename.substring(0, dot);
}
}
return filename;
}
public static String showFileSize(long size) {
String fileSize;
if (size < KB)
fileSize = size + "B";
else if (size < MB)
fileSize = String.format("%.1f", size / KB) + "KB";
else if (size < GB)
fileSize = String.format("%.1f", size / MB) + "MB";
else
fileSize = String.format("%.1f", size / GB) + "GB";
return fileSize;
}
/** 显示SD卡剩余空间 */
public static String showFileAvailable() {
String result = "";
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
StatFs sf = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
long blockSize = sf.getBlockSize();
long blockCount = sf.getBlockCount();
long availCount = sf.getAvailableBlocks();
return showFileSize(availCount * blockSize) + " / "
+ showFileSize(blockSize * blockCount);
}
return result;
}
/** 如果不存在就创建 */
public static boolean createIfNoExists(String path) {
File file = new File(path);
boolean mk = false;
if (!file.exists()) {
mk = file.mkdirs();
}
return mk;
}
private static HashMap mMimeType = new HashMap();
static {
mMimeType.put("M1V", "video/mpeg");
mMimeType.put("MP2", "video/mpeg");
mMimeType.put("MPE", "video/mpeg");
mMimeType.put("MPG", "video/mpeg");
mMimeType.put("MPEG", "video/mpeg");
mMimeType.put("MP4", "video/mp4");
mMimeType.put("M4V", "video/mp4");
mMimeType.put("3GP", "video/3gpp");
mMimeType.put("3GPP", "video/3gpp");
mMimeType.put("3G2", "video/3gpp2");
mMimeType.put("3GPP2", "video/3gpp2");
mMimeType.put("MKV", "video/x-matroska");
mMimeType.put("WEBM", "video/x-matroska");
mMimeType.put("MTS", "video/mp2ts");
mMimeType.put("TS", "video/mp2ts");
mMimeType.put("TP", "video/mp2ts");
mMimeType.put("WMV", "video/x-ms-wmv");
mMimeType.put("ASF", "video/x-ms-asf");
mMimeType.put("ASX", "video/x-ms-asf");
mMimeType.put("FLV", "video/x-flv");
mMimeType.put("MOV", "video/quicktime");
mMimeType.put("QT", "video/quicktime");
mMimeType.put("RM", "video/x-pn-realvideo");
mMimeType.put("RMVB", "video/x-pn-realvideo");
mMimeType.put("VOB", "video/dvd");
mMimeType.put("DAT", "video/dvd");
mMimeType.put("AVI", "video/x-divx");
mMimeType.put("OGV", "video/ogg");
mMimeType.put("OGG", "video/ogg");
mMimeType.put("VIV", "video/vnd.vivo");
mMimeType.put("VIVO", "video/vnd.vivo");
mMimeType.put("WTV", "video/wtv");
mMimeType.put("AVS", "video/avs-video");
mMimeType.put("SWF", "video/x-shockwave-flash");
mMimeType.put("YUV", "video/x-raw-yuv");
}
/** 获取MIME */
public static String getMimeType(String path) {
int lastDot = path.lastIndexOf(".");
if (lastDot < 0)
return null;
return mMimeType.get(path.substring(lastDot + 1).toUpperCase());
}
/** 多个SD卡时 取外置SD卡 */
public static String getExternalStorageDirectory() {
// 参考文章
// http://blog.csdn.net/bbmiku/article/details/7937745
Map map = System.getenv();
String[] values = new String[map.values().size()];
map.values().toArray(values);
String path = values[values.length - 1];
Log.e("nmbb", "FileUtils.getExternalStorageDirectory : " + path);
if (path.startsWith("/mnt/")
&& !Environment.getExternalStorageDirectory().getAbsolutePath()
.equals(path))
return path;
else
return null;
}
public static String getCanonical(File f) {
if (f == null)
return null;
try {
return f.getCanonicalPath();
} catch (IOException e) {
return f.getAbsolutePath();
}
}
public static boolean sdAvailable() {
return Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment
.getExternalStorageState())
|| Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState());
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/LeftSliderLayout.java
================================================
package com.cjj.bb.view;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;
/**
* 左边侧滑
* @author Administrator
*
*/
public class LeftSliderLayout extends ViewGroup {
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
/**
* Constant value for touch state
* TOUCH_STATE_REST : no touch
* TOUCH_STATE_SCROLLING : scrolling
*/
private static final int TOUCH_STATE_REST = 0;
private static final int TOUCH_STATE_SCROLLING = 1;
private int mTouchState = TOUCH_STATE_REST;
/**
* Distance in pixels a touch can wander before we think the user is scrolling
*/
private int mTouchSlop;
/**
* Values for saving axis of the last touch event.
*/
private float mLastMotionX;
private float mLastMotionY;
/**
* Values for VelocityTracker to compute current velocity.
* VELOCITY_UNITS in dp
* mVelocityUnits in px
*/
private static final int VELOCITY_UNITS = 1000;
private int mVelocityUnits;
/**
* The minimum velocity for determining the direction.
* MINOR_VELOCITY in dp
* mMinorVelocity in px
*/
private static final float MINOR_VELOCITY = 150.0f;
private int mMinorVelocity;
/**
* The width of Sliding distance from left.
* And it should be the same with the width of the View below SliderLayout in a FrameLayout.
* DOCK_WIDTH in dp
* mDockWidth in px
*/
private static final float SLIDING_WIDTH = 180.0f;
private int mSlidingWidth;
/**
* The default values of shadow.
* VELOCITY_UNITS in dp
* mVelocityUnits in px
*/
private static final float DEF_SHADOW_WIDTH = 10.0f;
private int mDefShadowWidth;
/**
* Value for checking a touch event is completed.
*/
private boolean mIsTouchEventDone = false;
/**
* Value for checking slider is open.
*/
private boolean mIsOpen = false;
/**
* Value for saving the last offset of scroller ’ x-axis.
*/
private int mSaveScrollX = 0;
/**
* Value for checking slider is allowed to slide.
*/
private boolean mEnableSlide = true;
private View mMainChild = null;
private OnLeftSliderLayoutStateListener mListener = null;
/**
* Instantiates a new LeftSliderLayout.
*
* @param context the associated Context
* @param attrs AttributeSet
*/
public LeftSliderLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* Instantiates a new LeftSliderLayout.
*
* @param context the associated Context
* @param attrs AttributeSet
* @param defStyle Style
*/
public LeftSliderLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScroller = new Scroller(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
/**
* Convert values in dp to values in px;
*/
final float fDensity = getResources().getDisplayMetrics().density;
mVelocityUnits = (int) (VELOCITY_UNITS * fDensity + 0.5f);
mMinorVelocity = (int) (MINOR_VELOCITY * fDensity + 0.5f);
mSlidingWidth = (int) (SLIDING_WIDTH * fDensity + 0.5f);
mDefShadowWidth = (int) (DEF_SHADOW_WIDTH * fDensity + 0.5f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// check Measure Mode is Exactly.
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("LeftSliderLayout only canmCurScreen run at EXACTLY mode!");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("LeftSliderLayout only can run at EXACTLY mode!");
}
// measure child views
int nCount = getChildCount();
for (int i = 2; i < nCount; i++) {
removeViewAt(i);
}
nCount = getChildCount();
if (nCount > 0) {
if (nCount > 1) {
mMainChild = getChildAt(1);
getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec);
} else {
mMainChild = getChildAt(0);
}
mMainChild.measure(widthMeasureSpec, heightMeasureSpec);
}
// Set the scrolled position
scrollTo(mSaveScrollX, 0);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int nCount = getChildCount();
if (nCount <= 0) {
return;
}
// Set the size and position of Main Child
if (mMainChild != null) {
mMainChild.layout(
l,
t,
l + mMainChild.getMeasuredWidth(),
t + mMainChild.getMeasuredHeight());
}
// Set the size and position of Shadow Child
if (nCount > 1) {
int nLeftChildWidth = 0;
View leftChild = getChildAt(0);
LayoutParams layoutParams = leftChild.getLayoutParams();
if (layoutParams.width == LayoutParams.FILL_PARENT
|| layoutParams.width == LayoutParams.MATCH_PARENT) {
nLeftChildWidth = mDefShadowWidth;
} else {
nLeftChildWidth = layoutParams.width;
}
leftChild.layout(
l - nLeftChildWidth,
t,
l,
t + leftChild.getMeasuredHeight());
}
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int nCurScrollX = getScrollX();
// check touch point is in the rectangle of Main Child
if (mMainChild != null
&& mTouchState != TOUCH_STATE_SCROLLING
&& mIsTouchEventDone) {
Rect rect = new Rect();
mMainChild.getHitRect(rect);
if (!rect.contains((int)event.getX() + nCurScrollX, (int)event.getY())) {
return false;
}
}
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
final int action = event.getAction();
final float x = event.getX();
switch (action) {
case MotionEvent.ACTION_DOWN: {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
mIsTouchEventDone = false;
mLastMotionX = x;
break;
}
case MotionEvent.ACTION_MOVE: {
// check slider is allowed to slide.
if (!mEnableSlide) {
break;
}
// compute the x-axis offset from last point to current point
int deltaX = (int) (mLastMotionX - x);
if (nCurScrollX + deltaX < getMinScrollX()) {
deltaX = getMinScrollX() - nCurScrollX;
mLastMotionX = mLastMotionX - deltaX;
} else if (nCurScrollX + deltaX > getMaxScrollX()) {
deltaX = getMaxScrollX() - nCurScrollX;
mLastMotionX = mLastMotionX - deltaX;
} else {
mLastMotionX = x;
}
// Move view to the current point
if (deltaX != 0) {
scrollBy(deltaX, 0);
}
// Save the scrolled position
mSaveScrollX = getScrollX();
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
// check slider is allowed to slide.
if (!mEnableSlide) {
break;
}
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(mVelocityUnits);
// Set open or close state, when get ACTION_UP or ACTION_CANCEL event.
if (nCurScrollX < 0) {
int velocityX = (int) velocityTracker.getXVelocity();
if (velocityX > mMinorVelocity) {
scrollByWithAnim(getMinScrollX() - nCurScrollX);
setState(true);
}
else if (velocityX < -mMinorVelocity) {
scrollByWithAnim(-nCurScrollX);
setState(false);
} else {
if (nCurScrollX >= getMinScrollX() / 2) {
scrollByWithAnim(- nCurScrollX);
setState(false);
} else {
scrollByWithAnim(getMinScrollX() - nCurScrollX);
setState(true);
}
}
} else {
if (nCurScrollX > 0) {
scrollByWithAnim(-nCurScrollX);
}
setState(false);
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
mTouchState = TOUCH_STATE_REST;
mIsTouchEventDone = true;
break;
}
}
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
if (mListener != null && !mListener.OnLeftSliderLayoutInterceptTouch(ev)) {
return false;
}
if ((action == MotionEvent.ACTION_MOVE)
&& (mTouchState != TOUCH_STATE_REST)) {
return true;
}
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastMotionX = x;
mLastMotionY = y;
mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
break;
case MotionEvent.ACTION_MOVE:
final int xDiff = (int) Math.abs(mLastMotionX - x);
if (xDiff > mTouchSlop) {
if (Math.abs(mLastMotionY - y) / Math.abs(mLastMotionX - x) < 1)
mTouchState = TOUCH_STATE_SCROLLING;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mTouchState = TOUCH_STATE_REST;
break;
}
return mTouchState != TOUCH_STATE_REST;
}
/**
* With the horizontal scroll of the animation
*
* @param nDx x-axis offset
*/
void scrollByWithAnim(int nDx) {
if (nDx == 0) {
return;
}
mScroller.startScroll(getScrollX(), 0, nDx, 0,
Math.abs(nDx));
invalidate();
}
/**
* Get distance of the maximum horizontal scroll
*
* @return distance in px
*/
private int getMaxScrollX() {
return 0;
}
/**
* Get distance of the minimum horizontal scroll
* @return distance in px
*/
private int getMinScrollX() {
return -mSlidingWidth;
}
/**
* Open LeftSlideLayout
*/
public void open() {
if (mEnableSlide) {
scrollByWithAnim(getMinScrollX() - getScrollX());
setState(true);
}
}
/**
* Close LeftSlideLayout
*/
public void close() {
if (mEnableSlide) {
scrollByWithAnim((-1) * getScrollX());
setState(false);
}
}
/**
* Determine whether LeftSlideLayout is open
*
* @return true-open,false-close
*/
public boolean isOpen() {
return mIsOpen;
}
/**
* Set state of LeftSliderLayout
*
* @param bIsOpen the new state
*/
private void setState(boolean bIsOpen) {
boolean bStateChanged = false;
if (mIsOpen && !bIsOpen) {
bStateChanged = true;
} else if (!mIsOpen && bIsOpen) {
bStateChanged = true;
}
mIsOpen = bIsOpen;
if (bIsOpen) {
mSaveScrollX = getMaxScrollX();
} else {
mSaveScrollX = 0;
}
if (bStateChanged && mListener != null) {
mListener.OnLeftSliderLayoutStateChanged(bIsOpen);
}
}
/**
* enable slide action of LeftSliderLayout
*
* @param bEnable
*/
public void enableSlide(boolean bEnable) {
mEnableSlide = bEnable;
}
/**
* Set listener to LeftSliderLayout
*/
public void setOnLeftSliderLayoutListener(OnLeftSliderLayoutStateListener listener) {
mListener = listener;
}
/**
* LeftSliderLayout Listener
*
*/
public interface OnLeftSliderLayoutStateListener {
/**
* Called when LeftSliderLayout’s state has been changed.
*
* @param bIsOpen the new state
*/
public void OnLeftSliderLayoutStateChanged(boolean bIsOpen);
/**
* Called when LeftSliderLayout has got onInterceptTouchEvent.
*
* @param ev Touch Event
* @return true - LeftSliderLayout need to manage the InterceptTouchEvent.
* false - LeftSliderLayout don't need to manage the InterceptTouchEvent.
*/
public boolean OnLeftSliderLayoutInterceptTouch(MotionEvent ev);
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/MediaController.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.view;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.cjj.bb.R;
import com.cjj.bb.utils.DeviceUtils;
import com.cjj.bb.utils.FractionalTouchDelegate;
import com.cjj.bb.utils.Logger;
import com.cjj.bb.utils.StringUtils;
import com.cjj.bb.utils.ToastUtils;
public class MediaController extends FrameLayout {
private MediaPlayerControl mPlayer;
private Activity mContext;
private PopupWindow mWindow;
private View mAnchor;
private View mRoot;
private ImageButton mLock;
private ImageButton mScreenToggle;
private ImageButton mSnapshot;
private SeekBar mProgress;
private TextView mEndTime, mCurrentTime;
private long mDuration;
private boolean mShowing;
private boolean mScreenLocked = false;
private boolean mDragging;
private boolean mInstantSeeking = true;
private static final int DEFAULT_TIME_OUT = 3000;
private static final int DEFAULT_LONG_TIME_SHOW = 120000;
private static final int DEFAULT_SEEKBAR_VALUE = 1000;
private static final int TIME_TICK_INTERVAL = 1000;
private ImageButton mPauseButton;
private View mMediaController;
private View mControlsLayout;
private View mSystemInfoLayout;
private View mControlsButtons;
private View mMenu;
private TextView mDateTime;
private TextView mDownloadRate;
private TextView mFileName;
private TextView mBatteryLevel;
private TextView mOperationInfo;
private View mOperationVolLum;
private ImageView mVolLumNum;
private ImageView mVolLumBg;
private AudioManager mAM;
private int mMaxVolume;
private float mBrightness = 0.01f;
private int mVolume = 0;
private Handler mHandler;
private Animation mAnimSlideInTop;
private Animation mAnimSlideInBottom;
private Animation mAnimSlideOutTop;
private Animation mAnimSlideOutBottom;
private CommonGestures mGestures;
private int mVideoMode;
private ImageButton mDanmakuSend;
private ImageButton mDanmakuSwitch;
private boolean mDanmakuShow = true;
public MediaController(Context context) {
super(context);
mContext = (Activity) context;
initFloatingWindow();
initResources();
}
public void setDanmakuVisible(boolean isVisible){
if(isVisible){
mDanmakuSend.setVisibility(View.VISIBLE);
mDanmakuSwitch.setVisibility(View.VISIBLE);
}else{
mDanmakuSend.setVisibility(View.GONE);
mDanmakuSwitch.setVisibility(View.GONE);
}
}
public MediaController(Context context, boolean locked) {
this(context);
mScreenLocked = locked;
lock(mScreenLocked);
}
private void initFloatingWindow() {
mWindow = new PopupWindow(mContext);
mWindow.setFocusable(true);
mWindow.setBackgroundDrawable(null);
mWindow.setOutsideTouchable(true);
}
@TargetApi(11)
public void setWindowLayoutType() {
if (DeviceUtils.hasICS()) {
try {
mAnchor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Method setWindowLayoutType = PopupWindow.class.getMethod("setWindowLayoutType", new Class[] { int.class });
setWindowLayoutType.invoke(mWindow, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG);
} catch (Exception e) {
Logger.e(e);
}
}
}
@SuppressLint("NewApi")
private void initResources() {
mHandler = new MHandler(this);
mAM = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mMaxVolume = mAM.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mGestures = new CommonGestures(mContext);
mGestures.setTouchListener(mTouchListener, true);
mAnimSlideOutBottom = AnimationUtils.loadAnimation(mContext, R.anim.slide_out_bottom);
mAnimSlideOutTop = AnimationUtils.loadAnimation(mContext, R.anim.slide_out_top);
mAnimSlideInBottom = AnimationUtils.loadAnimation(mContext, R.anim.slide_in_bottom);
mAnimSlideInTop = AnimationUtils.loadAnimation(mContext, R.anim.slide_in_top);
mAnimSlideOutBottom.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mMediaController.setVisibility(View.GONE);
showButtons(false);
mHandler.removeMessages(MSG_HIDE_SYSTEM_UI);
mHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_UI, DEFAULT_TIME_OUT);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
removeAllViews();
mRoot = inflateLayout();
mWindow.setContentView(mRoot);
mWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
mWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
findViewItems(mRoot);
showSystemUi(false);
if (DeviceUtils.hasHoneycomb()) {
mRoot.setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
mHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_UI, DEFAULT_TIME_OUT);
}
}
});
}
}
private View inflateLayout() {
return ((LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.mediacontroller, this);
}
private void findViewItems(View v) {
mMediaController = v.findViewById(R.id.mediacontroller);
mSystemInfoLayout = v.findViewById(R.id.info_panel);
mEndTime = (TextView) v.findViewById(R.id.mediacontroller_time_total);
mCurrentTime = (TextView) v.findViewById(R.id.mediacontroller_time_current);
mMenu = v.findViewById(R.id.video_menu);
mMenu.setOnClickListener(mMenuListener);
FractionalTouchDelegate.setupDelegate(mSystemInfoLayout, mMenu, new RectF(1.0f, 1f, 1.2f, 1.2f));
mFileName = (TextView) v.findViewById(R.id.mediacontroller_file_name);
mDateTime = (TextView) v.findViewById(R.id.date_time);
mDownloadRate = (TextView) v.findViewById(R.id.download_rate);
mBatteryLevel = (TextView) v.findViewById(R.id.battery_level);
mControlsLayout = v.findViewById(R.id.mediacontroller_controls);
mControlsButtons = v.findViewById(R.id.mediacontroller_controls_buttons);
mOperationInfo = (TextView) v.findViewById(R.id.operation_info);
mOperationVolLum = v.findViewById(R.id.operation_volume_brightness);
mVolLumBg = (ImageView) v.findViewById(R.id.operation_bg);
mVolLumNum = (ImageView) v.findViewById(R.id.operation_percent);
mLock = (ImageButton) v.findViewById(R.id.mediacontroller_lock);
mLock.setOnClickListener(mLockClickListener);
FractionalTouchDelegate.setupDelegate(mSystemInfoLayout, mLock, new RectF(1.0f, 1f, 1.2f, 1.2f));
mScreenToggle = (ImageButton) v.findViewById(R.id.mediacontroller_screen_size);
mScreenToggle.setOnClickListener(mScreenToggleListener);
mSnapshot = (ImageButton) v.findViewById(R.id.mediacontroller_snapshot);
mSnapshot.setOnClickListener(mSnapshotListener);
mPauseButton = (ImageButton) v.findViewById(R.id.mediacontroller_play_pause);
mPauseButton.setOnClickListener(mPauseListener);
mProgress = (SeekBar) v.findViewById(R.id.mediacontroller_seekbar);
mProgress.setOnSeekBarChangeListener(mSeekListener);
mProgress.setMax(DEFAULT_SEEKBAR_VALUE);
mDanmakuSend = (ImageButton) v.findViewById(R.id.mediacontroller_send_danmaku);
mDanmakuSend.setOnClickListener(mDanmakuSendListener);
mDanmakuSwitch = (ImageButton) v.findViewById(R.id.mediacontroller_danmaku_switch);
mDanmakuSwitch.setOnClickListener(mDanmakuSwitchListener);
}
public void setAnchorView(View view) {
mAnchor = view;
int[] location = new int[2];
mAnchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
setWindowLayoutType();
mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, anchorRect.left, anchorRect.bottom);
}
public void release() {
if (mWindow != null) {
mWindow.dismiss();
mWindow = null;
}
}
private OnClickListener mMenuListener = new OnClickListener() {
@Override
public void onClick(View v) {
mPlayer.showMenu();
}
};
private void setOperationInfo(String info, long time) {
mOperationInfo.setText(info);
mOperationInfo.setVisibility(View.VISIBLE);
mHandler.removeMessages(MSG_HIDE_OPERATION_INFO);
mHandler.sendEmptyMessageDelayed(MSG_HIDE_OPERATION_INFO, time);
}
private void setBrightnessScale(float scale) {
setGraphicOperationProgress(R.drawable.video_brightness_bg, scale);
}
private void setVolumeScale(float scale) {
setGraphicOperationProgress(R.drawable.video_volumn_bg, scale);
}
private void setGraphicOperationProgress(int bgID, float scale) {
mVolLumBg.setImageResource(bgID);
mOperationInfo.setVisibility(View.GONE);
mOperationVolLum.setVisibility(View.VISIBLE);
ViewGroup.LayoutParams lp = mVolLumNum.getLayoutParams();
lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * scale);
mVolLumNum.setLayoutParams(lp);
}
public void setFileName(String name) {
mFileName.setText(name);
}
public void setDownloadRate(String rate) {
mDownloadRate.setVisibility(View.VISIBLE);
mDownloadRate.setText(rate);
}
public void setBatteryLevel(String level) {
mBatteryLevel.setVisibility(View.VISIBLE);
mBatteryLevel.setText(level);
}
public void setMediaPlayer(MediaPlayerControl player) {
mPlayer = player;
updatePausePlay();
}
public void show() {
show(DEFAULT_TIME_OUT);
}
public void show(int timeout) {
if (timeout != 0) {
mHandler.removeMessages(MSG_FADE_OUT);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FADE_OUT), timeout);
}
if (!mShowing) {
showButtons(true);
mHandler.removeMessages(MSG_HIDE_SYSTEM_UI);
showSystemUi(true);
mPauseButton.requestFocus();
mControlsLayout.startAnimation(mAnimSlideInTop);
mSystemInfoLayout.startAnimation(mAnimSlideInBottom);
mMediaController.setVisibility(View.VISIBLE);
updatePausePlay();
mHandler.sendEmptyMessage(MSG_TIME_TICK);
mHandler.sendEmptyMessage(MSG_SHOW_PROGRESS);
mShowing = true;
}
}
public void hide() {
if (mShowing) {
try {
mHandler.removeMessages(MSG_TIME_TICK);
mHandler.removeMessages(MSG_SHOW_PROGRESS);
mControlsLayout.startAnimation(mAnimSlideOutTop);
mSystemInfoLayout.startAnimation(mAnimSlideOutBottom);
} catch (IllegalArgumentException ex) {
Logger.d("MediaController already removed");
}
mShowing = false;
}
}
private void toggleVideoMode(boolean larger, boolean recycle) {
if (larger) {
if (mVideoMode < VideoView.VIDEO_LAYOUT_ZOOM)
mVideoMode++;
else if (recycle)
mVideoMode = VideoView.VIDEO_LAYOUT_ORIGIN;
} else {
if (mVideoMode > VideoView.VIDEO_LAYOUT_ORIGIN)
mVideoMode--;
else if (recycle)
mVideoMode = VideoView.VIDEO_LAYOUT_ZOOM;
}
switch (mVideoMode) {
case VideoView.VIDEO_LAYOUT_ORIGIN:
setOperationInfo(mContext.getString(R.string.video_original), 500);
mScreenToggle.setImageResource(R.drawable.mediacontroller_sreen_size_100);
break;
case VideoView.VIDEO_LAYOUT_SCALE:
setOperationInfo(mContext.getString(R.string.video_fit_screen), 500);
mScreenToggle.setImageResource(R.drawable.mediacontroller_screen_fit);
break;
case VideoView.VIDEO_LAYOUT_STRETCH:
setOperationInfo(mContext.getString(R.string.video_stretch), 500);
mScreenToggle.setImageResource(R.drawable.mediacontroller_screen_size);
break;
case VideoView.VIDEO_LAYOUT_ZOOM:
setOperationInfo(mContext.getString(R.string.video_crop), 500);
mScreenToggle.setImageResource(R.drawable.mediacontroller_sreen_size_crop);
break;
}
mPlayer.toggleVideoMode(mVideoMode);
}
private void lock(boolean toLock) {
if (toLock) {
mLock.setImageResource(R.drawable.mediacontroller_lock);
mMenu.setVisibility(View.GONE);
mControlsButtons.setVisibility(View.GONE);
mProgress.setEnabled(false);
if (mScreenLocked != toLock)
setOperationInfo(mContext.getString(R.string.video_screen_locked), 1000);
} else {
mLock.setImageResource(R.drawable.mediacontroller_unlock);
// If you wanna to show, set mMenu visible
mMenu.setVisibility(View.GONE);
mControlsButtons.setVisibility(View.VISIBLE);
mProgress.setEnabled(true);
if (mScreenLocked != toLock)
setOperationInfo(mContext.getString(R.string.video_screen_unlocked), 1000);
}
mScreenLocked = toLock;
mGestures.setTouchListener(mTouchListener, !mScreenLocked);
}
public boolean isLocked() {
return mScreenLocked;
}
private static final int MSG_FADE_OUT = 1;
private static final int MSG_SHOW_PROGRESS = 2;
private static final int MSG_HIDE_SYSTEM_UI = 3;
private static final int MSG_TIME_TICK = 4;
private static final int MSG_HIDE_OPERATION_INFO = 5;
private static final int MSG_HIDE_OPERATION_VOLLUM = 6;
private static class MHandler extends Handler {
private WeakReference mc;
public MHandler(MediaController mc) {
this.mc = new WeakReference(mc);
}
@Override
public void handleMessage(Message msg) {
MediaController c = mc.get();
if (c == null)
return;
switch (msg.what) {
case MSG_FADE_OUT:
c.hide();
break;
case MSG_SHOW_PROGRESS:
long pos = c.setProgress();
if (!c.mDragging && c.mShowing) {
msg = obtainMessage(MSG_SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
c.updatePausePlay();
}
break;
case MSG_HIDE_SYSTEM_UI:
if (!c.mShowing)
c.showSystemUi(false);
break;
case MSG_TIME_TICK:
c.mDateTime.setText(StringUtils.currentTimeString());
sendEmptyMessageDelayed(MSG_TIME_TICK, TIME_TICK_INTERVAL);
break;
case MSG_HIDE_OPERATION_INFO:
c.mOperationInfo.setVisibility(View.GONE);
break;
case MSG_HIDE_OPERATION_VOLLUM:
c.mOperationVolLum.setVisibility(View.GONE);
break;
}
}
};
private long setProgress() {
if (mPlayer == null || mDragging)
return 0;
long position = mPlayer.getCurrentPosition();
long duration = mPlayer.getDuration();
if (duration > 0) {
long pos = 1000L * position / duration;
mProgress.setProgress((int) pos);
}
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
mDuration = duration;
mEndTime.setText(StringUtils.generateTime(mDuration));
mCurrentTime.setText(StringUtils.generateTime(position));
return position;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mHandler.removeMessages(MSG_HIDE_SYSTEM_UI);
mHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_UI, DEFAULT_TIME_OUT);
return mGestures.onTouchEvent(event) || super.onTouchEvent(event);
}
private CommonGestures.TouchListener mTouchListener = new CommonGestures.TouchListener() {
@Override
public void onGestureBegin() {
mBrightness = mContext.getWindow().getAttributes().screenBrightness;
mVolume = mAM.getStreamVolume(AudioManager.STREAM_MUSIC);
if (mBrightness <= 0.00f)
mBrightness = 0.50f;
if (mBrightness < 0.01f)
mBrightness = 0.01f;
if (mVolume < 0)
mVolume = 0;
}
@Override
public void onGestureEnd() {
mOperationVolLum.setVisibility(View.GONE);
}
@Override
public void onLeftSlide(float percent) {
setBrightness(mBrightness + percent);
setBrightnessScale(mContext.getWindow().getAttributes().screenBrightness);
}
@Override
public void onRightSlide(float percent) {
int v = (int) (percent * mMaxVolume) + mVolume;
setVolume(v);
}
@Override
public void onSingleTap() {
if (mShowing)
hide();
else
show();
if (mPlayer.getBufferPercentage() >= 100)
mPlayer.removeLoadingView();
}
@Override
public void onDoubleTap() {
toggleVideoMode(true, true);
}
@Override
public void onLongPress() {
doPauseResume();
}
@Override
public void onScale(float scaleFactor, int state) {
switch (state) {
case CommonGestures.SCALE_STATE_BEGIN:
mVideoMode = VideoView.VIDEO_LAYOUT_SCALE_ZOOM;
mScreenToggle.setImageResource(R.drawable.mediacontroller_sreen_size_100);
mPlayer.toggleVideoMode(mVideoMode);
break;
case CommonGestures.SCALE_STATE_SCALEING:
float currentRatio = mPlayer.scale(scaleFactor);
setOperationInfo((int) (currentRatio * 100) + "%", 500);
break;
case CommonGestures.SCALE_STATE_END:
break;
}
}
};
private void setVolume(int v) {
if (v > mMaxVolume)
v = mMaxVolume;
else if (v < 0)
v = 0;
mAM.setStreamVolume(AudioManager.STREAM_MUSIC, v, 0);
setVolumeScale((float) v / mMaxVolume);
}
private void setBrightness(float f) {
WindowManager.LayoutParams lp = mContext.getWindow().getAttributes();
lp.screenBrightness = f;
if (lp.screenBrightness > 1.0f)
lp.screenBrightness = 1.0f;
else if (lp.screenBrightness < 0.01f)
lp.screenBrightness = 0.01f;
mContext.getWindow().setAttributes(lp);
}
@Override
public boolean onTrackballEvent(MotionEvent ev) {
show(DEFAULT_TIME_OUT);
return false;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_MUTE:
return super.dispatchKeyEvent(event);
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
mVolume = mAM.getStreamVolume(AudioManager.STREAM_MUSIC);
int step = keyCode == KeyEvent.KEYCODE_VOLUME_UP ? 1 : -1;
setVolume(mVolume + step);
mHandler.removeMessages(MSG_HIDE_OPERATION_VOLLUM);
mHandler.sendEmptyMessageDelayed(MSG_HIDE_OPERATION_VOLLUM, 500);
return true;
}
if (isLocked()) {
show();
return true;
}
if (event.getRepeatCount() == 0 && (keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) {
doPauseResume();
show(DEFAULT_TIME_OUT);
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
release();
mPlayer.stop();
return true;
} else {
show(DEFAULT_TIME_OUT);
}
return super.dispatchKeyEvent(event);
}
@TargetApi(11)
private void showSystemUi(boolean visible) {
if (DeviceUtils.hasHoneycomb()) {
int flag = visible ? 0 : View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LOW_PROFILE;
mRoot.setSystemUiVisibility(flag);
}
}
private void showButtons(boolean showButtons) {
Window window = mContext.getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
float val = showButtons ? -1 : 0;
try {
Field buttonBrightness = layoutParams.getClass().getField("buttonBrightness");
buttonBrightness.set(layoutParams, val);
} catch (Exception e) {
Logger.e("dimButtons", e);
}
window.setAttributes(layoutParams);
}
private void updatePausePlay() {
if (mPlayer.isPlaying())
mPauseButton.setImageResource(R.drawable.mediacontroller_pause);
else
mPauseButton.setImageResource(R.drawable.mediacontroller_play);
}
private void doPauseResume() {
if (mPlayer.isPlaying())
mPlayer.pause();
else
mPlayer.start();
updatePausePlay();
}
private OnClickListener mPauseListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (mPlayer.isPlaying())
show(DEFAULT_LONG_TIME_SHOW);
else
show();
doPauseResume();
}
};
private OnClickListener mLockClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
hide();
lock(!mScreenLocked);
show();
}
};
private OnClickListener mScreenToggleListener = new OnClickListener() {
@Override
public void onClick(View v) {
show(DEFAULT_TIME_OUT);
toggleVideoMode(true, true);
}
};
private OnClickListener mSnapshotListener = new OnClickListener() {
@Override
public void onClick(View v) {
show(DEFAULT_TIME_OUT);
mSnapshot.setEnabled(false);
mPlayer.snapshot();
mSnapshot.setEnabled(true);
}
};
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
private boolean wasStopped = false;
@Override
public void onStartTrackingTouch(SeekBar bar) {
mDragging = true;
show(3600000);
mHandler.removeMessages(MSG_SHOW_PROGRESS);
wasStopped = !mPlayer.isPlaying();
if (mInstantSeeking) {
mAM.setStreamMute(AudioManager.STREAM_MUSIC, true);
if (wasStopped) {
mPlayer.start();
}
}
}
@Override
public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
if (!fromuser)
return;
long newposition = (mDuration * progress) / 1000;
String time = StringUtils.generateTime(newposition);
if (mInstantSeeking)
mPlayer.seekTo(newposition);
setOperationInfo(time, 1500);
mCurrentTime.setText(time);
}
@Override
public void onStopTrackingTouch(SeekBar bar) {
if (!mInstantSeeking) {
mPlayer.seekTo((mDuration * bar.getProgress()) / 1000);
} else if (wasStopped) {
mPlayer.pause();
}
mOperationInfo.setVisibility(View.GONE);
show(DEFAULT_TIME_OUT);
mHandler.removeMessages(MSG_SHOW_PROGRESS);
mAM.setStreamMute(AudioManager.STREAM_MUSIC, false);
mDragging = false;
mHandler.sendEmptyMessageDelayed(MSG_SHOW_PROGRESS, 1000);
}
};
private OnClickListener mDanmakuSendListener = new OnClickListener() {
@Override
public void onClick(View v) {
ToastUtils.showToast("发送弹幕(没有实现功能)");
}
};
private OnClickListener mDanmakuSwitchListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (mDanmakuShow) {
mDanmakuSwitch.setImageResource(R.drawable.bili_player_danmaku_is_closed);
mPlayer.setDanmakushow(false);
mDanmakuShow = false;
} else {
mDanmakuSwitch.setImageResource(R.drawable.bili_player_danmaku_is_open);
mPlayer.setDanmakushow(true);
mDanmakuShow = true;
}
}
};
public interface MediaPlayerControl {
void start();
void pause();
void stop();
void seekTo(long pos);
boolean isPlaying();
long getDuration();
long getCurrentPosition();
int getBufferPercentage();
void previous();
void next();
long goForward();
long goBack();
void toggleVideoMode(int mode);
void showMenu();
void removeLoadingView();
float scale(float scale);
void snapshot();
void setDanmakushow(boolean isShow);
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/PlayerService.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.view;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener;
import io.vov.vitamio.MediaPlayer.OnCompletionListener;
import io.vov.vitamio.MediaPlayer.OnErrorListener;
import io.vov.vitamio.MediaPlayer.OnHWRenderFailedListener;
import io.vov.vitamio.MediaPlayer.OnInfoListener;
import io.vov.vitamio.MediaPlayer.OnPreparedListener;
import io.vov.vitamio.MediaPlayer.OnSeekCompleteListener;
import io.vov.vitamio.MediaPlayer.OnTimedTextListener;
import io.vov.vitamio.MediaPlayer.OnVideoSizeChangedListener;
import io.vov.vitamio.Vitamio;
import io.vov.vitamio.utils.Log;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.SurfaceHolder;
import com.cjj.bb.utils.Logger;
public class PlayerService extends Service implements
OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
OnVideoSizeChangedListener, OnErrorListener, OnInfoListener,
OnSeekCompleteListener, OnTimedTextListener {
private MediaPlayer mPlayer;
private VPlayerListener mListener;
private Uri mUri;
private Uri mOldUri;
private float mSeekTo = -1f;
private boolean mFromNotification;
private String[] mSubPaths;
private boolean mInitialized;
private final IBinder mBinder = new LocalBinder();
private TelephonyManager mTelephonyManager;
private int mCurrentState;
private SurfaceHolder mSurfaceHolder;
public static final int VPLYAER_NOTIFICATION_ID = 1;
public static final int STATE_PREPARED = -1;
public static final int STATE_PLAYING = 0;
public static final int STATE_NEED_RESUME = 1;
public static final int STATE_STOPPED = 2;
public static final int STATE_RINGING = 3;
private int mLastAudioTrack = -1;
private String mLastSubTrack;
private int mLastSubTrackId = -1;
private long mMediaId = -1l;
public class LocalBinder extends Binder {
public PlayerService getService() {
return PlayerService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
mInitialized = false;
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyManager.listen(mPhoneListener,
PhoneStateListener.LISTEN_CALL_STATE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Vitamio.isInitialized(this)) {
vplayerInit(intent.getBooleanExtra("isHWCodec", false));
} else {
stopSelf();
}
Log.d("CREATE OK");
return super.onStartCommand(intent, flags, startId);
}
private void vplayerInit(boolean isHWCodec) {
mPlayer = new MediaPlayer(PlayerService.this.getApplicationContext(),
isHWCodec);
mPlayer.setOnHWRenderFailedListener(new OnHWRenderFailedListener() {
@Override
public void onFailed() {
if (mListener != null)
mListener.onHWRenderFailed();
}
});
mPlayer.setOnBufferingUpdateListener(PlayerService.this);
mPlayer.setOnCompletionListener(PlayerService.this);
mPlayer.setOnPreparedListener(PlayerService.this);
mPlayer.setOnVideoSizeChangedListener(PlayerService.this);
mPlayer.setOnErrorListener(PlayerService.this);
mPlayer.setOnInfoListener(PlayerService.this);
}
public void releaseContext() {
if (mPlayer != null)
mPlayer.release();
mPlayer = null;
}
@Override
public IBinder onBind(Intent intent) {
Log.d("BIND OK : " + intent.getPackage());
return mBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
release(true);
releaseContext();
}
public boolean isInitialized() {
return mInitialized;
}
private String mTitle;
public boolean initialize(Uri filePath, String displayName,
boolean saveUri, float startPos, VPlayerListener listener,
int parentId, boolean isHWCodec) {
if (mPlayer == null)
vplayerInit(isHWCodec);
mTitle = displayName;
mListener = listener;
mOldUri = mUri;
mUri = filePath;
mSeekTo = startPos;
mMediaId = -1;
mLastAudioTrack = -1;
mLastSubTrackId = -1;
mLastSubTrack = "";
setMediaTrack();
Log.i("%s ==> %s, %s, %s, %s", mOldUri, mUri, mInitialized, mPrepared,
mVideoSizeKnown);
mFromNotification = mInitialized && mUri != null
&& mUri.equals(mOldUri);
mListener.onOpenStart();
if (!mFromNotification)
openVideo();
else
openSuccess();
return mInitialized;
}
private void setMediaTrack() {
}
private void openVideo() {
if (mUri == null || mPlayer == null)
return;
mPlayer.reset();
mInitialized = false;
mPrepared = false;
mVideoSizeKnown = false;
try {
mPlayer.setScreenOnWhilePlaying(true);
mPlayer.setDataSource(PlayerService.this, mUri);
// if (mLastAudioTrack != -1)
// mPlayer.setInitialAudioTrack(mLastAudioTrack);
// if (mLastSubTrackId != -1)
// mPlayer.setInitialSubTrack(mLastSubTrackId);
if (mSurfaceHolder != null && mSurfaceHolder.getSurface() != null
&& mSurfaceHolder.getSurface().isValid())
mPlayer.setDisplay(mSurfaceHolder);
mPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
Logger.e("openVideo", e);
} catch (IllegalStateException e) {
Logger.e("openVideo", e);
} catch (IOException e) {
Logger.e("openVideo", e);
}
}
public Uri getUri() {
return mUri;
}
public long getMediaId() {
return mMediaId;
}
public int getLastAudioTrack() {
return mLastAudioTrack;
}
public String getLastSubTrack() {
return mLastSubTrack;
}
public int getLastSubTrackId() {
return mLastSubTrackId;
}
public void setVPlayerListener(VPlayerListener listener) {
mListener = listener;
}
public void setState(int state) {
mCurrentState = state;
}
public boolean needResume() {
return mInitialized
&& (mCurrentState == STATE_NEED_RESUME || mCurrentState == STATE_PREPARED);
}
public boolean ringingState() {
return mInitialized && mCurrentState == STATE_RINGING;
}
public void release() {
release(true);
}
private void release(boolean all) {
if (mPlayer != null) {
if (mListener != null)
mListener.onCloseStart();
mPlayer.reset();
mInitialized = false;
mPrepared = false;
mVideoSizeKnown = false;
if (mListener != null)
mListener.onCloseComplete();
}
if (all) {
mListener = null;
mUri = null;
}
}
public void stop() {
if (mInitialized) {
mPlayer.pause();
}
}
public void start() {
if (mInitialized) {
mPlayer.start();
setState(STATE_PLAYING);
}
}
public void setDisplay(SurfaceHolder surface) {
mSurfaceHolder = surface;
if (mPlayer != null)
mPlayer.setDisplay(surface);
}
public void releaseSurface() {
if (mInitialized)
mPlayer.releaseDisplay();
}
public boolean isPlaying() {
return (mInitialized && mPlayer.isPlaying());
}
public int getVideoWidth() {
if (mInitialized)
return mPlayer.getVideoWidth();
return 0;
}
public int getVideoHeight() {
if (mInitialized)
return mPlayer.getVideoHeight();
return 0;
}
public float getVideoAspectRatio() {
if (mInitialized)
return mPlayer.getVideoAspectRatio();
return 0f;
}
public long getDuration() {
if (mInitialized)
return mPlayer.getDuration();
return 0;
}
public long getCurrentPosition() {
if (mInitialized)
return mPlayer.getCurrentPosition();
return 0;
}
public Bitmap getCurrentFrame() {
if (mInitialized)
return mPlayer.getCurrentFrame();
return null;
}
public float getBufferProgress() {
if (mInitialized)
return mPlayer.getBufferProgress();
return 0f;
}
public void seekTo(float percent) {
if (mInitialized)
mPlayer.seekTo((int) (percent * getDuration()));
}
public String getMetaEncoding() {
if (mInitialized)
return mPlayer.getMetaEncoding();
return null;
}
public void setAudioTrack(int num) {
if (mInitialized)
mPlayer.selectTrack(num);
// mPlayer.setAudioTrack(num);
}
public int getAudioTrack() {
if (mInitialized)
return mPlayer.getAudioTrack();
return 0;
}
// public HashMap getAudioTrackMap() {
// if (!mInitialized)
// return null;
// String enc = VP.DEFAULT_META_ENCODING;
// return mPlayer.getAudioTrackMap(enc.equals(VP.DEFAULT_META_ENCODING) ?
// getMetaEncoding() : enc);
// }
//
// public HashMap getSubTrackMap() {
// if (!mInitialized)
// return null;
// String enc = VP.DEFAULT_SUB_ENCODING;
// HashMap trackMap = new HashMap();
// HashMap m =
// mPlayer.getSubTrackMap(enc.equals(VP.DEFAULT_SUB_ENCODING) ?
// getMetaEncoding() : enc);
// if (m != null)
// for (String k : m.keySet())
// trackMap.put(k, m.get(k));
//
// if (mSubPaths != null)
// for (String s : mSubPaths)
// trackMap.put(new File(s).getName(), s);
//
// return trackMap;
// }
//
// public int getSubTrack() {
// if (mInitialized)
// return mPlayer.getSubTrack();
// return 0;
// }
//
// public void setSubTrack(int id) {
// if (mInitialized)
// mPlayer.setSubTrack(id);
// }
//
// public String getSubPath() {
// if (mInitialized)
// return mPlayer.getSubPath();
// return null;
// }
public void setSubShown(boolean shown) {
if (mInitialized)
mPlayer.setTimedTextShown(shown);// setSubtitleShown ->
// setTimedTextShown 4.0
}
public boolean isBuffering() {
return (mInitialized && mPlayer.isBuffering());
}
public void setBuffer(int bufSize) {
if (mInitialized)
mPlayer.setBufferSize(bufSize);
}
public void setVolume(float left, float right) {
if (mInitialized) {
if (left <= 0f)
left = 0f;
else if (left >= 1f)
left = 1f;
if (right <= 0f)
right = 0f;
else if (right >= 1f)
right = 1f;
mPlayer.setVolume(left, right);
}
}
public void setVideoQuality(int quality) {
if (mInitialized)
mPlayer.setVideoQuality(quality);
}
public void setDeinterlace(boolean deinterlace) {
if (mInitialized)
mPlayer.setDeinterlace(deinterlace);
}
// public int getSubLocation() {
// if (mInitialized)
// return mPlayer.getSubLocation();
// return -1;
// }
//
public void setSubEncoding(String encoding) {
if (mInitialized) {
String enc = encoding.equals(VP.DEFAULT_SUB_ENCODING) ? null
: encoding;
mPlayer.setTimedTextEncoding(enc);// setSubEncoding ->
// setTimedTextEncoding
}
}
public void setSubPath(String subPath) {
if (mInitialized)
mPlayer.addTimedTextSource(subPath);
// mPlayer.setSubPath(subPath);
}
public static interface VPlayerListener {
public void onHWRenderFailed();
public void onVideoSizeChanged(int width, int height);
public void onSubChanged(String text);
public void onSubChanged(byte[] pixels, int width, int height);
public void onOpenStart();
public void onOpenSuccess();
public void onOpenFailed();
public void onBufferStart();
public void onBufferComplete();
public void onDownloadRateChanged(int kbPerSec);
public void onPlaybackComplete();
public void onCloseStart();
public void onCloseComplete();
}
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if (isPlaying()) {
stop();
setState(STATE_RINGING);
}
break;
default:
break;
}
}
};
private boolean mVideoSizeKnown = false;
private boolean mPrepared = false;
@Override
public void onVideoSizeChanged(MediaPlayer arg0, int arg1, int arg2) {
mVideoSizeKnown = true;
if (mListener != null)
mListener.onVideoSizeChanged(arg1, arg2);
}
@Override
public void onPrepared(MediaPlayer arg0) {
mPrepared = true;
openSuccess();
}
private void openSuccess() {
mInitialized = true;
if (!mFromNotification && mSeekTo > 0 && mSeekTo < 1)
seekTo(mSeekTo);
mSeekTo = -1;
mListener.onOpenSuccess();
if (!mFromNotification) {
setSubEncoding(VP.DEFAULT_SUB_ENCODING);
if (mUri != null)
mSubPaths = getSubFiles(mUri.getPath());
if (mSubPaths != null)
setSubPath(FileUtils.getCanonical(new File(mSubPaths[0])));
setSubShown(VP.DEFAULT_SUB_SHOWN);
}
}
@Override
public void onCompletion(MediaPlayer arg0) {
if (mListener != null) {
mListener.onPlaybackComplete();
} else {
release(true);
}
}
@Override
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
}
@Override
public void onSeekComplete(MediaPlayer arg0) {
}
@Override
public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {
switch (arg1) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
if (mListener != null)
mListener.onBufferStart();
else
mPlayer.pause();
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
if (mListener != null)
mListener.onBufferComplete();
else
mPlayer.start();
break;
case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
if (mListener != null)
mListener.onDownloadRateChanged(arg2);
break;
}
return true;
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
mListener.onOpenFailed();
return true;
}
private String[] getSubFiles(String videoPath) {
ArrayList files = new ArrayList();
for (String ext : MediaPlayer.SUB_TYPES) {
File s = new File(videoPath.substring(0,
videoPath.lastIndexOf('.') > 0 ? videoPath.lastIndexOf('.')
: videoPath.length())
+ ext);
if (s.exists() && s.isFile() && s.canRead())
files.add(s.getAbsolutePath());
}
if (files.isEmpty())
return null;
else
return files.toArray(new String[files.size()]);
}
@Override
public void onTimedText(String text) {
if (mListener != null)
mListener.onSubChanged(text);
}
@Override
public void onTimedTextUpdate(byte[] pixels, int width, int height) {
if (mListener != null)
mListener.onSubChanged(pixels, width, height);
}
// @Override
// public void onSubtitleUpdate(String arg0) {
// if (mListener != null)
// mListener.onSubChanged(arg0);
// }
//
// @Override
// public void onSubtitleUpdate(byte[] arg0, int arg1, int arg2) {
// if (mListener != null)
// mListener.onSubChanged(arg0, arg1, arg2);
// }
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/PullToZoomListView.java
================================================
package com.cjj.bb.view;
import android.app.Activity;
import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
/**
* 下拉缩放
*
* @author open resource
*
*/
public class PullToZoomListView extends ListView implements
AbsListView.OnScrollListener {
private static final int INVALID_VALUE = -1;
private static final String TAG = "PullToZoomListView";
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float paramAnonymousFloat) {
float f = paramAnonymousFloat - 1.0F;
return 1.0F + f * (f * (f * (f * f)));
}
};
int mActivePointerId = -1;
private FrameLayout mHeaderContainer;
private int mHeaderHeight;
private ImageView mHeaderImage;
float mLastMotionY = -1.0F;
float mLastScale = -1.0F;
float mMaxScale = -1.0F;
private OnScrollListener mOnScrollListener;
private ScalingRunnalable mScalingRunnalable;
private int mScreenHeight;
private ImageView mShadow;
public PullToZoomListView(Context paramContext) {
super(paramContext);
init(paramContext);
}
public PullToZoomListView(Context paramContext,
AttributeSet paramAttributeSet) {
super(paramContext, paramAttributeSet);
init(paramContext);
}
public PullToZoomListView(Context paramContext,
AttributeSet paramAttributeSet, int paramInt) {
super(paramContext, paramAttributeSet, paramInt);
init(paramContext);
}
private void endScraling() {
if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight)
Log.d("mmm", "endScraling");
this.mScalingRunnalable.startAnimation(200L);
}
private void init(Context paramContext) {
DisplayMetrics localDisplayMetrics = new DisplayMetrics();
((Activity) paramContext).getWindowManager().getDefaultDisplay()
.getMetrics(localDisplayMetrics);
this.mScreenHeight = localDisplayMetrics.heightPixels;
this.mHeaderContainer = new FrameLayout(paramContext);
this.mHeaderImage = new ImageView(paramContext);
int i = localDisplayMetrics.widthPixels;
setHeaderViewSize(i, (int) (9.0F * (i / 16.0F)));
this.mShadow = new ImageView(paramContext);
FrameLayout.LayoutParams localLayoutParams = new FrameLayout.LayoutParams(
-1, -2);
localLayoutParams.gravity = 80;
this.mShadow.setLayoutParams(localLayoutParams);
this.mHeaderContainer.addView(this.mHeaderImage);
this.mHeaderContainer.addView(this.mShadow);
addHeaderView(this.mHeaderContainer);
this.mScalingRunnalable = new ScalingRunnalable();
super.setOnScrollListener(this);
}
private void onSecondaryPointerUp(MotionEvent paramMotionEvent) {
int i = (paramMotionEvent.getAction()) >> 8;
if (paramMotionEvent.getPointerId(i) == this.mActivePointerId)
if (i != 0) {
int j = 1;
this.mLastMotionY = paramMotionEvent.getY(0);
this.mActivePointerId = paramMotionEvent.getPointerId(0);
return;
}
}
private void reset() {
this.mActivePointerId = -1;
this.mLastMotionY = -1.0F;
this.mMaxScale = -1.0F;
this.mLastScale = -1.0F;
}
public ImageView getHeaderView() {
return this.mHeaderImage;
}
public boolean onInterceptTouchEvent(MotionEvent paramMotionEvent) {
return super.onInterceptTouchEvent(paramMotionEvent);
}
protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2,
int paramInt3, int paramInt4) {
super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);
if (this.mHeaderHeight == 0)
this.mHeaderHeight = this.mHeaderContainer.getHeight();
}
@Override
public void onScroll(AbsListView paramAbsListView, int paramInt1,
int paramInt2, int paramInt3) {
Log.d("mmm", "onScroll");
float f = this.mHeaderHeight - this.mHeaderContainer.getBottom();
Log.d("mmm", "f|" + f);
if ((f > 0.0F) && (f < this.mHeaderHeight)) {
Log.d("mmm", "1");
int i = (int) (0.65D * f);
this.mHeaderImage.scrollTo(0, -i);
} else if (this.mHeaderImage.getScrollY() != 0) {
Log.d("mmm", "2");
this.mHeaderImage.scrollTo(0, 0);
}
if (this.mOnScrollListener != null) {
this.mOnScrollListener.onScroll(paramAbsListView, paramInt1,
paramInt2, paramInt3);
}
}
public void onScrollStateChanged(AbsListView paramAbsListView, int paramInt) {
if (this.mOnScrollListener != null)
this.mOnScrollListener.onScrollStateChanged(paramAbsListView,
paramInt);
}
public boolean onTouchEvent(MotionEvent paramMotionEvent) {
Log.d("mmm", "" + (0xFF & paramMotionEvent.getAction()));
switch (0xFF & paramMotionEvent.getAction()) {
case 4:
case 0:
if (!this.mScalingRunnalable.mIsFinished) {
this.mScalingRunnalable.abortAnimation();
}
this.mLastMotionY = paramMotionEvent.getY();
this.mActivePointerId = paramMotionEvent.getPointerId(0);
this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);
this.mLastScale = (this.mHeaderContainer.getBottom() / this.mHeaderHeight);
break;
case 2:
Log.d("mmm", "mActivePointerId" + mActivePointerId);
int j = paramMotionEvent.findPointerIndex(this.mActivePointerId);
if (j == -1) {
Log.e("PullToZoomListView", "Invalid pointerId="
+ this.mActivePointerId + " in onTouchEvent");
} else {
if (this.mLastMotionY == -1.0F)
this.mLastMotionY = paramMotionEvent.getY(j);
if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight) {
ViewGroup.LayoutParams localLayoutParams = this.mHeaderContainer
.getLayoutParams();
float f = ((paramMotionEvent.getY(j) - this.mLastMotionY + this.mHeaderContainer
.getBottom()) / this.mHeaderHeight - this.mLastScale)
/ 2.0F + this.mLastScale;
if ((this.mLastScale <= 1.0D) && (f < this.mLastScale)) {
localLayoutParams.height = this.mHeaderHeight;
this.mHeaderContainer
.setLayoutParams(localLayoutParams);
return super.onTouchEvent(paramMotionEvent);
}
this.mLastScale = Math.min(Math.max(f, 1.0F),
this.mMaxScale);
localLayoutParams.height = ((int) (this.mHeaderHeight * this.mLastScale));
if (localLayoutParams.height < this.mScreenHeight)
this.mHeaderContainer
.setLayoutParams(localLayoutParams);
this.mLastMotionY = paramMotionEvent.getY(j);
return true;
}
this.mLastMotionY = paramMotionEvent.getY(j);
}
break;
case 1:
reset();
endScraling();
break;
case 3:
int i = paramMotionEvent.getActionIndex();
this.mLastMotionY = paramMotionEvent.getY(i);
this.mActivePointerId = paramMotionEvent.getPointerId(i);
break;
case 5:
onSecondaryPointerUp(paramMotionEvent);
this.mLastMotionY = paramMotionEvent.getY(paramMotionEvent
.findPointerIndex(this.mActivePointerId));
break;
case 6:
}
return super.onTouchEvent(paramMotionEvent);
}
public void setHeaderViewSize(int paramInt1, int paramInt2) {
Object localObject = this.mHeaderContainer.getLayoutParams();
if (localObject == null)
localObject = new LayoutParams(paramInt1, paramInt2);
((ViewGroup.LayoutParams) localObject).width = paramInt1;
((ViewGroup.LayoutParams) localObject).height = paramInt2;
this.mHeaderContainer
.setLayoutParams((ViewGroup.LayoutParams) localObject);
this.mHeaderHeight = paramInt2;
}
public void setOnScrollListener(
OnScrollListener paramOnScrollListener) {
this.mOnScrollListener = paramOnScrollListener;
}
public void setShadow(int paramInt) {
this.mShadow.setBackgroundResource(paramInt);
}
class ScalingRunnalable implements Runnable {
long mDuration;
boolean mIsFinished = true;
float mScale;
long mStartTime;
ScalingRunnalable() {
}
public void abortAnimation() {
this.mIsFinished = true;
}
public boolean isFinished() {
return this.mIsFinished;
}
public void run() {
float f2;
ViewGroup.LayoutParams localLayoutParams;
if ((!this.mIsFinished) && (this.mScale > 1.0D)) {
float f1 = ((float) SystemClock.currentThreadTimeMillis() - (float) this.mStartTime)
/ (float) this.mDuration;
f2 = this.mScale - (this.mScale - 1.0F)
* PullToZoomListView.sInterpolator.getInterpolation(f1);
localLayoutParams = PullToZoomListView.this.mHeaderContainer
.getLayoutParams();
if (f2 > 1.0F) {
Log.d("mmm", "f2>1.0");
localLayoutParams.height = PullToZoomListView.this.mHeaderHeight;
localLayoutParams.height = ((int) (f2 * PullToZoomListView.this.mHeaderHeight));
PullToZoomListView.this.mHeaderContainer
.setLayoutParams(localLayoutParams);
PullToZoomListView.this.post(this);
return;
}
this.mIsFinished = true;
}
}
public void startAnimation(long paramLong) {
this.mStartTime = SystemClock.currentThreadTimeMillis();
this.mDuration = paramLong;
this.mScale = ((float) (PullToZoomListView.this.mHeaderContainer
.getBottom()) / PullToZoomListView.this.mHeaderHeight);
this.mIsFinished = false;
PullToZoomListView.this.post(this);
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/VP.java
================================================
package com.cjj.bb.view;
import io.vov.vitamio.MediaPlayer;
import android.graphics.Typeface;
public class VP {
public static final String SNAP_SHOT_PATH = "/Player";
public static final String SESSION_LAST_POSITION_SUFIX = ".last";
// key
public static final String SUB_SHADOW_COLOR = "vplayer_sub_shadow_color";
public static final String SUB_POSITION = "vplayer_sub_position";
public static final String SUB_SIZE = "vplayer_sub_size";
public static final String SUB_SHADOW_RADIUS = "vplayer_sub_shadow_radius";
public static final String SUB_ENABLED = "vplayer_sub_enabled";
public static final String SUB_SHADOW_ENABLED = "vplayer_sub_shadow_enabled";
public static final String SUB_TEXT_KEY = "sub_text";
public static final String SUB_PIXELS_KEY = "sub_pixels";
public static final String SUB_WIDTH_KEY = "sub_width";
public static final String SUB_HEIGHT_KEY = "sub_height";
// default value 1024
public static final int DEFAULT_BUF_SIZE = 512 * 1024;
public static final int DEFAULT_VIDEO_QUALITY = MediaPlayer.VIDEOQUALITY_MEDIUM;
public static final boolean DEFAULT_DEINTERLACE = false;
public static final float DEFAULT_ASPECT_RATIO = 0f;
public static final float DEFAULT_STEREO_VOLUME = 1.0f;
public static final String DEFAULT_META_ENCODING = "auto";
public static final String DEFAULT_SUB_ENCODING = "auto";
public static final int DEFAULT_SUB_STYLE = Typeface.BOLD;
public static final int DEFAULT_SUB_COLOR = 0xffffffff;
public static final int DEFAULT_SUB_SHADOWCOLOR = 0xff000000;
public static final float DEFAULT_SUB_SHADOWRADIUS = 2.0f;
public static final float DEFAULT_SUB_SIZE = 18.0f;
public static final float DEFAULT_SUB_POS = 10.0f;
public static final int DEFAULT_TYPEFACE_INT = 0;
public static final boolean DEFAULT_SUB_SHOWN = true;
public static final boolean DEFAULT_SUB_SHADOW = true;
public static final Typeface DEFAULT_TYPEFACE = Typeface.DEFAULT;
public static Typeface getTypeface(int type) {
switch (type) {
case 0:
return Typeface.DEFAULT;
case 1:
return Typeface.SANS_SERIF;
case 2:
return Typeface.SERIF;
case 3:
return Typeface.MONOSPACE;
default:
return DEFAULT_TYPEFACE;
}
}
}
================================================
FILE: app/src/main/java/com/cjj/bb/view/VideoView.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cjj.bb.view;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import com.cjj.bb.utils.DeviceUtils;
public class VideoView extends SurfaceView {
private Activity mActivity;
private SurfaceHolder mSurfaceHolder;
private int mSurfaceWidth, mSurfaceHeight;
private int mVideoMode = VIDEO_LAYOUT_SCALE;
public static final int VIDEO_LAYOUT_ORIGIN = 0;
public static final int VIDEO_LAYOUT_SCALE = 1;
public static final int VIDEO_LAYOUT_STRETCH = 2;
public static final int VIDEO_LAYOUT_ZOOM = 3;
public static final int VIDEO_LAYOUT_SCALE_ZOOM = 4;
public int mVideoHeight;
public VideoView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(mCallback);
getHolder().setFormat(PixelFormat.RGBA_8888);
}
@SuppressWarnings("deprecation")
public void initialize(Activity activity, SurfaceCallback l, boolean push) {
mActivity = activity;
mListener = l;
if (mSurfaceHolder == null)
mSurfaceHolder = getHolder();
// These methods is set to hw decoder or sw decoder, <= 2.3
if (push)
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
else
getHolder().setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
private void setSurfaceLayout(float userRatio, int videoWidth, int videoHeight, float videoAspectRatio) {
LayoutParams lp = getLayoutParams();
int windowWidth = DeviceUtils.getScreenWidth(mActivity);
int windowHeight = DeviceUtils.getScreenHeight(mActivity);
float windowRatio = windowWidth / (float) windowHeight;
float videoRatio = userRatio <= 0.01f ? videoAspectRatio : userRatio;
mSurfaceHeight = videoHeight;
mSurfaceWidth = videoWidth;
if (VIDEO_LAYOUT_ORIGIN == mVideoMode && mSurfaceWidth < windowWidth && mSurfaceHeight < windowHeight) {
lp.width = (int) (mSurfaceHeight * videoRatio);
lp.height = mSurfaceHeight;
} else if (mVideoMode == VIDEO_LAYOUT_ZOOM) {
lp.width = windowRatio > videoRatio ? windowWidth : (int) (videoRatio * windowHeight);
lp.height = windowRatio < videoRatio ? windowHeight : (int) (windowWidth / videoRatio);
} else if (mVideoMode == VIDEO_LAYOUT_SCALE_ZOOM && mVideoHeight > 0) {
lp.width = (int) (mVideoHeight * videoRatio);
lp.height = mVideoHeight;
} else {
boolean full = mVideoMode == VIDEO_LAYOUT_STRETCH;
lp.width = (full || windowRatio < videoRatio) ? windowWidth : (int) (videoRatio * windowHeight);
lp.height = (full || windowRatio > videoRatio) ? windowHeight : (int) (windowWidth / videoRatio);
}
mVideoHeight = lp.height;
setLayoutParams(lp);
getHolder().setFixedSize(mSurfaceWidth, mSurfaceHeight);
//Log.d("VIDEO: %dx%dx%f, Surface: %dx%d, LP: %dx%d, Window: %dx%dx%f", videoWidth, videoHeight, videoAspectRatio, mSurfaceWidth, mSurfaceHeight, lp.width, lp.height, windowWidth, windowHeight, windowRatio);
}
public void setVideoLayout(int layout, float userRatio, int videoWidth, int videoHeight, float videoRatio) {
mVideoMode = layout;
setSurfaceLayout(userRatio, videoWidth, videoHeight, videoRatio);
}
private SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
holder.setKeepScreenOn(true);
if (mListener != null)
mListener.onSurfaceChanged(holder, format, width, height);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
if (mListener != null)
mListener.onSurfaceCreated(holder);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mListener != null)
mListener.onSurfaceDestroyed(holder);
}
};
private SurfaceCallback mListener;
public interface SurfaceCallback {
public void onSurfaceCreated(SurfaceHolder holder);
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height);
public void onSurfaceDestroyed(SurfaceHolder holder);
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/CirclePageIndicator.java
================================================
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import com.cjj.bb.R;
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
/**
* Draws circles (one for each view). The current view position is filled and
* others are only stroked.
*/
public class CirclePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private float mRadius;
private final Paint mPaintPageFill = new Paint(ANTI_ALIAS_FLAG);
private final Paint mPaintStroke = new Paint(ANTI_ALIAS_FLAG);
private final Paint mPaintFill = new Paint(ANTI_ALIAS_FLAG);
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage;
private int mSnapPage;
private float mPageOffset;
private int mScrollState;
private int mOrientation;
private boolean mCentered;
private boolean mSnap;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
public CirclePageIndicator(Context context) {
this(context, null);
}
public CirclePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiCirclePageIndicatorStyle);
}
public CirclePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
//Load defaults from resources
final Resources res = getResources();
final int defaultPageColor = res.getColor(R.color.default_circle_indicator_page_color);
final int defaultFillColor = res.getColor(R.color.default_circle_indicator_fill_color);
final int defaultOrientation = res.getInteger(R.integer.default_circle_indicator_orientation);
final int defaultStrokeColor = res.getColor(R.color.default_circle_indicator_stroke_color);
final float defaultStrokeWidth = res.getDimension(R.dimen.default_circle_indicator_stroke_width);
final float defaultRadius = res.getDimension(R.dimen.default_circle_indicator_radius);
final boolean defaultCentered = res.getBoolean(R.bool.default_circle_indicator_centered);
final boolean defaultSnap = res.getBoolean(R.bool.default_circle_indicator_snap);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePageIndicator, defStyle, 0);
mCentered = a.getBoolean(R.styleable.CirclePageIndicator_centered, defaultCentered);
mOrientation = a.getInt(R.styleable.CirclePageIndicator_android_orientation, defaultOrientation);
mPaintPageFill.setStyle(Style.FILL);
mPaintPageFill.setColor(a.getColor(R.styleable.CirclePageIndicator_pageColor, defaultPageColor));
mPaintStroke.setStyle(Style.STROKE);
mPaintStroke.setColor(a.getColor(R.styleable.CirclePageIndicator_strokeColor, defaultStrokeColor));
mPaintStroke.setStrokeWidth(a.getDimension(R.styleable.CirclePageIndicator_strokeWidth, defaultStrokeWidth));
mPaintFill.setStyle(Style.FILL);
mPaintFill.setColor(a.getColor(R.styleable.CirclePageIndicator_fillColor, defaultFillColor));
mRadius = a.getDimension(R.styleable.CirclePageIndicator_radius, defaultRadius);
mSnap = a.getBoolean(R.styleable.CirclePageIndicator_snap, defaultSnap);
Drawable background = a.getDrawable(R.styleable.CirclePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public void setCentered(boolean centered) {
mCentered = centered;
invalidate();
}
public boolean isCentered() {
return mCentered;
}
public void setPageColor(int pageColor) {
mPaintPageFill.setColor(pageColor);
invalidate();
}
public int getPageColor() {
return mPaintPageFill.getColor();
}
public void setFillColor(int fillColor) {
mPaintFill.setColor(fillColor);
invalidate();
}
public int getFillColor() {
return mPaintFill.getColor();
}
public void setOrientation(int orientation) {
switch (orientation) {
case HORIZONTAL:
case VERTICAL:
mOrientation = orientation;
requestLayout();
break;
default:
throw new IllegalArgumentException("Orientation must be either HORIZONTAL or VERTICAL.");
}
}
public int getOrientation() {
return mOrientation;
}
public void setStrokeColor(int strokeColor) {
mPaintStroke.setColor(strokeColor);
invalidate();
}
public int getStrokeColor() {
return mPaintStroke.getColor();
}
public void setStrokeWidth(float strokeWidth) {
mPaintStroke.setStrokeWidth(strokeWidth);
invalidate();
}
public float getStrokeWidth() {
return mPaintStroke.getStrokeWidth();
}
public void setRadius(float radius) {
mRadius = radius;
invalidate();
}
public float getRadius() {
return mRadius;
}
public void setSnap(boolean snap) {
mSnap = snap;
invalidate();
}
public boolean isSnap() {
return mSnap;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
int longSize;
int longPaddingBefore;
int longPaddingAfter;
int shortPaddingBefore;
if (mOrientation == HORIZONTAL) {
longSize = getWidth();
longPaddingBefore = getPaddingLeft();
longPaddingAfter = getPaddingRight();
shortPaddingBefore = getPaddingTop();
} else {
longSize = getHeight();
longPaddingBefore = getPaddingTop();
longPaddingAfter = getPaddingBottom();
shortPaddingBefore = getPaddingLeft();
}
final float threeRadius = mRadius * 3;
final float shortOffset = shortPaddingBefore + mRadius;
float longOffset = longPaddingBefore + mRadius;
if (mCentered) {
longOffset += ((longSize - longPaddingBefore - longPaddingAfter) / 2.0f) - ((count * threeRadius) / 2.0f);
}
float dX;
float dY;
float pageFillRadius = mRadius;
if (mPaintStroke.getStrokeWidth() > 0) {
pageFillRadius -= mPaintStroke.getStrokeWidth() / 2.0f;
}
//Draw stroked circles
for (int iLoop = 0; iLoop < count; iLoop++) {
float drawLong = longOffset + (iLoop * threeRadius);
if (mOrientation == HORIZONTAL) {
dX = drawLong;
dY = shortOffset;
} else {
dX = shortOffset;
dY = drawLong;
}
// Only paint fill if not completely transparent
if (mPaintPageFill.getAlpha() > 0) {
canvas.drawCircle(dX, dY, pageFillRadius, mPaintPageFill);
}
// Only paint stroke if a stroke width was non-zero
if (pageFillRadius != mRadius) {
canvas.drawCircle(dX, dY, mRadius, mPaintStroke);
}
}
//Draw the filled circle according to the current scroll
float cx = (mSnap ? mSnapPage : mCurrentPage) * threeRadius;
if (!mSnap) {
cx += mPageOffset * threeRadius;
}
if (mOrientation == HORIZONTAL) {
dX = longOffset + cx;
dY = shortOffset;
} else {
dX = shortOffset;
dY = longOffset + cx;
}
canvas.drawCircle(dX, dY, mRadius, mPaintFill);
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPageOffset = positionOffset;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mSnap || mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
mSnapPage = position;
invalidate();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
/*
* (non-Javadoc)
*
* @see android.view.View#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mOrientation == HORIZONTAL) {
setMeasuredDimension(measureLong(widthMeasureSpec), measureShort(heightMeasureSpec));
} else {
setMeasuredDimension(measureShort(widthMeasureSpec), measureLong(heightMeasureSpec));
}
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureLong(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
//We were told how big to be
result = specSize;
} else {
//Calculate the width according the views count
final int count = mViewPager.getAdapter().getCount();
result = (int)(getPaddingLeft() + getPaddingRight()
+ (count * 2 * mRadius) + (count - 1) * mRadius + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureShort(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Measure the height
result = (int)(2 * mRadius + getPaddingTop() + getPaddingBottom() + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
mSnapPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator CREATOR = new Creator() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/IconPageIndicator.java
================================================
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import com.cjj.bb.R;
import static android.view.ViewGroup.LayoutParams.FILL_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class IconPageIndicator extends HorizontalScrollView implements PageIndicator {
private final IcsLinearLayout mIconsLayout;
private ViewPager mViewPager;
private OnPageChangeListener mListener;
private Runnable mIconSelector;
private int mSelectedIndex;
public IconPageIndicator(Context context) {
this(context, null);
}
public IconPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
mIconsLayout = new IcsLinearLayout(context, R.attr.vpiIconPageIndicatorStyle);
addView(mIconsLayout, new LayoutParams(WRAP_CONTENT, FILL_PARENT, Gravity.CENTER));
}
private void animateToIcon(final int position) {
final View iconView = mIconsLayout.getChildAt(position);
if (mIconSelector != null) {
removeCallbacks(mIconSelector);
}
mIconSelector = new Runnable() {
public void run() {
final int scrollPos = iconView.getLeft() - (getWidth() - iconView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mIconSelector = null;
}
};
post(mIconSelector);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mIconSelector != null) {
// Re-post the selector we saved
post(mIconSelector);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mIconSelector != null) {
removeCallbacks(mIconSelector);
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
if (mListener != null) {
mListener.onPageScrollStateChanged(arg0);
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mListener != null) {
mListener.onPageScrolled(arg0, arg1, arg2);
}
}
@Override
public void onPageSelected(int arg0) {
setCurrentItem(arg0);
if (mListener != null) {
mListener.onPageSelected(arg0);
}
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
PagerAdapter adapter = view.getAdapter();
if (adapter == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
view.setOnPageChangeListener(this);
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
mIconsLayout.removeAllViews();
IconPagerAdapter iconAdapter = (IconPagerAdapter) mViewPager.getAdapter();
int count = iconAdapter.getCount();
for (int i = 0; i < count; i++) {
ImageView view = new ImageView(getContext(), null, R.attr.vpiIconPageIndicatorStyle);
view.setImageResource(iconAdapter.getIconResId(i));
mIconsLayout.addView(view);
}
if (mSelectedIndex > count) {
mSelectedIndex = count - 1;
}
setCurrentItem(mSelectedIndex);
requestLayout();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mSelectedIndex = item;
mViewPager.setCurrentItem(item);
int tabCount = mIconsLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
View child = mIconsLayout.getChildAt(i);
boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animateToIcon(item);
}
}
}
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
mListener = listener;
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/IconPagerAdapter.java
================================================
package viewpagerindicator;
public interface IconPagerAdapter {
/**
* Get icon representing the page at {@code index} in the adapter.
*/
int getIconResId(int index);
// From PagerAdapter
int getCount();
}
================================================
FILE: app/src/main/java/viewpagerindicator/IcsLinearLayout.java
================================================
package viewpagerindicator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.LinearLayout;
/**
* A simple extension of a regular linear layout that supports the divider API
* of Android 4.0+. The dividers are added adjacent to the children by changing
* their layout params. If you need to rely on the margins which fall in the
* same orientation as the layout you should wrap the child in a simple
* {@link android.widget.FrameLayout} so it can receive the margin.
*/
class IcsLinearLayout extends LinearLayout {
private static final int[] LL = new int[] {
/* 0 */ android.R.attr.divider,
/* 1 */ android.R.attr.showDividers,
/* 2 */ android.R.attr.dividerPadding,
};
private static final int LL_DIVIDER = 0;
private static final int LL_SHOW_DIVIDER = 1;
private static final int LL_DIVIDER_PADDING = 2;
private Drawable mDivider;
private int mDividerWidth;
private int mDividerHeight;
private int mShowDividers;
private int mDividerPadding;
public IcsLinearLayout(Context context, int themeAttr) {
super(context);
TypedArray a = context.obtainStyledAttributes(null, LL, themeAttr, 0);
setDividerDrawable(a.getDrawable(IcsLinearLayout.LL_DIVIDER));
mDividerPadding = a.getDimensionPixelSize(LL_DIVIDER_PADDING, 0);
mShowDividers = a.getInteger(LL_SHOW_DIVIDER, SHOW_DIVIDER_NONE);
a.recycle();
}
public void setDividerDrawable(Drawable divider) {
if (divider == mDivider) {
return;
}
mDivider = divider;
if (divider != null) {
mDividerWidth = divider.getIntrinsicWidth();
mDividerHeight = divider.getIntrinsicHeight();
} else {
mDividerWidth = 0;
mDividerHeight = 0;
}
setWillNotDraw(divider == null);
requestLayout();
}
@Override
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
final int index = indexOfChild(child);
final int orientation = getOrientation();
final LayoutParams params = (LayoutParams) child.getLayoutParams();
if (hasDividerBeforeChildAt(index)) {
if (orientation == VERTICAL) {
//Account for the divider by pushing everything up
params.topMargin = mDividerHeight;
} else {
//Account for the divider by pushing everything left
params.leftMargin = mDividerWidth;
}
}
final int count = getChildCount();
if (index == count - 1) {
if (hasDividerBeforeChildAt(count)) {
if (orientation == VERTICAL) {
params.bottomMargin = mDividerHeight;
} else {
params.rightMargin = mDividerWidth;
}
}
}
super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
}
@Override
protected void onDraw(Canvas canvas) {
if (mDivider != null) {
if (getOrientation() == VERTICAL) {
drawDividersVertical(canvas);
} else {
drawDividersHorizontal(canvas);
}
}
super.onDraw(canvas);
}
private void drawDividersVertical(Canvas canvas) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/;
drawHorizontalDivider(canvas, top);
}
}
}
if (hasDividerBeforeChildAt(count)) {
final View child = getChildAt(count - 1);
int bottom = 0;
if (child == null) {
bottom = getHeight() - getPaddingBottom() - mDividerHeight;
} else {
//final LayoutParams lp = (LayoutParams) child.getLayoutParams();
bottom = child.getBottom()/* + lp.bottomMargin*/;
}
drawHorizontalDivider(canvas, bottom);
}
}
private void drawDividersHorizontal(Canvas canvas) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/;
drawVerticalDivider(canvas, left);
}
}
}
if (hasDividerBeforeChildAt(count)) {
final View child = getChildAt(count - 1);
int right = 0;
if (child == null) {
right = getWidth() - getPaddingRight() - mDividerWidth;
} else {
//final LayoutParams lp = (LayoutParams) child.getLayoutParams();
right = child.getRight()/* + lp.rightMargin*/;
}
drawVerticalDivider(canvas, right);
}
}
private void drawHorizontalDivider(Canvas canvas, int top) {
mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,
getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);
mDivider.draw(canvas);
}
private void drawVerticalDivider(Canvas canvas, int left) {
mDivider.setBounds(left, getPaddingTop() + mDividerPadding,
left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding);
mDivider.draw(canvas);
}
private boolean hasDividerBeforeChildAt(int childIndex) {
if (childIndex == 0 || childIndex == getChildCount()) {
return false;
}
if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {
boolean hasVisibleViewBefore = false;
for (int i = childIndex - 1; i >= 0; i--) {
if (getChildAt(i).getVisibility() != GONE) {
hasVisibleViewBefore = true;
break;
}
}
return hasVisibleViewBefore;
}
return false;
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/LinePageIndicator.java
================================================
/*
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import com.cjj.bb.R;
/**
* Draws a line for each page. The current page line is colored differently
* than the unselected page lines.
*/
public class LinePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private final Paint mPaintUnselected = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintSelected = new Paint(Paint.ANTI_ALIAS_FLAG);
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage;
private boolean mCentered;
private float mLineWidth;
private float mGapWidth;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
public LinePageIndicator(Context context) {
this(context, null);
}
public LinePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiLinePageIndicatorStyle);
}
public LinePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
final Resources res = getResources();
//Load defaults from resources
final int defaultSelectedColor = res.getColor(R.color.default_line_indicator_selected_color);
final int defaultUnselectedColor = res.getColor(R.color.default_line_indicator_unselected_color);
final float defaultLineWidth = res.getDimension(R.dimen.default_line_indicator_line_width);
final float defaultGapWidth = res.getDimension(R.dimen.default_line_indicator_gap_width);
final float defaultStrokeWidth = res.getDimension(R.dimen.default_line_indicator_stroke_width);
final boolean defaultCentered = res.getBoolean(R.bool.default_line_indicator_centered);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LinePageIndicator, defStyle, 0);
mCentered = a.getBoolean(R.styleable.LinePageIndicator_centered, defaultCentered);
mLineWidth = a.getDimension(R.styleable.LinePageIndicator_lineWidth, defaultLineWidth);
mGapWidth = a.getDimension(R.styleable.LinePageIndicator_gapWidth, defaultGapWidth);
setStrokeWidth(a.getDimension(R.styleable.LinePageIndicator_strokeWidth, defaultStrokeWidth));
mPaintUnselected.setColor(a.getColor(R.styleable.LinePageIndicator_unselectedColor, defaultUnselectedColor));
mPaintSelected.setColor(a.getColor(R.styleable.LinePageIndicator_selectedColor, defaultSelectedColor));
Drawable background = a.getDrawable(R.styleable.LinePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public void setCentered(boolean centered) {
mCentered = centered;
invalidate();
}
public boolean isCentered() {
return mCentered;
}
public void setUnselectedColor(int unselectedColor) {
mPaintUnselected.setColor(unselectedColor);
invalidate();
}
public int getUnselectedColor() {
return mPaintUnselected.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaintSelected.setColor(selectedColor);
invalidate();
}
public int getSelectedColor() {
return mPaintSelected.getColor();
}
public void setLineWidth(float lineWidth) {
mLineWidth = lineWidth;
invalidate();
}
public float getLineWidth() {
return mLineWidth;
}
public void setStrokeWidth(float lineHeight) {
mPaintSelected.setStrokeWidth(lineHeight);
mPaintUnselected.setStrokeWidth(lineHeight);
invalidate();
}
public float getStrokeWidth() {
return mPaintSelected.getStrokeWidth();
}
public void setGapWidth(float gapWidth) {
mGapWidth = gapWidth;
invalidate();
}
public float getGapWidth() {
return mGapWidth;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
final float lineWidthAndGap = mLineWidth + mGapWidth;
final float indicatorWidth = (count * lineWidthAndGap) - mGapWidth;
final float paddingTop = getPaddingTop();
final float paddingLeft = getPaddingLeft();
final float paddingRight = getPaddingRight();
float verticalOffset = paddingTop + ((getHeight() - paddingTop - getPaddingBottom()) / 2.0f);
float horizontalOffset = paddingLeft;
if (mCentered) {
horizontalOffset += ((getWidth() - paddingLeft - paddingRight) / 2.0f) - (indicatorWidth / 2.0f);
}
//Draw stroked circles
for (int i = 0; i < count; i++) {
float dx1 = horizontalOffset + (i * lineWidthAndGap);
float dx2 = dx1 + mLineWidth;
canvas.drawLine(dx1, verticalOffset, dx2, verticalOffset, (i == mCurrentPage) ? mPaintSelected : mPaintUnselected);
}
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager viewPager) {
if (mViewPager == viewPager) {
return;
}
if (mViewPager != null) {
//Clear us from the old pager.
mViewPager.setOnPageChangeListener(null);
}
if (viewPager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
mCurrentPage = position;
invalidate();
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec) {
float result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
//We were told how big to be
result = specSize;
} else {
//Calculate the width according the views count
final int count = mViewPager.getAdapter().getCount();
result = getPaddingLeft() + getPaddingRight() + (count * mLineWidth) + ((count - 1) * mGapWidth);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return (int)FloatMath.ceil(result);
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec) {
float result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Measure the height
result = mPaintSelected.getStrokeWidth() + getPaddingTop() + getPaddingBottom();
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return (int)FloatMath.ceil(result);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator CREATOR = new Creator() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/PageIndicator.java
================================================
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.support.v4.view.ViewPager;
/**
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* Bind the indicator to a ViewPager.
*
* @param view
*/
void setViewPager(ViewPager view);
/**
* Bind the indicator to a ViewPager.
*
* @param view
* @param initialPosition
*/
void setViewPager(ViewPager view, int initialPosition);
/**
*
Set the current page of both the ViewPager and indicator.
*
*
This must be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).
*
* @param item
*/
void setCurrentItem(int item);
/**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
/**
* Notify the indicator that the fragment list has changed.
*/
void notifyDataSetChanged();
}
================================================
FILE: app/src/main/java/viewpagerindicator/TabPageIndicator.java
================================================
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.cjj.bb.R;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class TabPageIndicator extends HorizontalScrollView implements PageIndicator {
/** Title text used when no title is provided by the adapter. */
private static final CharSequence EMPTY_TITLE = "";
/**
* Interface for a callback when the selected tab has been reselected.
*/
public interface OnTabReselectedListener {
/**
* Callback when the selected tab has been reselected.
*
* @param position Position of the current center item.
*/
void onTabReselected(int position);
}
private Runnable mTabSelector;
private final OnClickListener mTabClickListener = new OnClickListener() {
public void onClick(View view) {
TabView tabView = (TabView)view;
final int oldSelected = mViewPager.getCurrentItem();
final int newSelected = tabView.getIndex();
mViewPager.setCurrentItem(newSelected);
if (oldSelected == newSelected && mTabReselectedListener != null) {
mTabReselectedListener.onTabReselected(newSelected);
}
}
};
private final IcsLinearLayout mTabLayout;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mMaxTabWidth;
private int mSelectedTabIndex;
private OnTabReselectedListener mTabReselectedListener;
public TabPageIndicator(Context context) {
this(context, null);
}
public TabPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
mTabLayout = new IcsLinearLayout(context, R.attr.vpiTabPageIndicatorStyle);
addView(mTabLayout, new ViewGroup.LayoutParams(WRAP_CONTENT, MATCH_PARENT));
}
public void setOnTabReselectedListener(OnTabReselectedListener listener) {
mTabReselectedListener = listener;
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
setFillViewport(lockedExpanded);
final int childCount = mTabLayout.getChildCount();
if (childCount > 1 && (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
if (childCount > 2) {
mMaxTabWidth = (int)(MeasureSpec.getSize(widthMeasureSpec) * 0.4f);
} else {
mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
}
} else {
mMaxTabWidth = -1;
}
final int oldWidth = getMeasuredWidth();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int newWidth = getMeasuredWidth();
if (lockedExpanded && oldWidth != newWidth) {
// Recenter the tab display if we're at a new (scrollable) size.
setCurrentItem(mSelectedTabIndex);
}
}
private void animateToTab(final int position) {
final View tabView = mTabLayout.getChildAt(position);
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mTabSelector != null) {
// Re-post the selector we saved
post(mTabSelector);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
}
private void addTab(int index, CharSequence text, int iconResId) {
final TabView tabView = new TabView(getContext());
tabView.mIndex = index;
tabView.setFocusable(true);
tabView.setOnClickListener(mTabClickListener);
tabView.setText(text);
if (iconResId != 0) {
tabView.setCompoundDrawablesWithIntrinsicBounds(iconResId, 0, 0, 0);
}
mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, MATCH_PARENT, 1));
}
@Override
public void onPageScrollStateChanged(int arg0) {
if (mListener != null) {
mListener.onPageScrollStateChanged(arg0);
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mListener != null) {
mListener.onPageScrolled(arg0, arg1, arg2);
}
}
@Override
public void onPageSelected(int arg0) {
setCurrentItem(arg0);
if (mListener != null) {
mListener.onPageSelected(arg0);
}
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
final PagerAdapter adapter = view.getAdapter();
if (adapter == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
view.setOnPageChangeListener(this);
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
mTabLayout.removeAllViews();
PagerAdapter adapter = mViewPager.getAdapter();
IconPagerAdapter iconAdapter = null;
if (adapter instanceof IconPagerAdapter) {
iconAdapter = (IconPagerAdapter)adapter;
}
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
CharSequence title = adapter.getPageTitle(i);
if (title == null) {
title = EMPTY_TITLE;
}
int iconResId = 0;
if (iconAdapter != null) {
iconResId = iconAdapter.getIconResId(i);
}
addTab(i, title, iconResId);
}
if (mSelectedTabIndex > count) {
mSelectedTabIndex = count - 1;
}
setCurrentItem(mSelectedTabIndex);
requestLayout();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mSelectedTabIndex = item;
mViewPager.setCurrentItem(item);
final int tabCount = mTabLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
final View child = mTabLayout.getChildAt(i);
final boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animateToTab(item);
}
}
}
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
mListener = listener;
}
private class TabView extends TextView {
private int mIndex;
public TabView(Context context) {
super(context, null, R.attr.vpiTabPageIndicatorStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Re-measure if we went beyond our maximum size.
if (mMaxTabWidth > 0 && getMeasuredWidth() > mMaxTabWidth) {
super.onMeasure(MeasureSpec.makeMeasureSpec(mMaxTabWidth, MeasureSpec.EXACTLY),
heightMeasureSpec);
}
}
public int getIndex() {
return mIndex;
}
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/TitlePageIndicator.java
================================================
/*
* Copyright (C) 2011 Jake Wharton
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Francisco Figueiredo Jr.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import com.cjj.bb.R;
import java.util.ArrayList;
/**
* A TitlePageIndicator is a PageIndicator which displays the title of left view
* (if exist), the title of the current select view (centered) and the title of
* the right view (if exist). When the user scrolls the ViewPager then titles are
* also scrolled.
*/
public class TitlePageIndicator extends View implements PageIndicator {
/**
* Percentage indicating what percentage of the screen width away from
* center should the underline be fully faded. A value of 0.25 means that
* halfway between the center of the screen and an edge.
*/
private static final float SELECTION_FADE_PERCENTAGE = 0.25f;
/**
* Percentage indicating what percentage of the screen width away from
* center should the selected text bold turn off. A value of 0.05 means
* that 10% between the center and an edge.
*/
private static final float BOLD_FADE_PERCENTAGE = 0.05f;
/**
* Title text used when no title is provided by the adapter.
*/
private static final String EMPTY_TITLE = "";
/**
* Interface for a callback when the center item has been clicked.
*/
public interface OnCenterItemClickListener {
/**
* Callback when the center item has been clicked.
*
* @param position Position of the current center item.
*/
void onCenterItemClick(int position);
}
public enum IndicatorStyle {
None(0), Triangle(1), Underline(2);
public final int value;
private IndicatorStyle(int value) {
this.value = value;
}
public static IndicatorStyle fromValue(int value) {
for (IndicatorStyle style : IndicatorStyle.values()) {
if (style.value == value) {
return style;
}
}
return null;
}
}
public enum LinePosition {
Bottom(0), Top(1);
public final int value;
private LinePosition(int value) {
this.value = value;
}
public static LinePosition fromValue(int value) {
for (LinePosition position : LinePosition.values()) {
if (position.value == value) {
return position;
}
}
return null;
}
}
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage = -1;
private float mPageOffset;
private int mScrollState;
private final Paint mPaintText = new Paint();
private boolean mBoldText;
private int mColorText;
private int mColorSelected;
private Path mPath = new Path();
private final Rect mBounds = new Rect();
private final Paint mPaintFooterLine = new Paint();
private IndicatorStyle mFooterIndicatorStyle;
private LinePosition mLinePosition;
private final Paint mPaintFooterIndicator = new Paint();
private float mFooterIndicatorHeight;
private float mFooterIndicatorUnderlinePadding;
private float mFooterPadding;
private float mTitlePadding;
private float mTopPadding;
/** Left and right side padding for not active view titles. */
private float mClipPadding;
private float mFooterLineHeight;
private static final int INVALID_POINTER = -1;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
private OnCenterItemClickListener mCenterItemClickListener;
public TitlePageIndicator(Context context) {
this(context, null);
}
public TitlePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiTitlePageIndicatorStyle);
}
public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
//Load defaults from resources
final Resources res = getResources();
final int defaultFooterColor = res.getColor(R.color.default_title_indicator_footer_color);
final float defaultFooterLineHeight = res.getDimension(R.dimen.default_title_indicator_footer_line_height);
final int defaultFooterIndicatorStyle = res.getInteger(R.integer.default_title_indicator_footer_indicator_style);
final float defaultFooterIndicatorHeight = res.getDimension(R.dimen.default_title_indicator_footer_indicator_height);
final float defaultFooterIndicatorUnderlinePadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_underline_padding);
final float defaultFooterPadding = res.getDimension(R.dimen.default_title_indicator_footer_padding);
final int defaultLinePosition = res.getInteger(R.integer.default_title_indicator_line_position);
final int defaultSelectedColor = res.getColor(R.color.default_title_indicator_selected_color);
final boolean defaultSelectedBold = res.getBoolean(R.bool.default_title_indicator_selected_bold);
final int defaultTextColor = res.getColor(R.color.default_title_indicator_text_color);
final float defaultTextSize = res.getDimension(R.dimen.default_title_indicator_text_size);
final float defaultTitlePadding = res.getDimension(R.dimen.default_title_indicator_title_padding);
final float defaultClipPadding = res.getDimension(R.dimen.default_title_indicator_clip_padding);
final float defaultTopPadding = res.getDimension(R.dimen.default_title_indicator_top_padding);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitlePageIndicator, defStyle, 0);
//Retrieve the colors to be used for this view and apply them.
mFooterLineHeight = a.getDimension(R.styleable.TitlePageIndicator_footerLineHeight, defaultFooterLineHeight);
mFooterIndicatorStyle = IndicatorStyle.fromValue(a.getInteger(R.styleable.TitlePageIndicator_footerIndicatorStyle, defaultFooterIndicatorStyle));
mFooterIndicatorHeight = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorHeight, defaultFooterIndicatorHeight);
mFooterIndicatorUnderlinePadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorUnderlinePadding, defaultFooterIndicatorUnderlinePadding);
mFooterPadding = a.getDimension(R.styleable.TitlePageIndicator_footerPadding, defaultFooterPadding);
mLinePosition = LinePosition.fromValue(a.getInteger(R.styleable.TitlePageIndicator_linePosition, defaultLinePosition));
mTopPadding = a.getDimension(R.styleable.TitlePageIndicator_topPadding, defaultTopPadding);
mTitlePadding = a.getDimension(R.styleable.TitlePageIndicator_titlePadding, defaultTitlePadding);
mClipPadding = a.getDimension(R.styleable.TitlePageIndicator_clipPadding, defaultClipPadding);
mColorSelected = a.getColor(R.styleable.TitlePageIndicator_selectedColor, defaultSelectedColor);
mColorText = a.getColor(R.styleable.TitlePageIndicator_android_textColor, defaultTextColor);
mBoldText = a.getBoolean(R.styleable.TitlePageIndicator_selectedBold, defaultSelectedBold);
final float textSize = a.getDimension(R.styleable.TitlePageIndicator_android_textSize, defaultTextSize);
final int footerColor = a.getColor(R.styleable.TitlePageIndicator_footerColor, defaultFooterColor);
mPaintText.setTextSize(textSize);
mPaintText.setAntiAlias(true);
mPaintFooterLine.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterIndicator.setColor(footerColor);
Drawable background = a.getDrawable(R.styleable.TitlePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public int getFooterColor() {
return mPaintFooterLine.getColor();
}
public void setFooterColor(int footerColor) {
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator.setColor(footerColor);
invalidate();
}
public float getFooterLineHeight() {
return mFooterLineHeight;
}
public void setFooterLineHeight(float footerLineHeight) {
mFooterLineHeight = footerLineHeight;
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
invalidate();
}
public float getFooterIndicatorHeight() {
return mFooterIndicatorHeight;
}
public void setFooterIndicatorHeight(float footerTriangleHeight) {
mFooterIndicatorHeight = footerTriangleHeight;
invalidate();
}
public float getFooterIndicatorPadding() {
return mFooterPadding;
}
public void setFooterIndicatorPadding(float footerIndicatorPadding) {
mFooterPadding = footerIndicatorPadding;
invalidate();
}
public IndicatorStyle getFooterIndicatorStyle() {
return mFooterIndicatorStyle;
}
public void setFooterIndicatorStyle(IndicatorStyle indicatorStyle) {
mFooterIndicatorStyle = indicatorStyle;
invalidate();
}
public LinePosition getLinePosition() {
return mLinePosition;
}
public void setLinePosition(LinePosition linePosition) {
mLinePosition = linePosition;
invalidate();
}
public int getSelectedColor() {
return mColorSelected;
}
public void setSelectedColor(int selectedColor) {
mColorSelected = selectedColor;
invalidate();
}
public boolean isSelectedBold() {
return mBoldText;
}
public void setSelectedBold(boolean selectedBold) {
mBoldText = selectedBold;
invalidate();
}
public int getTextColor() {
return mColorText;
}
public void setTextColor(int textColor) {
mPaintText.setColor(textColor);
mColorText = textColor;
invalidate();
}
public float getTextSize() {
return mPaintText.getTextSize();
}
public void setTextSize(float textSize) {
mPaintText.setTextSize(textSize);
invalidate();
}
public float getTitlePadding() {
return this.mTitlePadding;
}
public void setTitlePadding(float titlePadding) {
mTitlePadding = titlePadding;
invalidate();
}
public float getTopPadding() {
return this.mTopPadding;
}
public void setTopPadding(float topPadding) {
mTopPadding = topPadding;
invalidate();
}
public float getClipPadding() {
return this.mClipPadding;
}
public void setClipPadding(float clipPadding) {
mClipPadding = clipPadding;
invalidate();
}
public void setTypeface(Typeface typeface) {
mPaintText.setTypeface(typeface);
invalidate();
}
public Typeface getTypeface() {
return mPaintText.getTypeface();
}
/*
* (non-Javadoc)
*
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
// mCurrentPage is -1 on first start and after orientation changed. If so, retrieve the correct index from viewpager.
if (mCurrentPage == -1 && mViewPager != null) {
mCurrentPage = mViewPager.getCurrentItem();
}
//Calculate views bounds
ArrayList bounds = calculateAllBounds(mPaintText);
final int boundsSize = bounds.size();
//Make sure we're on a page that still exists
if (mCurrentPage >= boundsSize) {
setCurrentItem(boundsSize - 1);
return;
}
final int countMinusOne = count - 1;
final float halfWidth = getWidth() / 2f;
final int left = getLeft();
final float leftClip = left + mClipPadding;
final int width = getWidth();
int height = getHeight();
final int right = left + width;
final float rightClip = right - mClipPadding;
int page = mCurrentPage;
float offsetPercent;
if (mPageOffset <= 0.5) {
offsetPercent = mPageOffset;
} else {
page += 1;
offsetPercent = 1 - mPageOffset;
}
final boolean currentSelected = (offsetPercent <= SELECTION_FADE_PERCENTAGE);
final boolean currentBold = (offsetPercent <= BOLD_FADE_PERCENTAGE);
final float selectedPercent = (SELECTION_FADE_PERCENTAGE - offsetPercent) / SELECTION_FADE_PERCENTAGE;
//Verify if the current view must be clipped to the screen
Rect curPageBound = bounds.get(mCurrentPage);
float curPageWidth = curPageBound.right - curPageBound.left;
if (curPageBound.left < leftClip) {
//Try to clip to the screen (left side)
clipViewOnTheLeft(curPageBound, curPageWidth, left);
}
if (curPageBound.right > rightClip) {
//Try to clip to the screen (right side)
clipViewOnTheRight(curPageBound, curPageWidth, right);
}
//Left views starting from the current position
if (mCurrentPage > 0) {
for (int i = mCurrentPage - 1; i >= 0; i--) {
Rect bound = bounds.get(i);
//Is left side is outside the screen
if (bound.left < leftClip) {
int w = bound.right - bound.left;
//Try to clip to the screen (left side)
clipViewOnTheLeft(bound, w, left);
//Except if there's an intersection with the right view
Rect rightBound = bounds.get(i + 1);
//Intersection
if (bound.right + mTitlePadding > rightBound.left) {
bound.left = (int) (rightBound.left - w - mTitlePadding);
bound.right = bound.left + w;
}
}
}
}
//Right views starting from the current position
if (mCurrentPage < countMinusOne) {
for (int i = mCurrentPage + 1 ; i < count; i++) {
Rect bound = bounds.get(i);
//If right side is outside the screen
if (bound.right > rightClip) {
int w = bound.right - bound.left;
//Try to clip to the screen (right side)
clipViewOnTheRight(bound, w, right);
//Except if there's an intersection with the left view
Rect leftBound = bounds.get(i - 1);
//Intersection
if (bound.left - mTitlePadding < leftBound.right) {
bound.left = (int) (leftBound.right + mTitlePadding);
bound.right = bound.left + w;
}
}
}
}
//Now draw views
int colorTextAlpha = mColorText >>> 24;
for (int i = 0; i < count; i++) {
//Get the title
Rect bound = bounds.get(i);
//Only if one side is visible
if ((bound.left > left && bound.left < right) || (bound.right > left && bound.right < right)) {
final boolean currentPage = (i == page);
final CharSequence pageTitle = getTitle(i);
//Only set bold if we are within bounds
mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText);
//Draw text as unselected
mPaintText.setColor(mColorText);
if(currentPage && currentSelected) {
//Fade out/in unselected text as the selected text fades in/out
mPaintText.setAlpha(colorTextAlpha - (int)(colorTextAlpha * selectedPercent));
}
//Except if there's an intersection with the right view
if (i < boundsSize - 1) {
Rect rightBound = bounds.get(i + 1);
//Intersection
if (bound.right + mTitlePadding > rightBound.left) {
int w = bound.right - bound.left;
bound.left = (int) (rightBound.left - w - mTitlePadding);
bound.right = bound.left + w;
}
}
canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding, mPaintText);
//If we are within the selected bounds draw the selected text
if (currentPage && currentSelected) {
mPaintText.setColor(mColorSelected);
mPaintText.setAlpha((int)((mColorSelected >>> 24) * selectedPercent));
canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding, mPaintText);
}
}
}
//If we want the line on the top change height to zero and invert the line height to trick the drawing code
float footerLineHeight = mFooterLineHeight;
float footerIndicatorLineHeight = mFooterIndicatorHeight;
if (mLinePosition == LinePosition.Top) {
height = 0;
footerLineHeight = -footerLineHeight;
footerIndicatorLineHeight = -footerIndicatorLineHeight;
}
//Draw the footer line
mPath.reset();
mPath.moveTo(0, height - footerLineHeight / 2f);
mPath.lineTo(width, height - footerLineHeight / 2f);
mPath.close();
canvas.drawPath(mPath, mPaintFooterLine);
float heightMinusLine = height - footerLineHeight;
switch (mFooterIndicatorStyle) {
case Triangle:
mPath.reset();
mPath.moveTo(halfWidth, heightMinusLine - footerIndicatorLineHeight);
mPath.lineTo(halfWidth + footerIndicatorLineHeight, heightMinusLine);
mPath.lineTo(halfWidth - footerIndicatorLineHeight, heightMinusLine);
mPath.close();
canvas.drawPath(mPath, mPaintFooterIndicator);
break;
case Underline:
if (!currentSelected || page >= boundsSize) {
break;
}
Rect underlineBounds = bounds.get(page);
final float rightPlusPadding = underlineBounds.right + mFooterIndicatorUnderlinePadding;
final float leftMinusPadding = underlineBounds.left - mFooterIndicatorUnderlinePadding;
final float heightMinusLineMinusIndicator = heightMinusLine - footerIndicatorLineHeight;
mPath.reset();
mPath.moveTo(leftMinusPadding, heightMinusLine);
mPath.lineTo(rightPlusPadding, heightMinusLine);
mPath.lineTo(rightPlusPadding, heightMinusLineMinusIndicator);
mPath.lineTo(leftMinusPadding, heightMinusLineMinusIndicator);
mPath.close();
mPaintFooterIndicator.setAlpha((int)(0xFF * selectedPercent));
canvas.drawPath(mPath, mPaintFooterIndicator);
mPaintFooterIndicator.setAlpha(0xFF);
break;
}
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
final float leftThird = halfWidth - sixthWidth;
final float rightThird = halfWidth + sixthWidth;
final float eventX = ev.getX();
if (eventX < leftThird) {
if (mCurrentPage > 0) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
}
} else if (eventX > rightThird) {
if (mCurrentPage < count - 1) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
} else {
//Middle third
if (mCenterItemClickListener != null && action != MotionEvent.ACTION_CANCEL) {
mCenterItemClickListener.onCenterItemClick(mCurrentPage);
}
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
/**
* Set bounds for the right textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheRight(Rect curViewBound, float curViewWidth, int right) {
curViewBound.right = (int) (right - mClipPadding);
curViewBound.left = (int) (curViewBound.right - curViewWidth);
}
/**
* Set bounds for the left textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheLeft(Rect curViewBound, float curViewWidth, int left) {
curViewBound.left = (int) (left + mClipPadding);
curViewBound.right = (int) (mClipPadding + curViewWidth);
}
/**
* Calculate views bounds and scroll them according to the current index
*
* @param paint
* @return
*/
private ArrayList calculateAllBounds(Paint paint) {
ArrayList list = new ArrayList();
//For each views (If no values then add a fake one)
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final int halfWidth = width / 2;
for (int i = 0; i < count; i++) {
Rect bounds = calcBounds(i, paint);
int w = bounds.right - bounds.left;
int h = bounds.bottom - bounds.top;
bounds.left = (int)(halfWidth - (w / 2f) + ((i - mCurrentPage - mPageOffset) * width));
bounds.right = bounds.left + w;
bounds.top = 0;
bounds.bottom = h;
list.add(bounds);
}
return list;
}
/**
* Calculate the bounds for a view's title
*
* @param index
* @param paint
* @return
*/
private Rect calcBounds(int index, Paint paint) {
//Calculate the text bounds
Rect bounds = new Rect();
CharSequence title = getTitle(index);
bounds.right = (int) paint.measureText(title, 0, title.length());
bounds.bottom = (int) (paint.descent() - paint.ascent());
return bounds;
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
/**
* Set a callback listener for the center item click.
*
* @param listener Callback instance.
*/
public void setOnCenterItemClickListener(OnCenterItemClickListener listener) {
mCenterItemClickListener = listener;
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPageOffset = positionOffset;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
invalidate();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Measure our width in whatever mode specified
final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
//Determine our height
float height;
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightSpecMode == MeasureSpec.EXACTLY) {
//We were told how big to be
height = MeasureSpec.getSize(heightMeasureSpec);
} else {
//Calculate the text bounds
mBounds.setEmpty();
mBounds.bottom = (int) (mPaintText.descent() - mPaintText.ascent());
height = mBounds.bottom - mBounds.top + mFooterLineHeight + mFooterPadding + mTopPadding;
if (mFooterIndicatorStyle != IndicatorStyle.None) {
height += mFooterIndicatorHeight;
}
}
final int measuredHeight = (int)height;
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator CREATOR = new Creator() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
private CharSequence getTitle(int i) {
CharSequence title = mViewPager.getAdapter().getPageTitle(i);
if (title == null) {
title = EMPTY_TITLE;
}
return title;
}
}
================================================
FILE: app/src/main/java/viewpagerindicator/UnderlinePageIndicator.java
================================================
/*
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import com.cjj.bb.R;
/**
* Draws a line for each page. The current page line is colored differently
* than the unselected page lines.
*/
public class UnderlinePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private static final int FADE_FRAME_MS = 30;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private boolean mFades;
private int mFadeDelay;
private int mFadeLength;
private int mFadeBy;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mScrollState;
private int mCurrentPage;
private float mPositionOffset;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
private final Runnable mFadeRunnable = new Runnable() {
@Override public void run() {
if (!mFades) return;
final int alpha = Math.max(mPaint.getAlpha() - mFadeBy, 0);
mPaint.setAlpha(alpha);
invalidate();
if (alpha > 0) {
postDelayed(this, FADE_FRAME_MS);
}
}
};
public UnderlinePageIndicator(Context context) {
this(context, null);
}
public UnderlinePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiUnderlinePageIndicatorStyle);
}
public UnderlinePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
final Resources res = getResources();
//Load defaults from resources
final boolean defaultFades = res.getBoolean(R.bool.default_underline_indicator_fades);
final int defaultFadeDelay = res.getInteger(R.integer.default_underline_indicator_fade_delay);
final int defaultFadeLength = res.getInteger(R.integer.default_underline_indicator_fade_length);
final int defaultSelectedColor = res.getColor(R.color.default_underline_indicator_selected_color);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.UnderlinePageIndicator, defStyle, 0);
setFades(a.getBoolean(R.styleable.UnderlinePageIndicator_fades, defaultFades));
setSelectedColor(a.getColor(R.styleable.UnderlinePageIndicator_selectedColor, defaultSelectedColor));
setFadeDelay(a.getInteger(R.styleable.UnderlinePageIndicator_fadeDelay, defaultFadeDelay));
setFadeLength(a.getInteger(R.styleable.UnderlinePageIndicator_fadeLength, defaultFadeLength));
Drawable background = a.getDrawable(R.styleable.UnderlinePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public boolean getFades() {
return mFades;
}
public void setFades(boolean fades) {
if (fades != mFades) {
mFades = fades;
if (fades) {
post(mFadeRunnable);
} else {
removeCallbacks(mFadeRunnable);
mPaint.setAlpha(0xFF);
invalidate();
}
}
}
public int getFadeDelay() {
return mFadeDelay;
}
public void setFadeDelay(int fadeDelay) {
mFadeDelay = fadeDelay;
}
public int getFadeLength() {
return mFadeLength;
}
public void setFadeLength(int fadeLength) {
mFadeLength = fadeLength;
mFadeBy = 0xFF / (mFadeLength / FADE_FRAME_MS);
}
public int getSelectedColor() {
return mPaint.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaint.setColor(selectedColor);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
final int paddingLeft = getPaddingLeft();
final float pageWidth = (getWidth() - paddingLeft - getPaddingRight()) / (1f * count);
final float left = paddingLeft + pageWidth * (mCurrentPage + mPositionOffset);
final float right = left + pageWidth;
final float top = getPaddingTop();
final float bottom = getHeight() - getPaddingBottom();
canvas.drawRect(left, top, right, bottom, mPaint);
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager viewPager) {
if (mViewPager == viewPager) {
return;
}
if (mViewPager != null) {
//Clear us from the old pager.
mViewPager.setOnPageChangeListener(null);
}
if (viewPager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(this);
invalidate();
post(new Runnable() {
@Override public void run() {
if (mFades) {
post(mFadeRunnable);
}
}
});
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPositionOffset = positionOffset;
if (mFades) {
if (positionOffsetPixels > 0) {
removeCallbacks(mFadeRunnable);
mPaint.setAlpha(0xFF);
} else if (mScrollState != ViewPager.SCROLL_STATE_DRAGGING) {
postDelayed(mFadeRunnable, mFadeDelay);
}
}
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
mPositionOffset = 0;
invalidate();
mFadeRunnable.run();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator CREATOR = new Creator() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: app/src/main/res/anim/bili_anim.xml
================================================
================================================
FILE: app/src/main/res/anim/push_left_in.xml
================================================
================================================
FILE: app/src/main/res/anim/push_no.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_in_bottom.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_in_top.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_out_bottom.xml
================================================
================================================
FILE: app/src/main/res/anim/slide_out_top.xml
================================================
================================================
FILE: app/src/main/res/color/vpi__dark_theme.xml
================================================
================================================
FILE: app/src/main/res/color/vpi__light_theme.xml
================================================
================================================
FILE: app/src/main/res/drawable/back_btn.xml
================================================
================================================
FILE: app/src/main/res/drawable/base_action_bar_action_more_selector.xml
================================================
================================================
FILE: app/src/main/res/drawable/card_background.xml
================================================
================================================
FILE: app/src/main/res/drawable/comment_btn.xml
================================================
================================================
FILE: app/src/main/res/drawable/corner.xml
================================================
================================================
FILE: app/src/main/res/drawable/dot_focused.xml
================================================
================================================
FILE: app/src/main/res/drawable/dot_normal.xml
================================================
================================================
FILE: app/src/main/res/drawable/focus_show.xml
================================================
================================================
FILE: app/src/main/res/drawable/home_btn_bg.xml
================================================
================================================
FILE: app/src/main/res/drawable/image_corner.xml
================================================
================================================
FILE: app/src/main/res/drawable/list_selector.xml
================================================
================================================
FILE: app/src/main/res/drawable/normal_show.xml
================================================
================================================
FILE: app/src/main/res/drawable/progressbar_large.xml
================================================
================================================
FILE: app/src/main/res/drawable/selector_tabtext.xml
================================================
================================================
FILE: app/src/main/res/drawable/tab_indicator.xml
================================================
================================================
FILE: app/src/main/res/drawable/vpi__tab_indicator.xml
================================================
================================================
FILE: app/src/main/res/drawable-xhdpi/mediacontroller_btn_bg.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_video.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_video_info.xml
================================================
================================================
FILE: app/src/main/res/layout/area_item.xml
================================================
================================================
FILE: app/src/main/res/layout/back_head.xml
================================================
================================================
FILE: app/src/main/res/layout/banner.xml
================================================
================================================
FILE: app/src/main/res/layout/bili_videoview.xml
================================================
================================================
FILE: app/src/main/res/layout/bili_webview.xml
================================================
================================================
FILE: app/src/main/res/layout/bili_webview_head.xml
================================================
================================================
FILE: app/src/main/res/layout/brightness_volumn.xml
================================================
================================================
FILE: app/src/main/res/layout/card_layout.xml
================================================
================================================
FILE: app/src/main/res/layout/donghua_tab.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_donghua.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_gamecenter.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_homepage.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_main.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_online.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_online_item.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_subarea.xml
================================================
================================================
FILE: app/src/main/res/layout/fragment_videoinfo.xml
================================================
================================================
FILE: app/src/main/res/layout/game_list_item.xml
================================================
================================================
FILE: app/src/main/res/layout/homepage_item.xml
================================================
================================================
FILE: app/src/main/res/layout/item.xml
================================================
================================================
FILE: app/src/main/res/layout/items_list.xml
================================================
================================================
FILE: app/src/main/res/layout/main_head.xml
================================================
================================================
FILE: app/src/main/res/layout/mediacontroller.xml
================================================
================================================
FILE: app/src/main/res/layout/video_info_list_item.xml
================================================
================================================
FILE: app/src/main/res/layout/video_list_item.xml
================================================
================================================
FILE: app/src/main/res/layout/videoview.xml
================================================
================================================
FILE: app/src/main/res/menu/main.xml
================================================
================================================
FILE: app/src/main/res/menu/menu_main.xml
================================================
================================================
FILE: app/src/main/res/raw/comments.xml
================================================
chat.bilibili.com79533901000k-vone piece是真实存在的!!!one piece是真实存在的!!!one piece是真实存在的!!!ONE PIECE是真实存在的!!!!!!!one piece是真实存在的!!!ONEone piece是真实存在的!!!ONE PIECE 是真实存在的!!!!!!!!!!!!!!!!!!!!!!!!!!!!ONE PIECE 是真是存在的!今生无悔入海贼有生之年不愿看到海贼完结我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!我是要成为海贼王的男人!!!!one piece 是真实存在的多谢白字 辛苦了说一点都不好看的你过来我们谈谈人生艾斯!!!!这么燃却泪了的你不是一个我大海贼还能再战500年!看的好震撼!我来晚了one piece 是真的存在的one piece 是真的存在的第一?尼桑大骗子QAQ2014.10.17最后高能!!注意这不是演习!!!我大海贼还能再战5000年!最后高能!!注意这不是演习!!!最后高能!!注意这不是演习!!!最后高能!!注意这不是演习!!!最后高能!!注意这不是演习!!!最后高能!!注意这不是演习!!!最后高能!!注意这不是演习!!!我是要成为海贼王的男人!最后高能!!注意这不是演习!!!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!尼桑大骗子!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!十万也好百万也好,我们会把你们全部打飞!!!!!!我是要成为海贼王的男人!!我是要成为海贼王的男人!!我是要成为海贼王的男人!!我是要成为海贼王的男人!!我是要成为海贼王的男人!!我是要成为海贼王的男人!!2014.10.19打卡,爱海贼一生一世ONE PIECE!!!是真实存在的!!!ONE PIECE!!!是真实存在的!!!ONE PIECE!!!是真实存在的!!!2014.10.19老爹刷2014-10-19 艾斯我好想你。雷利桑!~海贼王里都是真爷们狗耳朵罗杰!狗耳朵罗杰!2014/10/20又上首页啦!不想海贼完结的是抖M么gold前方高能!!!!前方高能!!!!前方高能!!!!前方高能!!!!前方高能!!!!恭喜再上首页!我大海贼还能再战500年!D!路飞我爱你啊!草帽海贼团是最棒的!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!拉夫德鲁!我是要成为海贼王的男人!!!ONE PIECE是真实存在的!!ONE PIECE是真实存在的!!对不起,我要让他上首页!对不起,我要让他上首页!对不起,我要让他上首页!对不起,我要让他上首页!对不起,我要让他上首页!对不起,我要让他上首页!全身鸡皮疙瘩的别跑 带上我我叫 蒙奇D路飞 我是要成为海贼王的男人又被顶上来了 = -=我是要成为海贼王的 男人!!!!!!!爱死海贼王大爱路飞我来晚了老爹艾斯。。。。。老爹我是要成为海贼王的男人!ONE PIECE是真实存在的!!!!!ONE PIECE是真实存在的!!!!!ONE PIECE是真实存在的!!!!!小心脏损伤不轻一生的归宿点死了2014 10 25 打卡one piece是真实存在的!!!2014.10.27打卡我擦!!!浑身鸡皮疙瘩了------------------------罗杰长大长残了one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!one piece是真实存在的!!!!!!!连衣裙的混蛋!2014.11.1打卡弹幕又被清了前方高能 注意这不是演戏!!!前方高能 注意这不是演戏前方高能 注意这不是演戏前方高能 注意这不是演戏前方高能 注意这不是演戏感觉弹幕又清了是男人谁不看海贼王!是男人谁不看海贼王!是男人谁不看海贼王!是男人谁不看海贼王!是男人谁不看海贼王!是男人谁不看海贼王!是男人谁不看海贼王!是男人谁不看海贼王!ONE PIECE 是真实存在的!ONE PIECE 是真实存在的!日常打卡我也是大海贼啊。我是罗杰如果我听你的话,我就不是海贼了,对吧!!艾斯日常打卡2014/11/7我是哥尔·D·罗杰!2014.11.7D应该是dream或者dreamer~oyaji雷利,和我一起去颠覆世界吧话说回来,萨博的配音是鸣人吧我要去拉夫德鲁艾斯便当不服弹幕给我刷出来!海贼必须上首页!!为大海贼盖楼!前面弹幕被删了好多。。感谢遇到你!雷利 要和我一起把世界闹的天翻地覆吗? 要和我一起把世界闹的天翻地覆吗? 要和我一起把世界闹的天翻地覆吗?感谢字幕君!!!永远大海贼 永远不完结高能高能高能高能高能连衣裙笑尿哈哈哈哈哈哈哈哈顶端白字+12014 11 1011.12打卡我拒绝你的邀请。海贼一生挚爱!!我会打到你的全员DreamONE PIECE 是真实存在的燃燃燃D·路飞2014.11.15从小就想有个自己的家族..鸡皮疙瘩onepiece是真实存在的!!onepiece是真实存在的!!onepiece是真实存在的!!是啊出发吧~D绿字来到顶顶顶顶顶顶顶顶QAQ海贼666 海贼666 海贼666操。我突然哭了、、哭了弹幕绝对清了!!!!拉夫德鲁感觉这个画质的海贼看起来好有感觉one piece. ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!白字大赞ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!ONEPIECE是真实存在的!!!!!!我来晚了 11.25罗杰长残了见海进QAQ一生推看此视频,今生无怨!看此视频,今生无怨!看此视频,今生无怨!看此视频,今生无怨!看此视频,今生无怨!看此视频,今生无怨!看此视频,今生无怨!第一?好嫩!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE,是真实存在的!lala !!!燃哭我i!!!!老爹啊!!!雷利DD颜表立男神鸡皮疙瘩大爱大爱2014 11 30路飞船长我能成为你的同伴吗ONE PIECE 是真实存在的ONE PIECE是真实存在的!!!吗的,就是忍不住眼泪!让了海贼王道路宝我爱你大爱海贼老爹帅爆了看了各种爽啊。再顶海贼王就来了成为,海贼的男人大爱海贼画风!!超级有气场我是要成为海贼王的男人萨博燃烧果实ONE PIECE是真实存在的!one piece !!是真实存在的!!one piece !!是真实存在的DDDDDDone piece是真实存在的 one piece是真实存在的 one piece是真实存在的老爹的声音鹰眼帅爆2014 12 31再来回顾我的大船长!!!!索隆我宣你!!!!老爹啊啊啊啊啊啊啊啊臭红狗!!!萨博尼桑海贼王,2015,你好ONE PIECE是真实存在的!!突然发现就我自己了one piece 是真实存在的ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!ONEP POECE!!!!!!是真实存在的!!!!!DDDDDDDDDDDDDDDDDDDDDDDDDDDa1a1a1ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!ONE PIECE!!!是真实存在的!!狗耳朵罗杰路飞要成为罗杰的男人我也来依法 OnePiece是真实存在的22222222222222222222222222aaaDDDDDDDDDDDDDDDDDDDDONE PIECE,是真实存在的!ONE PIECE,是真实存在的!ONE PIECE,是真实存在的!鸣人新吧唧我是要成为海贼王的男人我是要成为海贼王的男人!!!我是要成为海贼王的男人!!!此生无悔入海贼!!长残了。。。那是鼻毛还是胡子?2015/1/6最爱。没有之一。海贼一生被清空了?燃爆了 红狗海贼王本命!!!!!D没有确定的意思 这样才是男人的浪漫啊!!!永远追求着别人看来意义不明的东西!路过。。。23333333333333要哭了!他娘要去在更海贼!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!OONE PIECE 是真实存在的!!ONONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!!ONE PIECE 是真实存在的!!!你要死了,路飞?ONEP IECE是真实存在的红发大人QAQ我的小男神出来了one piece!!是真实存在的。。。全身抖动!!!!!2015-01-10因为那可是全世界啊!因为那可是全世界啊!因为那可是全世界啊!因为那可是全世界啊!因为那可是全世界啊!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!我是要成为海贼王的男人!ONE PIECE是真实存在的!!!!!赞赞赞赞赞赞赞帅帅帅燃燃哭我是要成为海贼王的男人1!!赞飞赞赞赞那灾难OP是真实存在的!One Piece是真实存在的!k去找吧 骚年们ONE PIECE IT'S RELLY BELIVE!!!ONE PIECE IT'S RELLY BELIVE!ONE PIECE IT'S RELLY BELIEVE!ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的ONE PIECE是真实存在的重温one piece 是真实存在的!!!!!!!!!装在我大海贼我的财宝吗?想要的话就都给你了。去找吧!我把他们都放在伟大航路了!世界将会颠覆因为那可是全世界啊!因为那可是全世界啊!我会听你的话就不是海贼了!我拒绝你的邀请!我可是哥鲁·D·罗杰啊!!!!向这个世界发起挑战!!!我是要成为海贼王的男人!!!!!one piece 是真是存在的!!!DDDDDDDDDDDDDDDDD太棒了我是要成为海贼王的男人!!!!一辈子的爱要和我一起把世界闹得天翻地覆吗?海贼王的称号!从今天开始,我们就是兄弟了!That Day Is Not FarBOTHERFAMILYPNE PIECEFIGHTONE PIECE 是真实存在的QAQ真实的!!!!黄金·杰克逊号这声音太拖了,不喜ONE PIECE 是真实存在的!!!!!!!!!!!我拒绝你的邀请!!!我拒绝你的邀请!!!我拒绝你的邀请!!!我拒绝你的邀请!!!我拒绝你的邀请!!!我拒绝你的邀请!!!我拒绝你的邀请!!!海贼王路飞罗杰的帽子怎么和红发的一样顶顶顶顶顶顶顶顶顶顶!!!顶!D啊!DDDDDDDDDDDDDDDDDDDD我是要成为海贼王的男人!我是要成为海贼王的男人!即使在战斗中死了,也没什么不好!DDDDDDDDDDDDDDDDD从今天开始,我们就是兄弟了!one piece 是真实存在的!one piece 是真实存在的!!!!one piece 是真实存在的!!!!由我来把你们全部打飞!ONE PIECE!!!是真实存在的!!!!ONE PIECE!!!是真实存在的!!!!ONE PIECE!!!是真实存在的!!!!!ONE PIECE!!!是真实存在的!成为海贼王的男人!!!!!!!!!成为海贼王的男人!!!!!!成为海贼王的男人!!!!!!成为海贼王的男人!!!!!!我大海贼还能再战10000年!!!2015.2.2顶!!!出发吧!我是哥鲁·D·罗杰啊!我是哥鲁·D·罗杰啊!我是哥鲁·D·罗杰啊!我是哥鲁·D·罗杰啊!我是哥鲁·D·罗杰啊!我是哥鲁·D·罗杰啊!我是哥鲁·D·罗杰啊!我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人我是要成为海贼王的男人从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!2015.2.2哥儿 D 罗杰莫名泪目ONE PIECE是真实存在的!!!!!ONE PIECE是真实存在的!!!!!ONE PIECE是真实存在的!!!!!艾斯永远的大本命 海贼最爱的动漫艾斯永远的大本命 海贼永远的最爱弹幕被清了Q_Q艾斯 尼桑 Q_QQ_QQ_Q我大海贼!一天一补!世界不末日,海贼不完结。d 海贼 是自由 DA 兄弟 伙伴老爹 就是家 啊弹幕 走起要 收苍2015.2.14好想哭,卧槽!!!要和我一起把世界闹的天翻地覆吗?我的财宝吗?想要的话就都给你了。去找吧!我把他们都放在伟大航路了!我是要成为海贼王的男人!!ONE PIECE!!!是真实存在的!!!!!!!!!ONE PIECE!!!是真实存在的!!!!!!!!!ONE PIECE!!!是真实存在的!!!!!!!!!2333333大海贼 ~~我是海贼王的丈夫~~!!233333333333大草帽@罗我是要成为海贼王的男人又顶上来了,又顶上来了 此生无悔入海贼我是要成为海贼王的男人!!!!zhy自由再来一次好了one picec,是真实存在的onepone picec,是真实存在的one picec,是真实存在的one picec,是真实存在的one picec,是真实存在的!one picec,是真实存在的!one picec,是真实存在的!one picec,是真实存在的!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!从今天开始,我们就是兄弟了!one piece是真实存在的漫画的这一段更更更更更加燃ONE PIECE 是真实存在的真是条不错的船!是我偷来的我的房子没了,所以我住在这里。知道了,你的名字?雷利我叫罗杰我们在此相遇是命运啊!命运?你想和我一起把世界颠覆吗?为什么我要这么做?因为那可是世界啊!启航了,雷利!还要我说多少次成为我的左右手吧,罗杰!如果我答应了你,我就不是海贼了吧无论你邀请我多少次金狮子你的邀请……我拒绝!我会把你们全员打飞的!两年后,罗杰海贼团征服了大航海线哥尔多.罗杰成为了海贼王你要死了,罗杰?嗯,我没有多少时间了你知道世界政府怎么称呼我吗?黄金罗杰我是哥尔.D.罗杰!不是被捕罗杰是自首的因为我们的冒险已经到了尽头我的财宝吗?如果你想要,就是你的找去吧!我把世上的全部都留在那里了!我不会死的,伙伴雷利先生,我真的很惊讶在东海,有个孩子和船长说了同样的话船长的那句誓言我是蒙奇.D.路飞我是要成为海贼王的男人!海贼王,我当定了正是如此,就算战死也没什么大不了的!就像罗杰的意志被传承了总有一天会有人背负这数百年的历史向世界发起挑战战国你们世界政府一直在害怕一场将世界颠覆的……巨大的战争!当那份财宝被人找到世界将被颠覆!终有一天会被人找到的那一天必会到来!艾斯!路飞!我们一定会出海离开这个国家,获得自由!从今往后,我们就是……兄弟了!索隆乌索普山治娜美乔巴罗宾弗兰奇布鲁克当我还是一个小鬼的时候我就想要一个家族!One piece……是真实存在的!无论如何男子汉必须站起来战斗!管你是十万,还是一百万人我们会把你们全部打飞!进入二档是旅行的话你想去哪?我大海贼还能再战五百年海贼王的时代海贼王我当定了!处女币 走你·~~~~看到大海贼就滚进来了看到大海贼就滚进来了看到大海贼就滚进来了尼酱家one piece 是真实存在的one piece 是真实存在的one piece 是真实存在的one piece 是真实存在的被顶上来了..金狮子被路飞打败纯粹开挂啊啊哥尔·D·罗杰 哥尔·D·罗杰 哥尔·D·罗杰 哥尔·D·罗杰 哥尔·D·罗杰 哥尔·D·罗杰 哥尔·D·罗杰 哥尔·D·罗杰 正是这个视频让我接触了海贼!鸣人都成了火影,路飞还会远吗!!!我是要成为海贼王的男人!!!!!!!11燃哭了家人艾斯duang duang duang我是要成为海贼王的男人!!!!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!为了这个决定就算是在战斗中死了,也没有什么不好!这辈子能遇见海贼真是太好了QWQBGM 一响就想哭啊红发 帅哭我嗷嗷嗷嗷 老爹泪目了海贼王~~~我当定了~~~~~泪目了 嗷嗷嗷嗷嗷燃却哭2015.3.5 兄弟这是最让我感动的一幕这个BGM不是Two steps from hell的么卧槽 这句打倒你们全员戳中燃点伙伴!!!巨大战争由路飞他们打响感谢地下的白字菌15.3.9ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!去吧处女币路飞我男神路飞我要嫁给你爱爱爱爱爱童年萨博的声优和鸣人的是同一个为了D为了D!!!!!!!!!!老爹超越D了one plece 是存在的气枪````````````````````````燃·······One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的One piece 是真实存在的艾斯ONE piece 是真是存在的!ONE piece 是真是存在的!高能非战斗人员撤离!!!少主是将成为海贼王的男人!黑胡子是将成为海贼王的男人!ONE PIECE 是真实存在的这里应该翻译成:家人泪目前方高能!!!前方高能!前方!前方高能!脏赞鸡皮疙瘩鸡皮疙瘩哇哈哈哈海贼是我每周的期待我是要成为海贼王的男人太棒了3.27此生无悔入海贼!追梦路上永相随!!此生无悔入海贼,追梦路上永相随!One Piece是真实存在的!我大海贼还能再战5000年!!!白胡子!!!!!!ONEPIECE是真是存在的!!!!!!!高能!!!!!!!!!!!欧亚及。。。@罗萨博!!!!!从今天开始 我们就是兄弟了!!!从今天开始 我们就是兄弟了!!!从今天开始 我们就是兄弟了!!!从今天开始 我们就是兄弟了!!!从今天开始 我们就是兄弟了!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!看几次燃几次王者的声音啊!!!!二次元。!~二次元。!~二次元。!~二次元。!~二次元。!~我是要成为海贼王的男人我的处女币就给你了!没有一起看得小伙伴?大爱海贼!我是要成为海贼王的男人!老爹霸气one picec,是真实存在的罗杰命运天翻地覆全世界one piece 是真实存在的!!帽子是罗杰给红发 红发给路飞的块顶起来啊one piece是真实存在的 d我是要成为海贼王的男人!!!! 我是要成为海贼王的男人!!!! ONE PIECE是真实存在的!!!ONE PIECE是真实存在的!!!处女弹幕和处女币都献给你了!!!!好想哭啊!!!!!2015.4.8我是要成为海贼王的男人尼桑 大骗子 快回来ONE PIECE 是真正存在的会员第一发弹幕就交给你了!!!处女币已交泪目。默默的掏出洛阳铲我大海贼卧槽 然哭~~~~~~~~~~~~one piece是真实存在的!!!!one piece是真实存在的!!!!忍不住眼泪了..命运的邂逅。老爹既然你们都喜欢尼桑,那雷利大爷让我来。老爹。。 23333333333333333333老爹。。想要我的财宝吗顶我大海贼one piece!!!!是真实存在的!大家好,我是山治黄~~~kai.sou.kou.ao.ni.ou.lei.wa.na.lu.ONE PIECE佐罗我喜欢你!!海贼ONE PIECE是真实纯在的!!!キラメキONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!ONE PIECE是真实纯在的!!!DDDDDDDDDDDDDD!吾大海贼!吾大海贼!啊啊啊啊啊啊啊 啊因为那帽子是罗杰给红发的看见路飞的草帽我就进来了我是要成为海贼王的男人ONE PICE是真实存在的!!!!!其实罗杰只是想骗船。。。。本名雷叔D之意志的继承者D之意志的继承者不自然的全身打颤,燃起来了海贼王在这,谁要做我的男人?海贼王在这,谁要做我的男人?海贼王在这,谁要做我的男人?ONE PIECE是真实纯在的!!!泪流满面的你不是一个人果然海贼最燃了白胡子新的时代开始了是要成为海贼王的男人艾斯白胡子的死代表了一个时代的结束新的一代来了浑身的鸡皮疙瘩萨博白胡子家族雷利熊我是要成为海贼王的男人!one piece 是真是存在的!!!全程高能啊!新时代开启!2015.4.15金狮子D的意识D家族就是这么厉害看着要哭了我大海贼海贼好燃白胡子老爹!!!!!!!!!!!!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!大海賊王永遠不會完結ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!ONE PIECE 是真实存在的!!!痛哭One piece是真实存在的!!!2015.4.15我是哥爾·羅傑!!ONE PIECE是真实存在的!!!!!尼桑!!!!!!!!!!!老爹!!!!!!!我大海贼还可以再战100000000000000000年海贼王的弹幕我来补海贼王我哭了真的是可以看到鸡皮疙瘩都起来的!!!!!!!!!!!可以大海贼尅呀再喊100年!大家好 我是海贼王我是要成为海贼王的男人!onepiece是真是存在的!!!各种高能帅哭了OP!!!!!!!路飞是要要成为海贼王的男人!罗杰的男人!路飞的时代开始了!纯在的!!!!! one piece 是真实存在的黄金罗杰!!!!!!!海贼王!!!我大海贼!!!来了!!高能!!这个真高能又顶上来了。。。野生字幕君.....第一?家族顶上去这群大神- -把世界毁灭吧我是要成为海贼王的男人!!!全身发麻乌索普大神大爱海贼!!!这可是我大海贼我大海贼兄弟!家人ONE PIECE是真实存在的!!!家人老爹苦苦苦了壮哉我大凤凰我是要成为看完海贼王的男人啊aaaaaaaaaaaaaaa燃哭我大海贼还能再战500年那可是全世界啊我是哥尔D罗杰啊我是要成为海贼王的男人为了这个决定就算在战斗中战死了 也没什么从今天开始 我们就是:ONE PIECE 是真实存在的!!!!海贼王的团队!!我大海贼还能再战五百年!!!我大海贼还能再战五百年!!!我大海贼还能再战五百年!!!我大海贼还能再战五百年!!!我大海贼还能再战五百年!!!我大海贼还能再战五百年!!!这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ这辈子能遇到ONE PIECE真是太好了!QAQ路飞!D之意志的传承者!!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!ASL之羁绊永不解体!兄弟情义永不解散!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!从今天开始,我们就是兄弟了!!要把你们全部打飞!!命运 哎全世界 啊 啊啊啊啊 啊啊 啊上 啊 处女 币 海贼 自由 肉村赛高!!!!!!哦压机罗杰的声优去世了T T看得我浑身发颤……索隆绿ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!ONE PIECE是真的存在的!!!这一幕帅爆了有没有,面对这么多的海贼船还淡定拒绝泪目看得我哭的稀里哇啦的啊上去吧定罗宾路飞生日快乐D啊0505路飞生日快乐!我大海贼还能再战五百年!!!!0505路飞生日快乐路飞是要成为海贼王的男人!!!!!路飞是要成为海贼王的男人!!!!这是海贼的时代!!是路飞的时代!!!!!老爹!!!!!!!萨博!!!!!!前方高能!!!ONE PIECE是真实存在的!!!第一次看海贼觉得这句话帅到爆表闹吧!!!大家一起翻天吧!!喂!多精致的一艘船喂!多精致的一艘船真是条不错的船这是条偷来的船我的家被烧了 所以就住这了原来如此 你的名字是?雷利我是罗杰!我们在这相遇是命运啊 雷利!命运?要一起和我把世界闹的天翻地覆吗?为什么我也要跟着做这种事?因为那可是全世界哦!好了 出发咯!雷利!都跟你说多少遍了啊成为我的左右手吧!罗杰!如果我会听你的话 我就不是海贼了 对吧?无论你怎么对我施压金狮子!我拒绝你的邀请!我会打倒你们全员的!两年后罗杰海贼团征服了大航海线黄金罗杰得到了海贼王称号你快要死了?罗杰?是啊 我快没时间了你知道政府的那些人都叫我什么吗?黄金罗杰我是 哥尔·D·罗杰 啊没有被抓住罗杰他是去自首了我们的旅途已经到尽头了我的财宝?如果想要的话都给你了!去找吧!我把这世界的全部都放在那了!我是不会死的 伙伴雷利先生 我当时真的吓了一跳!东海有个小鬼竟然和罗杰船长说了同样的话船长的那句誓言我是蒙奇D路飞!我是要成为海贼王的男人!海贼王我当定了为了这个决定就算是在战斗中死了也没什么不好的!就像有继承罗杰意志的人们一样终有一日会有人背负那数百年份的历史向这个世界发起挑战战国你们世界政府一直在害怕那场席卷全世界的巨大战争终有一日会被谁找到的当那财宝被谁发现的时候全世界将会颠覆终有一日会被谁找到的那一天一定会到来艾斯!路飞!我们总有一天会出海的!离开这个城市 获得自由!从今天开始 我们就是兄弟!索罗索罗乌索普香吉士娜米索罗乌索普香吉士娜米乔巴罗宾弗兰克布鲁克在我还是小鬼的时候我就想要一个家族!ONE PIECE是真实的存在男子汉无论何时都要站起来奋斗!十万也好 百万也好我们会把你们全部打飞!二档旅行的话你想要去哪里?
================================================
FILE: app/src/main/res/values/attrs.xml
================================================
================================================
FILE: app/src/main/res/values/colors.xml
================================================
#ffffff#FF000000#f2f2f2#75000000#23000000#00000000#ffefc1d9#99000000#f4f4f4#ff0000ff#ff00ff00#ffff0000#ff0078f0#ff7d7d7d#ffc3ddea#ffffcc00#ff274462#808080ff#445CACEE#db77ab#efc1d9#fcf4f8
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
16dp16dp16.0dip15.0dip18.0dip14.0dip13.0dip30.0dip49.0dip40.0dip48dp32dp2dp0dp
================================================
FILE: app/src/main/res/values/integers.xml
================================================
2
================================================
FILE: app/src/main/res/values/strings.xml
================================================
哔哩哔哩动画1.0本地视频在线视频初始化播放器...载入中,请稍后...文件操作重命名重命名失败文件已存在删除确定删除 (%s) ?正在缓冲...VPlayer codecCannot play videoSorry, this video is not valid for streaming to
this device.对不起,这个视频不能播放。OKPlay/Pause锁定100%全屏拉伸裁剪屏幕已锁定屏幕锁定已解除缓冲: %.2f%%对不起,这个视频不能播放。SD卡无法读取截图存放在 %s.截图失败正在退出…settings
================================================
FILE: app/src/main/res/values/styles.xml
================================================
================================================
FILE: app/src/main/res/values/vpi__attrs.xml
================================================
================================================
FILE: app/src/main/res/values/vpi__colors.xml
================================================
#ff000000#fff3f3f3@color/vpi__background_holo_light@color/vpi__background_holo_dark#ff4c4c4c#ffb2b2b2@color/vpi__bright_foreground_holo_light@color/vpi__bright_foreground_holo_dark
================================================
FILE: app/src/main/res/values/vpi__defaults.xml
================================================
true#FFFFFFFF#0000000003dpfalse#FFDDDDDD1dp12dp4dp1dp#FF33B5E5#FFBBBBBBtrue4dp#FF33B5E52dp24dp20dp7dp0#FFFFFFFFtrue#BBFFFFFF15dp5dp7dptrue300400#FF33B5E5
================================================
FILE: app/src/main/res/values/vpi__styles.xml
================================================
================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
64dp
================================================
FILE: build/intermediates/dex-cache/cache.xml
================================================
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: local.properties
================================================
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\as\\sdk-install
================================================
FILE: settings.gradle
================================================
include ':app',':vitamio',':DanmakuFlameMaster'