diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e76c77c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..f13fa33 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..2e25463 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f797995 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..9b770a6 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..72fee8f --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,45 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + buildToolsVersion "29.0.2" + defaultConfig { + applicationId "com.example.wgjrouter" + minSdkVersion 19 + targetSdkVersion 28 + versionCode 15 + versionName "1.2.2" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support:design:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:support-vector-drawable:28.0.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.android.support:support-v4:28.0.0' + implementation files('libs\\jcifs-1.3.19.jar') + implementation 'com.github.open-android:Gson:2.8' + implementation("com.squareup.okhttp3:okhttp:4.2.1") + implementation 'com.squareup.picasso:picasso:2.71828' + implementation project(':vitamio') + implementation files('libs\\commons-net-3.6.jar') + implementation 'org.greenrobot:eventbus:3.1.1' + implementation files('libs\\pgyer_sdk_3.0.7.jar') + implementation 'com.github.chrisbanes:PhotoView:2.0.0' + implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.19' + implementation 'org.litepal.android:java:3.0.0' + implementation files('libs\\jsoup-1.12.1.jar') + implementation 'com.ddz.materialdesign:FloatingActionButton:1.0.4' +} diff --git a/app/libs/commons-net-3.6.jar b/app/libs/commons-net-3.6.jar new file mode 100644 index 0000000..4537623 Binary files /dev/null and b/app/libs/commons-net-3.6.jar differ diff --git a/app/libs/jcifs-1.3.19.jar b/app/libs/jcifs-1.3.19.jar new file mode 100644 index 0000000..efbd81e Binary files /dev/null and b/app/libs/jcifs-1.3.19.jar differ diff --git a/app/libs/jsoup-1.12.1.jar b/app/libs/jsoup-1.12.1.jar new file mode 100644 index 0000000..4f84d6d Binary files /dev/null and b/app/libs/jsoup-1.12.1.jar differ diff --git a/app/libs/pgyer_sdk_3.0.7.jar b/app/libs/pgyer_sdk_3.0.7.jar new file mode 100644 index 0000000..8ac16fb Binary files /dev/null and b/app/libs/pgyer_sdk_3.0.7.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..6e7ffa9 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/example/wgjrouter/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/wgjrouter/ExampleInstrumentedTest.java new file mode 100644 index 0000000..2e117a6 --- /dev/null +++ b/app/src/androidTest/java/com/example/wgjrouter/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.wgjrouter; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.example.wgjrouter", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f819136 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/litepal.xml b/app/src/main/assets/litepal.xml new file mode 100644 index 0000000..5acda02 --- /dev/null +++ b/app/src/main/assets/litepal.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/src/main/assets/livevideolist.txt b/app/src/main/assets/livevideolist.txt new file mode 100644 index 0000000..dc885de --- /dev/null +++ b/app/src/main/assets/livevideolist.txt @@ -0,0 +1,1033 @@ +CCTV1,http://39.135.36.151:18890/000000001000/1000000001000021973/1.m3u8?channel-id=ystenlive&Contentid=1000000001000021973&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000021973&owchid=ystenlive&owsid=1106497909461769539&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRLaQJeR5usCQMKdpIDCZAoYPt4bOuuiUwGxs8%2fKxpb7Wa3xqB26AcGEvjhx3JJlw6 +CCTV2,http://39.135.36.150:18890/000000001000/1000000001000012442/1.m3u8?channel-id=ystenlive&Contentid=1000000001000012442&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000012442&owchid=ystenlive&owsid=1106497909461775063&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRknGE%2fO0VC9Co37x%2f7gMjaWYjatUfTQlAa15Ksg%2fXe8sQo%2fi5btdpzeV%2b1v4UwuHf +CCTV3,http://39.135.36.141:18890/000000001000/1000000001000011218/1.m3u8?channel-id=ystenlive&Contentid=1000000001000011218&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000011218&owchid=ystenlive&owsid=1106497909461779572&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRrAyJU4rR1Dadw9ISEYm5oBbA9lSzNfT0W7kMLAWHUBTbBAjpiIN0Pdi%2fTRm3zPoh +CCTV4,http://39.135.36.150:18890/000000001000/1000000002000031664/1.m3u8?channel-id=ystenlive&Contentid=1000000002000031664&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000031664&owchid=ystenlive&owsid=1106497909461056460&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhSaNRr4LzI3YsXQPQcGzS6VSIZXSs858JtCAdvl%2fg%2f2u5lawXOBSX%2fqESSB5FmTXS +CCTV5,http://39.135.36.146:18890/000000001000/1000000001000004794/1.m3u8?channel-id=ystenlive&Contentid=1000000001000004794&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000004794&owchid=ystenlive&owsid=1106497909461092492&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRFIaTOfcD93c7ACh3puyaR1v%2bioI39cfseenlxp5u9UfADU6BCDl7v7CTGKuGZw1d +CCTV5+,http://39.135.36.152:18890/000000001000/1000000001000020505/1.m3u8?channel-id=ystenlive&Contentid=1000000001000020505&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000020505&owchid=ystenlive&owsid=1106497909461103025&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRkrZ1YVus93dDbxNB4SF1DDcF4ZpIL8iGHt%2bMdt2ZAOlknlq9lyy%2fQZJVqiFUxfle +CCTV6,http://39.135.36.140:18890/000000001000/1000000001000016466/1.m3u8?channel-id=ystenlive&Contentid=1000000001000016466&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000016466&owchid=ystenlive&owsid=1106497909461115566&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRPL4aTeGJNlZwIkZROfGAKEC3iG4uOUkYNIdPRliCqBi8AjSQtKTBHB8b3LPXJcIA +CCTV7,http://39.135.36.152:18890/000000001000/7050628689018054317/1.m3u8?channel-id=ystenlive&Contentid=7050628689018054317&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=7050628689018054317&owchid=ystenlive&owsid=1106497909461123525&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5v8WYfJSLSoSDQSshIAsx77pE15UEXEdMCmKIrL5%2f3xV22iBl6KMm%2bLcZrmbA5H1KmAD8EY%2bWAeRUs2LJ9Vxxk +CCTV8,http://39.135.36.154:18890/000000001000/1000000001000003736/1.m3u8?channel-id=ystenlive&Contentid=1000000001000003736&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000003736&owchid=ystenlive&owsid=1106497909461132718&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRKhIjYL3aRNrIf2qoTcK90Bd0oe1gvWxxvd9Qs9pkD5eKCeYPeHs2GppHtnd1klhd +CCTV9,http://39.135.36.145:18890/000000001000/1000000001000014583/1.m3u8?channel-id=ystenlive&Contentid=1000000001000014583&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000014583&owchid=ystenlive&owsid=1106497909461138654&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRh3XYVWmjehcJ6eeMnvhxAUHggQtCK8Xdm86HMC53JU75N56tG8kTzA%2fMocL0w%2bEi +CCTV10,http://39.135.36.151:18890/000000001000/7019587760656900133/1.m3u8?channel-id=ystenlive&Contentid=7019587760656900133&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=7019587760656900133&owchid=ystenlive&owsid=1106497909461152716&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5DtJGdM%2bq9fDiivHNjKl%2bK%2b9%2fvTG5xUEzd4ADPtXjiSOOAPl07bvHVEc1KInbp3p%2fXrmwsjTHZ%2fLcoxEWqnCxI +CCTV11,http://39.135.36.157:18890/000000001000/1000000002000019789/1.m3u8?channel-id=ystenlive&Contentid=1000000002000019789&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000019789&owchid=ystenlive&owsid=1106497909461158507&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhUELVtb8TDQzMSm5TScAJJF9JU4YcW5z4YHYDU6y7yn5EMhEqmI%2fAHiE6j4Y95QQ6 +CCTV12,http://39.135.36.153:18890/000000001000/5325631075193490169/1.m3u8?channel-id=ystenlive&Contentid=5325631075193490169&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=5325631075193490169&owchid=ystenlive&owsid=1106497909461165978&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7Q36zc4fu7NwQ%2fn1v2mTHqagOL8gLhzmY66HLCxgy24bGH5Xn1D6yEQdwViWmtBz15WRKuKxWsf0XH20JE0dby +CCTV13,http://39.135.36.142:18890/000000001000/1000000002000021303/1.m3u8?channel-id=ystenlive&Contentid=1000000002000021303&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000021303&owchid=ystenlive&owsid=1106497909461172796&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjht3HVAbnHsmZNUh9hfpXto6CyOW1rkA%2biXZhxwyg0QWyFIN7oKbswdBdf7iWy8vlE +CCTV14少儿,http://39.135.36.147:18890/000000001000/8203666801302077036/1.m3u8?channel-id=ystenlive&Contentid=8203666801302077036&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=8203666801302077036&owchid=ystenlive&owsid=1106497909461179285&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5OdsPl7aB2c%2fh9IG5fEu5Y1yWuhr6PsL8ovQK5JmdmvjbSpXjguwCa8emDxg5lQPKN6B6go0yKDtys3NmnOM6U +CCTV15音乐,http://39.135.36.158:18890/000000001000/1000000002000008163/1.m3u8?channel-id=ystenlive&Contentid=1000000002000008163&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000008163&owchid=ystenlive&owsid=1106497909461186580&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhY20qRt7%2f617UUdZqFKeX8uE3lV%2bUYqhdkQW8TTtgMeMYnBWivLOAtJKqm6UM8Epy +CCTV17,http://39.135.36.140:18890/000000001000/1000000005000056836/1.m3u8?channel-id=ystenlive&Contentid=1000000005000056836&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000005000056836&owchid=ystenlive&owsid=1106497909461196027&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6skxOPttMtBQzbEMb71jMrM9bNA5sjuldmGASVEj1FB1TOzqCEWAK6w%2fJbtYz8kEYu99sUSfTSd48Av%2fzOzjC1 +电影-李连杰,https://js.hls.huya.com/huyalive/94525224-2460686093-10568566295157014528-2789253848-10057-A-0-1_1200.m3u8 +电影-成龙,https://aldirect.hls.huya.com/huyalive/94525224-2460685722-10568564701724147712-2789253838-10057-A-0-1_1200.m3u8 +电影-金庸电影,https://aldirect.hls.huya.com/huyalive/29359996-2689645314-11551938661469650944-2847687586-10057-A-0-1_1200.m3u8 +电影-黄渤,https://aldirect.hls.huya.com/huyalive/30765679-2554414680-10971127511022305280-3048991634-10057-A-0-1_1200.m3u8 +电影-吴京,https://aldirect.hls.huya.com/huyalive/30765679-2554414705-10971127618396487680-3048991636-10057-A-0-1_1200.m3u8 +电影-周润发,https://aldirect.hls.huya.com/huyalive/94525224-2460685774-10568564925062447104-2789253840-10057-A-0-1_1200.m3u8 +电影-刘德华,https://aldirect.hls.huya.com/huyalive/94525224-2467341872-10597152648291418112-2789274550-10057-A-0-1_1200.m3u8 +电影-徐峥,https://aldirect.hls.huya.com/huyalive/30765679-2689675828-11552069718101721088-3048991626-10057-A-0-1_1200.m3u8 +电影-甄子丹,https://aldirect.hls.huya.com/huyalive/29169025-2686219938-11537226783573147648-2847699096-10057-A-1524024759-1_1200.m3u8 +电影-徐克,https://aldirect.hls.huya.com/huyalive/29106097-2689447148-11551087544980471808-2789253872-10057-A-1525420294-1_1200.m3u8 +电影-林正英,https://tx.hls.huya.com/huyalive/94525224-2460686034-10568566041753944064-2789274542-10057-A-0-1_1200.m3u8 +电影-林正英2,https://aldirect.hls.huya.com/huyalive/29359996-2689615538-11551810774523445248-2847687642-10057-A-1525496014-1_1200.m3u8 +电影-超级英雄,https://aldirect.hls.huya.com/huyalive/30765679-2504742278-10757786168918540288-3049003128-10057-A-0-1_1200.m3u8 +电影-女神系列2,https://aldirect.hls.huya.com/huyalive/94525224-2472147404-10617792251071299584-2777026638-10057-A-0-1_1200.m3u8 +电影-五福星系列,https://aldirect.hls.huya.com/huyalive/29169025-2686220040-11537227221659811840-2713685416-10057-A-1524041498-1_1200.m3u8 +电影-红色经典,https://aldirect.hls.huya.com/huyalive/30765679-2533224718-10880117317228822528-3049003134-10057-A-0-1_1200.m3u8 +电影-顶级科幻,https://aldirect.hls.huya.com/huyalive/28466698-2689656864-11551988268341919744-2847699194-10057-A-0-1_1200.m3u8 +电影-惊悚大片,https://aldirect.hls.huya.com/huyalive/29106097-2689447600-11551089486305689600-2789274568-10057-A-1525420695-1_1200.m3u8 +电影-灾难,https://aldirect.hls.huya.com/huyalive/29106097-2689453724-11551115788685410304-2847687506-10057-A-1525422901-1_1200.m3u8 +电影-迪士尼,https://aldirect.hls.huya.com/huyalive/29106097-2689406818-11550914328949424128-2789274560-10057-A-1525417691-1_1200.m3u8 +电影-搞笑港片,https://aldirect.hls.huya.com/huyalive/30765679-2480413542-10653295043445522432-3048959596-10057-A-0-1_1200.m3u8 +电影-喜剧,https://aldirect.hls.huya.com/huyalive/30765679-2554414567-10971127025691000832-3048991638-10057-A-0-1_1200.m3u8 +电影-生化危机,https://aldirect.hls.huya.com/huyalive/28466698-2689654156-11551976637570482176-2847699186-10057-A-0-1_1200.m3u8 +电影-速度与激情,https://aldirect.hls.huya.com/huyalive/29169025-2686219962-11537226886652362752-2710080226-10057-A-0-1_1200.m3u8 +电影-死神来了,https://txdirect.hls.huya.com/huyalive/30765679-2484192708-10669526437821677568-3049003172-10057-A-0-1_1200.m3u8 +电影-重案六组,https://aldirect.hls.huya.com/huyalive/30765679-2523416621-10837991861377826816-2777027388-10057-A-0-1_1200.m3u8 +虎牙电影-周星驰,https://tx.hls.huya.com/huyalive/94525224-2460685313-10568562945082523648-2789274524-10057-A-0-1_1200.m3u8 +虎牙电影-林正英,https://tx.hls.huya.com/huyalive/94525224-2460686034-10568566041753944064-2789274542-10057-A-0-1_1200.m3u8 +虎牙电影-李连杰,https://js.hls.huya.com/huyalive/94525224-2460686093-10568566295157014528-2789253848-10057-A-0-1_1200.m3u8 +虎牙电影-成龙,https://aldirect.hls.huya.com/huyalive/94525224-2460685722-10568564701724147712-2789253838-10057-A-0-1_1200.m3u8 +虎牙电影-超级英雄,https://aldirect.hls.huya.com/huyalive/30765679-2504742278-10757786168918540288-3049003128-10057-A-0-1_1200.m3u8 +虎牙电影-女神系列2,https://aldirect.hls.huya.com/huyalive/94525224-2472147404-10617792251071299584-2777026638-10057-A-0-1_1200.m3u8 +虎牙电影-吴京,https://aldirect.hls.huya.com/huyalive/30765679-2554414705-10971127618396487680-3048991636-10057-A-0-1_1200.m3u8 +虎牙电影-周润发,https://aldirect.hls.huya.com/huyalive/94525224-2460685774-10568564925062447104-2789253840-10057-A-0-1_1200.m3u8 +虎牙电影-五福星系列,https://aldirect.hls.huya.com/huyalive/29169025-2686220040-11537227221659811840-2713685416-10057-A-1524041498-1_1200.m3u8 +虎牙电影-红色经典,https://aldirect.hls.huya.com/huyalive/30765679-2533224718-10880117317228822528-3049003134-10057-A-0-1_1200.m3u8 +虎牙电影-黑帮大片,https://js.hls.huya.com/huyalive/30765679-2523417522-10837995731143360512-2777068634-10057-A-0-1_1200.m3u8 +虎牙电影-刘德华,https://aldirect.hls.huya.com/huyalive/94525224-2467341872-10597152648291418112-2789274550-10057-A-0-1_1200.m3u8 +虎牙电影-顶级科幻,https://aldirect.hls.huya.com/huyalive/28466698-2689656864-11551988268341919744-2847699194-10057-A-0-1_1200.m3u8 +虎牙电影-速度与激情,https://aldirect.hls.huya.com/huyalive/29169025-2686219962-11537226886652362752-2710080226-10057-A-0-1_1200.m3u8 +虎牙电影-好莱坞,https://aldirect.hls.huya.com/huyalive/30765679-2484192572-10669525853706125312-2847687498-10057-A-1521100607-1_1200.m3u8 +虎牙电影-惊悚大片,https://aldirect.hls.huya.com/huyalive/29106097-2689447600-11551089486305689600-2789274568-10057-A-1525420695-1_1200.m3u8 +虎牙电影-搞笑港片,https://aldirect.hls.huya.com/huyalive/30765679-2480413542-10653295043445522432-3048959596-10057-A-0-1_1200.m3u8 +虎牙电影-变形金刚,https://ws4.streamhls.huya.com/huyalive/29106097-2689448236-11551092217904889856-2789274572-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-金庸电影,https://aldirect.hls.huya.com/huyalive/29359996-2689645314-11551938661469650944-2847687586-10057-A-0-1_1200.m3u8 +虎牙电影-徐峥,https://aldirect.hls.huya.com/huyalive/30765679-2689675828-11552069718101721088-3048991626-10057-A-0-1_1200.m3u8 +虎牙电影-生化危机,https://aldirect.hls.huya.com/huyalive/28466698-2689654156-11551976637570482176-2847699186-10057-A-0-1_1200.m3u8 +虎牙电影-战争片,https://tx.hls.huya.com/huyalive/28466698-2689659358-11551998979990355968-2789274580-10057-A-0-1_1200.m3u8 +虎牙电影-黄晓明,https://ws4.streamhls.huya.com/huyalive/30765679-2484192728-10669526523721023488-3048991650-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-重案六组,https://aldirect.hls.huya.com/huyalive/30765679-2523416621-10837991861377826816-2777027388-10057-A-0-1_1200.m3u8 +虎牙电影-科幻启示录,https://aldirect.hls.huya.com/huyalive/30765679-2499070088-10733424298371842048-2789274548-10057-A-1521102596-1_1200.m3u8 +虎牙电影-经典大片,https://ws4.streamhls.huya.com/huyalive/29106097-2689279104-11550365801496182784-2777026902-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-喜剧电影,https://ws4.streamhls.huya.com/huyalive/30765679-2689675904-11552070044519235584-3049003156-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-洪金宝,https://tx.hls.huya.com/huyalive/29106097-2689406282-11550912026846953472-2789274558-10057-A-0-1_1200.m3u8 +虎牙电影-港片女神,https://ws4.streamhls.huya.com/huyalive/30765679-2484192476-10669525441389264896-2789274564-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-喜剧,https://aldirect.hls.huya.com/huyalive/30765679-2554414567-10971127025691000832-3048991638-10057-A-0-1_1200.m3u8 +虎牙电影-甄子丹,https://aldirect.hls.huya.com/huyalive/29169025-2686219938-11537226783573147648-2847699096-10057-A-1524024759-1_1200.m3u8 +虎牙电影-死神来了,https://txdirect.hls.huya.com/huyalive/30765679-2484192708-10669526437821677568-3049003172-10057-A-0-1_1200.m3u8 +虎牙电影-迪士尼,https://aldirect.hls.huya.com/huyalive/29106097-2689406818-11550914328949424128-2789274560-10057-A-1525417691-1_1200.m3u8 +虎牙电影-徐克,https://aldirect.hls.huya.com/huyalive/29106097-2689447148-11551087544980471808-2789253872-10057-A-1525420294-1_1200.m3u8 +虎牙电影-灾难,https://aldirect.hls.huya.com/huyalive/29106097-2689453724-11551115788685410304-2847687506-10057-A-1525422901-1_1200.m3u8 +虎牙电影-电锯惊魂,https://al.hls.huya.com/huyalive/29106097-2689451202-11551104956777889792-2789274590-10057-A-0-1_1200.m3u8 +虎牙电影-黑帮斗争,https://ws4.streamhls.huya.com/huyalive/30765679-2480288304-10652757150331305984-2789274538-10057-A-1511757260-1_1200/playlist.m3u8 +虎牙电影-开心鬼,https://aldirect.hls.huya.com/huyalive/29169025-2686221566-11537233775779905536-2789253842-10057-A-1523933708-1_1200.m3u8 +虎牙电影-金庸电影,https://aldirect.hls.huya.com/huyalive/29359996-2689645314-11551938661469650944-2847687586-10057-A-0-1_1200.m3u8 +虎牙电影-女神系列3,https://aldirect.hls.huya.com/huyalive/28466698-2689661530-11552008308659322880-3049003102-10057-A-0-1_1200.m3u8 +虎牙电影-林正英2,https://aldirect.hls.huya.com/huyalive/29359996-2689615538-11551810774523445248-2847687642-10057-A-1525496014-1_1200.m3u8 +虎牙电影-黄渤,https://aldirect.hls.huya.com/huyalive/30765679-2554414680-10971127511022305280-3048991634-10057-A-0-1_1200.m3u8 +虎牙电影-泰国鬼片,https://aldirect.hls.huya.com/huyalive/29169025-2686220062-11537227316149092352-2777037828-10057-A-1524041857-1_1200.m3u8 +虎牙电影-好莱坞大片,https://aldirect.hls.huya.com/huyalive/30765679-2672001664-11476159761737580544-3048991600-10057-A-0-1_1200.m3u8 +虎牙电影-刘德华,https://aldirect.hls.huya.com/huyalive/94525224-2467341872-10597152648291418112-2789274550-10057-A-0-1_1200.m3u8 +虎牙电影-金庸电影,https://aldirect.hls.huya.com/huyalive/29359996-2689645314-11551938661469650944-2847687586-10057-A-0-1_1200.m3u8 +虎牙电影-徐峥电影,http://tx.hls.huya.com/huyalive/30765679-2689675828-11552069718101721088-3048991626-10057-A-0-1.m3u8 +虎牙电影-林正英,http://aldirect.hls.huya.com/huyalive/94525224-2460686034-10568566041753944064-2789274542-10057-A-0-1_1200.m3u8 +虎牙电影-刘德华,http://aldirect.hls.huya.com/huyalive/94525224-2467341872-10597152648291418112-2789274550-10057-A-0-1_1200.m3u8 +虎牙电影-王晶,http://aldirect.hls.huya.com/huyalive/94525224-2579683592-11079656661667807232-2847687574-10057-A-0-1_1200.m3u8 +虎牙电影-古惑仔,http://tx.hls.huya.com/huyalive/30765679-2523417522-10837995731143360512-2777068634-10057-A-0-1.m3u8 +虎牙电影-赌博,http://tx.hls.huya.com/huyalive/29106097-2689446042-11551082794746642432-2789253870-10057-A-0-1.m3u8 +虎牙电影-成龙,http://aldirect.hls.huya.com/huyalive/94525224-2460685722-10568564701724147712-2789253838-10057-A-0-1_1200.m3u8 +虎牙电影-李连杰,http://js.hls.huya.com/huyalive/94525224-2460686093-10568566295157014528-2789253848-10057-A-0-1_1200.m3u8 +虎牙电影-女神港片,http://tx.hls.huya.com/huyalive/30765679-2484192476-10669525441389264896-2789274564-10057-A-0-1.m3u8 +虎牙电影-丧尸,http://tx.hls.huya.com/huyalive/29106097-2689286606-11550398022340837376-2789274544-10057-A-0-1.m3u8 +虎牙电影-战争,http://tx.hls.huya.com/huyalive/28466698-2689659358-11551998979990355968-2789274580-10057-A-0-1.m3u8 +虎牙电影-好莱坞,http://tx.hls.huya.com/huyalive/30765679-2484192572-10669525853706125312-2847687498-10057-A-1521100607-1.m3u8 +虎牙电影-灾难,http://tx.hls.huya.com/huyalive/29359996-2689475864-11551210879261343744-2847699104-10057-A-1525430092-1.m3u8 +虎牙电影-惊悚,http://tx.hls.huya.com/huyalive/29106097-2689447600-11551089486305689600-2789274568-10057-A-1525420695-1.m3u8 +虎牙电影-复仇犯罪,http://tx.hls.huya.com/huyalive/28466698-2689661530-11552008308659322880-3049003102-10057-A-0-1.m3u8 +虎牙电影-甄子丹,http://tx.hls.huya.com/huyalive/29169025-2686219938-11537226783573147648-2847699096-10057-A-1524024759-1.m3u8 +虎牙电影-古天乐,http://tx.hls.huya.com/huyalive/29169025-2686220040-11537227221659811840-2713685416-10057-A-1524041498-1.m3u8 +虎牙电影-香港魔幻,http://aldirect.hls.huya.com/huyalive/94525224-2460685722-10568564701724147712-2789253838-10057-A-0-1_1200.m3u8 +虎牙电影-周润发,http://aldirect.hls.huya.com/huyalive/94525224-2460685774-10568564925062447104-2789253840-10057-A-0-1_1200.m3u8 +虎牙电影-好莱坞魔幻,http://aldirect.hls.huya.com/huyalive/29106097-2689453724-11551115788685410304-2847687506-10057-A-1525422901-1_1200.m3u8 +虎牙电影-香港古装,http://al.hls.huya.com/huyalive/94525224-2460686093-10568566295157014528-2789253848-10057-A-0-1.m3u8 +虎牙电影-周润发,http://aldirect.hls.huya.com/huyalive/94525224-2460685774-10568564925062447104-2789253840-10057-A-0-1_1200.m3u8 +虎牙电影-林正英,http://aldirect.hls.huya.com/huyalive/94525224-2460686034-10568566041753944064-2789274542-10057-A-0-1_1200.m3u8 +虎牙电影-甄子丹,http://ws4.streamhls.huya.com/huyalive/29169025-2686219938-11537226783573147648-2847699096-10057-A-1524024759-1_1200/playlist.m3u8 +虎牙电影-黄日华,http://ws4.streamhls.huya.com/huyalive/30765679-2523417506-10837995662423883776-2777071322-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-陈小春,http://ws4.streamhls.huya.com/huyalive/30765679-2523417522-10837995731143360512-2777068634-10057-A-0-1_1200/playlist.m3u8 +虎牙电影-黄百鸣,http://ws4.streamhls.huya.com/huyalive/29169025-2686220062-11537227316149092352-2777037828-10057-A-1524041857-1_1200/playlist.m3u8 +虎牙电影-速度与激情,http://aldirect.hls.huya.com/huyalive/29169025-2686219962-11537226886652362752-2710080226-10057-A-0-1_1200.m3u8 +虎牙电影-开心鬼,https://aldirect.hls.huya.com/huyalive/29169025-2686220062-11537227316149092352-2777037828-10057-A-1524041857-1_1200.m3u8 +虎牙电影-笑傲江湖,http://ws4.streamhls.huya.com/huyalive/30765679-2484192476-10669525441389264896-2789274564-10057-A-0-1_10000/playlist.m3u8 +虎牙电视剧-爱情公寓,https://tx.hls.huya.com/huyalive/30765679-2523417493-10837995606589308928-2777071594-10057-A-0-1_1200.m3u8 +虎牙电视剧-陈翔六点半,https://aldirect.hls.huya.com/huyalive/94525224-2655537474-11405446604132450304-2704233350-10057-A-0-1_1200.m3u8 +虎牙电视剧-终极一班,https://aldirect.hls.huya.com/huyalive/29169025-2686220910-11537230958281359360-2847687608-10057-A-1524018691-1_1200.m3u8 +虎牙电视剧-新三国,https://aldirect.hls.huya.com/huyalive/30765679-2523417353-10837995005293887488-2847699118-10057-A-0-1_1200.m3u8 +虎牙电视剧-亮剑,https://js.hls.huya.com/huyalive/30765679-2475713500-10633108516765696000-2789274576-10057-A-0-1_1200.m3u8 +虎牙电视剧-天龙八部,https://ws4.streamhls.huya.com/huyalive/30765679-2475713428-10633108207528050688-3048991608-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-我是特种兵,https://tx.hls.huya.com/huyalive/30765679-2497296332-10725806074360758272-2789253834-10057-A-0-1_1200.m3u8 +虎牙电视剧-铁齿铜牙纪晓岚,https://aldirect.hls.huya.com/huyalive/94525224-2468571348-10602433207502635008-2789253864-10057-A-0-1_1200.m3u8 +虎牙电视剧-神雕侠侣,https://aldirect.hls.huya.com/huyalive/29359996-2689607114-11551774593718943744-2847687530-10057-A-1525492553-1_1200.m3u8 +虎牙电视剧-笑傲江湖,https://aldirect.hls.huya.com/huyalive/29359996-2689640740-11551919016289239040-2847699140-10057-A-0-1_1200.m3u8 +虎牙电视剧-特警力量,https://aldirect.hls.huya.com/huyalive/29141112-2689671100-11552049411496345600-3048959608-10057-A-0-1_1200.m3u8 +虎牙电视剧-卧底警匪,https://aldirect.hls.huya.com/huyalive/29169025-2686220598-11537229618251563008-2847687556-10057-A-1524043048-1_1200.m3u8 +虎牙电视剧-鹿鼎记,https://aldirect.hls.huya.com/huyalive/94525224-2701055008-11600942924057018368-2847687618-10057-A-0-1_1200.m3u8 +虎牙电视剧-卫国无敌,https://aldirect.hls.huya.com/huyalive/29169025-2686221276-11537232530239389696-2777027178-10057-A-1524213244-1_1200.m3u8 +虎牙电视剧-温柔的谎言,https://aldirect.hls.huya.com/huyalive/29359996-2689613622-11551802545366106112-2847687550-10057-A-0-1_1200.m3u8 +虎牙电视剧-士兵突击,https://aldirect.hls.huya.com/huyalive/94525224-2579683622-11079656790516826112-2789274566-10057-A-1521167951-1_1200.m3u8 +虎牙电视剧-新水浒传,https://ws4.streamhls.huya.com/huyalive/30765679-2523417567-10837995924416888832-2789253832-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-兲龙八部,https://aldirect.hls.huya.com/huyalive/30765679-2523417506-10837995662423883776-2777071322-10057-A-0-1_1200.m3u8 +虎牙电视剧-还珠格格,https://ws4.streamhls.huya.com/huyalive/30765679-2523417093-10837993888602390528-2789274530-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-少年包青天,https://aldirect.hls.huya.com/huyalive/30765679-2534694464-10886429828232249344-2789253856-10057-A-0-1_1200.m3u8 +虎牙电视剧-侠客行,https://aldirect.hls.huya.com/huyalive/30765679-2554414889-10971128408670470144-3048991640-10057-A-0-1_1200.m3u8 +虎牙电视剧-勇敢的心,https://ws4.streamhls.huya.com/huyalive/94525224-2604793662-11187503591118077952-3048991612-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-魔幻手机,https://aldirect.hls.huya.com/huyalive/29169025-2686220680-11537229970438881280-2847687524-10057-A-0-1_1200.m3u8 +虎牙电视剧-封神榜,https://ws4.streamhls.huya.com/huyalive/30765679-2523427569-10838038882679783424-2789253886-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-康熙王朝,https://aldirect.hls.huya.com/huyalive/29141112-2691519968-11559990239090966528-3049003118-10057-A-0-1_1200.m3u8 +虎牙电视剧-医馆笑传,https://txdirect.hls.huya.com/huyalive/29359996-2689637846-11551906586653884416-2847687566-10057-A-0-1_1200.m3u8 +虎牙电视剧-倚天屠龙刀,https://aldirect.hls.huya.com/huyalive/29141112-2525901554-10848664567345577984-2847687634-10057-A-0-1_1200.m3u8 +虎牙电视剧-咱们结婚吧,https://aldirect.hls.huya.com/huyalive/29106097-2689287372-11550401312285786112-2789253858-10057-A-0-1_1200.m3u8 +虎牙电视剧-倚天屠龙记,https://aldirect.hls.huya.com/huyalive/30765679-2523417175-10837994240789708800-2789253884-10057-A-0-1_1200.m3u8 +虎牙电视剧-谍战,https://aldirect.hls.huya.com/huyalive/29141112-2689670234-11552045692054667264-3048959590-10057-A-1525515454-1_1200.m3u8 +虎牙电视剧-伪装者,https://js.hls.huya.com/huyalive/30765679-2554414866-10971128309886222336-3049003164-10057-A-0-1_1200.m3u8 +虎牙电视剧-三国演义,https://aldirect.hls.huya.com/huyalive/29169025-2686221140-11537231946123837440-3049003146-10057-A-0-1_1200.m3u8 +虎牙电视剧-终极三国,https://aldirect.hls.huya.com/huyalive/30765679-2480428944-10653361194531815424-2789274554-10057-A-0-1_1200.m3u8 +虎牙电视剧-民兵葛二蛋,https://aldirect.hls.huya.com/huyalive/30765679-2675956786-11493146881379270656-3049003120-10057-A-0-1_1200.m3u8 +虎牙电视剧-康熙微服私访,https://aldirect.hls.huya.com/huyalive/29169025-2686221704-11537234368485392384-2789274536-10057-A-0-1_1200.m3u8 +虎牙电视剧-丧尸来了,https://ws4.streamhls.huya.com/huyalive/29106097-2689286606-11550398022340837376-2789274544-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-热血高校,https://txdirect.hls.huya.com/huyalive/29169025-2686219818-11537226268177072128-2789253878-10057-A-0-1_1200.m3u8 +虎牙电视剧-射雕英雄传,https://aldirect.hls.huya.com/huyalive/30765679-2686220976-11537231241749200896-3049003126-10057-A-0-1_1200.m3u8 +虎牙电视剧-隋唐英雄传,https://aldirect.hls.huya.com/huyalive/29359996-2689637532-11551905238034153472-2847687564-10057-A-0-1_1200.m3u8 +虎牙电视剧-齐天大圣,https://ws4.streamhls.huya.com/huyalive/30765679-2550665260-10955023874743336960-2789253862-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-雪山飞狐,https://aldirect.hls.huya.com/huyalive/29169025-2686220976-11537231241749200896-2847699180-10057-A-0-1_1200.m3u8 +虎牙电视剧-宝莲灯,https://aldirect.hls.huya.com/huyalive/30765679-2525901744-10848665383389364224-2847699200-10057-A-0-1_1200.m3u8 +虎牙电视剧-我的兄弟叫顺溜,https://aldirect.hls.huya.com/huyalive/30765679-2523205260-10837084072795176960-2789274532-10057-A-1511870010-1_1200.m3u8 +虎牙电视剧-雍正王朝,https://txdirect.hls.huya.com/huyalive/29359996-2689277426-11550358594541060096-2847699098-10057-A-0-1_1200.m3u8 +虎牙电视剧-篮球火,https://aldirect.hls.huya.com/huyalive/30765679-2682197822-11519951926892429312-2847699094-10057-A-0-1_1200.m3u8 +虎牙电视剧-西游记,https://aldirect.hls.huya.com/huyalive/29141112-2689673336-11552059015043219456-3048991588-10057-A-0-1_1200.m3u8 +虎牙电视剧-龙门镖局,https://aldirect.hls.huya.com/huyalive/29106097-2689454638-11551119714285518848-2847687516-10057-A-0-1_1200.m3u8 +虎牙电视剧-终极一班,https://aldirect.hls.huya.com/huyalive/29169025-2686221732-11537234488744476672-2847699168-10057-A-0-1_1200.m3u8 +虎牙电视剧-家有儿女,https://aldirect.hls.huya.com/huyalive/29169025-2686221252-11537232427160174592-2847687508-10057-A-0-1_1200.m3u8 +虎牙电视剧-济公,https://aldirect.hls.huya.com/huyalive/29169025-2686221242-11537232384210501632-2847687560-10057-A-0-1_1200.m3u8 +虎牙电视剧-大长今,https://aldirect.hls.huya.com/huyalive/30765679-2533158964-10879834905949241344-2847687638-10057-A-0-1_1200.m3u8 +虎牙电视剧-济公2,https://aldirect.hls.huya.com/huyalive/29169025-2686221242-11537232384210501632-2847687560-10057-A-0-1_1200.m3u8 +虎牙电视剧-轩辕剑,https://aldirect.hls.huya.com/huyalive/28466698-2689663056-11552014862779416576-3048959692-10057-A-0-1_1200.m3u8 +虎牙电视剧-最佳搭档,https://aldirect.hls.huya.com/huyalive/30765679-2689675756-11552069408864075776-3048991624-10057-A-0-1_1200.m3u8 +虎牙电视剧-宝莲灯,https://aldirect.hls.huya.com/huyalive/30765679-2525901744-10848665383389364224-2847699200-10057-A-0-1_1200.m3u8 +虎牙电视剧-风云霸天下,https://aldirect.hls.huya.com/huyalive/94525224-2604793760-11187504012024872960-2847699160-10057-A-1523523587-1_1200.m3u8 +虎牙电视剧-战雷,https://aldirect.hls.huya.com/huyalive/28466698-2689654432-11551977822981455872-2847687622-10057-A-1525510118-1_1200.m3u8 +虎牙电视剧-情深深雨蒙蒙,https://aldirect.hls.huya.com/huyalive/94525224-2583571812-11096356439407460352-2847687552-10057-A-0-1_1200.m3u8 +虎牙电视剧-张卫健,https://aldirect.hls.huya.com/huyalive/94525224-2472045388-10617354095687630848-2847687664-10057-A-1526356723-1_1200.m3u8 +虎牙电视剧-步步惊心,https://aldirect.hls.huya.com/huyalive/29169025-2686221544-11537233681290625024-2847687612-10057-A-1523933320-1_1200.m3u8 +虎牙电视剧-大宅门,https://aldirect.hls.huya.com/huyalive/29106097-2689284984-11550391055903883264-2847699150-10057-A-0-1_1200.m3u8 +虎牙电视剧-我的团长我的团,https://tx.hls.huya.com/huyalive/94525224-2583571852-11096356611206152192-2847687652-10057-A-0-1_1200.m3u8 +虎牙电视剧-小鱼儿与花无缺,https://aldirect.hls.huya.com/huyalive/28466698-2689664968-11552023074756886528-3048991596-10057-A-1525513786-1_1200.m3u8 +虎牙电视剧-大秦帝国,https://aldirect.hls.huya.com/huyalive/30765679-2554414808-10971128060778119168-3048959636-10057-A-0-1_1200.m3u8 +虎牙电视剧-上海滩,https://aldirect.hls.huya.com/huyalive/28466698-2689659874-11552001196193480704-2847699220-10057-A-0-1_1200.m3u8 +虎牙电视剧-人间正道是沧桑,https://aldirect.hls.huya.com/huyalive/30765679-2685178192-11532752518572408832-3048959604-10057-A-0-1_1200.m3u8 +虎牙电视剧-流星雨,https://aldirect.hls.huya.com/huyalive/29141112-2689670670-11552047564660408320-2847687630-10057-A-0-1_1200.m3u8 +虎牙电视剧-大唐双龙传,https://aldirect.hls.huya.com/huyalive/30765679-2554414910-10971128498864783360-3049003166-10057-A-0-1_1200.m3u8 +虎牙电视剧-天外飞仙,https://aldirect.hls.huya.com/huyalive/29106097-2689283558-11550384931280519168-2789274528-10057-A-1525418694-1_1200.m3u8 +虎牙电视剧-X女特工,https://aldirect.hls.huya.com/huyalive/30765679-2554414938-10971128619123867648-3048959644-10057-A-0-1_1200.m3u8 +虎牙电视剧-红色追击令,https://aldirect.hls.huya.com/huyalive/28466698-2689654812-11551979455069028352-2847687626-10057-A-1525510268-1_1200.m3u8 +虎牙电视剧-少年锦衣卫,https://aldirect.hls.huya.com/huyalive/30765679-2475855302-10633717551718203392-2847687536-10057-A-1523416572-1_1200.m3u8 +虎牙电视剧-远去的飞鹰,https://aldirect.hls.huya.com/huyalive/29169025-2686221528-11537233612571148288-2847687610-10057-A-1523932939-1_1200.m3u8 +虎牙电视剧-圆月弯刀,https://ws.streamhls.huya.com/huyalive/1444264131-1444264131-6203067209430859776-2884953448-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-道师爷,https://aldirect.hls.huya.com/huyalive/29359996-2689642844-11551928052900429824-2847699142-10057-A-0-1_1200.m3u8 +虎牙电视剧-还珠格格,https://ws4.streamhls.huya.com/huyalive/30765679-2523417093-10837993888602390528-2789274530-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-倚天屠龙记,https://aldirect.hls.huya.com/huyalive/29141112-2525901554-10848664567345577984-2847687634-10057-A-0-1_1200.m3u8 +虎牙电视剧-雪山飞狐,https://aldirect.hls.huya.com/huyalive/29169025-2686220976-11537231241749200896-2847699180-10057-A-0-1_1200.m3u8 +虎牙电视剧-鹿鼎记,https://aldirect.hls.huya.com/huyalive/94525224-2701055008-11600942924057018368-2847687618-10057-A-0-1_1200.m3u8 +虎牙电视剧-神雕侠侣,https://aldirect.hls.huya.com/huyalive/29359996-2689607114-11551774593718943744-2847687530-10057-A-1525492553-1_1200.m3u8 +虎牙电视剧-笑傲江湖,https://aldirect.hls.huya.com/huyalive/29359996-2689640740-11551919016289239040-2847699140-10057-A-0-1_1200.m3u8 +虎牙电视剧-天龙八部,https://ws4.streamhls.huya.com/huyalive/30765679-2475713428-10633108207528050688-3048991608-10057-A-0-1_1200/playlist.m3u8 +虎牙电视剧-射雕英雄传,https://aldirect.hls.huya.com/huyalive/30765679-2686220976-11537231241749200896-3049003126-10057-A-0-1_1200.m3u8 +虎牙电视剧-侠客行,https://aldirect.hls.huya.com/huyalive/30765679-2554414889-10971128408670470144-3048991640-10057-A-0-1_1200.m3u8 +虎牙电视剧-鹿鼎记,https://aldirect.hls.huya.com/huyalive/94525224-2701055008-11600942924057018368-2847687618-10057-A-0-1_1200.m3u8 +虎牙电视剧-隋唐英雄传,https://aldirect.hls.huya.com/huyalive/29359996-2689637532-11551905238034153472-2847687564-10057-A-0-1_1200.m3u8 +国家地理悠人,http://cloud-play.hhalloy.com/live/0293b493509468a0a896adea05ad5e30.flv +国家地理野生,http://cloud-play.hhalloy.com/live/a4540237835700ece1fc1e54ce826125.flv +国家地理HD,http://cloud-play.hhalloy.com/live/1b4017a457de80eec599895ec807e124.flv +历史频道,http://cloud-play.hhalloy.com/live/998ce23199bda76900024601f6dd859d.flv +历史频道2,http://cloud-play.hhalloy.com/live/b4d47c14a4665a2ef43d657ea6384c27.flv +广东影视,http://nclive.grtn.cn/tvs4/sd/live.m3u8 +广东新闻,http://nclive.grtn.cn/xwpd/sd/live.m3u8 +广东少儿,http://nclive.grtn.cn/tvs5/sd/live.m3u8 +广东公共,http://nclive.grtn.cn/ggpd/sd/live.m3u8 +广东国际,http://nclive.grtn.cn/gjpd/sd/live.m3u8 +广东房产,http://nclive.grtn.cn/fcpd/sd/live.m3u8 +广东科教,http://nclive.grtn.cn/tvs1hd/hd/live.m3u8 +广东珠江,http://nclive.grtn.cn/zjpd/sd/live.m3u8 +河北卫视,http://weblive.hebtv.com/live/hbws_bq/index.m3u8 +兵团卫视,http://v.btzx.com.cn:1935/live/weishi.stream/playlist.m3u8 +珠江频道,http://nclive.grtn.cn/zjpd/sd/live.m3u8 +嘉佳卡通,http://nclive.grtn.cn/jjkt/sd/live.m3u8 +山东教育,http://live.sdetv.com.cn/live/sdetv/playlist.m3u8 +康巴卫视,http://scgctvshow.sctv.com/sdlive/kangba/3.m3u8 +北京影视,http://ivi.bupt.edu.cn/hls/btv4.m3u8 +北京新闻,http://ivi.bupt.edu.cn/hls/btv9.m3u8 +重庆新闻,http://219.153.252.50/PLTV/88888888/224/3221225531/chunklist.m3u8 +河北少儿,http://weblive.hebtv.com/live/hbse_bq/index.m3u8 +高尔夫,http://nclive.grtn.cn/grfpd/sd/live.m3u8 +北京科教,http://ivi.bupt.edu.cn/hls/btv3.m3u8 +北京影视,http://ivi.bupt.edu.cn/hls/btv4.m3u8 +北京财经,http://ivi.bupt.edu.cn/hls/btv5.m3u8 +北京生活,http://ivi.bupt.edu.cn/hls/btv7.m3u8 +北京青年,http://ivi.bupt.edu.cn/hls/btv8.m3u8 +北京新闻,http://ivi.bupt.edu.cn/hls/btv9.m3u8 +河北经济,http://weblive.hebtv.com/live/hbjj_bq/index.m3u8 +河北都市,http://weblive.hebtv.com/live/hbds_bq/index.m3u8 +河北影视,http://weblive.hebtv.com/live/hbys_bq/index.m3u8 +河北少儿,http://weblive.hebtv.com/live/hbse_bq/index.m3u8 +河北公共,http://weblive.hebtv.com/live/hbgg_bq/index.m3u8 +河北农民,http://weblive.hebtv.com/live/nmpd_bq/index.m3u8 +辽宁公共,http://lms.csytv.com/Live/124/live/livestream.m3u8 +泉州综合,http://live.qztvxwgj.com/live/news.m3u8 +泉州闽南语,http://live.qztvxwgj.com/live/mny.m3u8 +福州综合,http://live1.fzntv.cn/live/zohi_fztv1/playlist.m3u8 +福州影视,http://live1.fzntv.cn/live/zohi_fztv2/playlist.m3u8 +福州生活,http://live1.fzntv.cn/live/zohi_fztv3/playlist.m3u8 +福州少儿,http://live1.fzntv.cn/live/zohi_fztv4/playlist.m3u8 +宁德综合,http://220.161.247.82:8199/live/nd1_1128.m3u8 +宁德公共,http://220.161.247.82:8199/live/nd2_1128.m3u8 +石狮综合,http://218.5.112.180:88/live/dssl/playlist.m3u8 +叶县一套,http://hnyx.chinashadt.com:1935/live/yexian1001.stream/playlist.m3u8 +叶县二套,http://hnyx.chinashadt.com:1935/live/1002.stream/playlist.m3u8 +娄底综合,http://218.77.102.118:1935/live/zonghe/playlist.m3u8 +娄底公共,http://218.77.102.118:1935/live/gonggong/playlist.m3u8 +南方卫视,http://nclive.grtn.cn/tvs2/sd/live.m3u8 +深圳蛇口,http://218.17.99.211:82/hls/d4encs75.m3u8 +潮州综合,http://live.zscz0768.com/live/zhpd.m3u8 +潮州公共,http://live.zscz0768.com/live/ggpd.m3u8 +海口一套,http://hls.hkbtv.cn/hkbtv/0a2dnq6ZoKKknKmL4K2dmqqW7KGgn6uWoqk/playlist.m3u8 +海口二套,http://hls.hkbtv.cn/hkbtv/0a2dnq6ZoKKknKiL4K2dmqqW7KGgn6uWoqc/playlist.m3u8 +海口三套,http://hls.hkbtv.cn/hkbtv/0a2dnq6ZoKKknKeL4K2dmqqW7KGgn6uWoqU/playlist.m3u8 +陕西新闻,http://stream.snrtv.com/sxtvs-1.m3u8 +陕西都市,http://stream.snrtv.com/sxtvs-2.m3u8 +陕西生活,http://stream.snrtv.com/sxtvs-3.m3u8 +陕西公共,http://stream.snrtv.com/sxtvs-5.m3u8 +西安新闻,http://stream2.xiancity.cn/xatv1/sd/live.m3u8 +西安白鸽,http://stream2.xiancity.cn/xatv2/sd/live.m3u8 +西安资讯,http://stream2.xiancity.cn/xatv3/sd/live.m3u8 +西安影视,http://stream2.xiancity.cn/xatv4/sd/live.m3u8 +西安健康,http://stream2.xiancity.cn/xatv5/sd/live.m3u8 +江西新闻HD,http://live02.jxtvcn.com.cn/live-jxtvcn/jxtv07.m3u8 +蚌埠新闻综合,http://newvod.ahbbtv.com:1935/live/smil:xwpd_copy.smil/playlist.m3u8 +蚌埠公共频道,http://newvod.ahbbtv.com:1935/live/smil:ggpd_copy.smil/playlist.m3u8 +蚌埠生活频道,http://newvod.ahbbtv.com:1935/live/smil:shpd_copy.smil/playlist.m3u8 +蚌埠公交频道,http://newvod.ahbbtv.com:1935/live/smil:gjpd_copy.smil/playlist.m3u8 +宿州公共频道,http://live.ahsz.tv/video/s10001-ggpd/index.m3u8 +宿州科教频道,http://live.ahsz.tv/video/s10001-kxjy/index.m3u8 +阜阳新闻综合,http://120.210.216.73:8080/ysten-business/reallive/fyxwpd/1.m3u8 +阜阳公共频道,http://120.210.216.73:8080/ysten-business/reallive/fyggpd/1.m3u8 +阜阳教育频道,http://120.210.216.73:8080/ysten-business/reallive/fyjypd/1.m3u8 +阜阳都市频道,http://120.210.216.73:8080/ysten-business/reallive/fydspd/1.m3u8 +亳州新闻频道,http://220.180.110.101:8083/videos/live/33/59/NC7XQdEveyncq/NC7XQdEveyncq.m3u8 +亳州农村频道,http://220.180.110.101:8083/videos/live/39/13/o4ncrHkSp7q09/o4ncrHkSp7q09.m3u8 +芜湖新闻综合,http://live1.wuhubtv.com/channel1/sd/live.m3u8 +芜湖生活频道,http://live1.wuhubtv.com/channel2/sd/live.m3u8 +芜湖公共频道,http://live1.wuhubtv.com/channel3/sd/live.m3u8 +芜湖教育频道,http://live1.wuhubtv.com/channel4/sd/live.m3u8 +六安新闻综合,http://live.china-latv.com/channel1/sd/live.m3u8 +六安公共频道,http://live.china-latv.com/channel2/sd/live.m3u8 +马鞍山新闻综合,http://live.massp.cn:5011/vod/video_hls/c01.m3u8 +马鞍山影视频道,http://live.massp.cn:5011/vod/video_hls/c02.m3u8 +滁州新闻综合,http://183.167.193.45:1935/live/cztvzh/playlist.m3u8 +滁州科教频道,http://183.167.193.45:1935/live/cztvkj/playlist.m3u8 +滁州公共频道,http://183.167.193.45:1935/live/cztvgg/playlist.m3u8 +宿松新闻综合,http://31022.hlsplay.aodianyun.com/lms_31022/tv_channel_99.m3u8 +宿松影视文艺,http://31022.hlsplay.aodianyun.com/lms_31022/tv_channel_126.m3u8 +东至影视频道,http://223.247.33.124:1935/live/yingshi/playlist.m3u8 +东至文化资讯,http://223.247.33.124:1935/live/wenhua/playlist.m3u8 +岳西综合频道,http://58.243.4.22:1935/live/zonghe/playlist.m3u8 +岳西影视频道,http://58.243.4.22:1935/live/yingshi/playlist.m3u8 +岳西图文频道,http://58.243.4.22:1935/live/tuwen/playlist.m3u8 +涡阳新闻综合,http://220.180.110.101:8083/videos/live/36/57/hwEHU4UVQ1Iv5/hwEHU4UVQ1Iv5.m3u8 +霍山综合频道,http://ahhs.chinashadt.com:1936/live/stream:hs1.stream/playlist.m3u8 +北京影视,http://ivi.bupt.edu.cn/hls/btv4.m3u8 +北京财经,http://ivi.bupt.edu.cn/hls/btv5.m3u8 +北京生活,http://ivi.bupt.edu.cn/hls/btv7.m3u8 +北京青年,http://ivi.bupt.edu.cn/hls/btv8.m3u8 +万州综合频道,http://wanzhoulive.cbg.cn:8017/iTXwrGs/800/live.m3u8 +万州三峡移民,http://wanzhoulive.cbg.cn:8017/c2F0hmi/1000/live.m3u8 +万州影视文艺,http://wanzhoulive.cbg.cn:8017/d4ceB1a/1000/live.m3u8 +万州科教频道,http://wanzhoulive.cbg.cn:8017/Cz7WPb8/800/live.m3u8 +梁平综合频道,http://qxlmlive.cbg.cn:1935/app_2/ls_44.stream/playlist.m3u8 +长寿文化旅游,http://qxlmlive.cbg.cn:1935/app_2/ls_75.stream/playlist.m3u8 +酉阳新闻综合,http://qxlmlive.cbg.cn:1935/app_2/ls_68.stream/chunklist.m3u8 +开州综合频道,http://kaixianlive.cbg.cn:10345/1.m3u8 +开州生活频道,http://kaixianlive.cbg.cn:10345/5.m3u8 +綦江综合频道,http://113.207.29.195:1935/app_2/_definst_/ls_25.stream/playlist.m3u8 +江津经济生活,http://jiangjinlive.cbg.cn:1935/ch0.m3u8 +丰都文化旅游,http://125.62.25.201:1936/output0.m3u8 +忠县综合频道,http://qxlmlive.cbg.cn:1935/app_2/_definst_/ls_35.stream/playlist.m3u8 +黔江综合频道,http://qianjianglive.cbg.cn:9001/hls/live/live1/starsam.m3u8 +黔江武陵频道,http://qianjianglive.cbg.cn:9001/hls/live/live2/starsam.m3u8 +黔江生态文化,http://qianjianglive.cbg.cn:9001/hls/live/live3/starsam.m3u8 +城口综合频道,http://chengkoulive2.cbg.cn:1935/chengkou01.m3u8 +万盛新闻综合,http://qxlmlive.cbg.cn:1935/app_2/ls_40.stream/playlist.m3u8 +福建导视,http://fjnh.chinashadt.com:2036/live/stream:fjds.stream/playlist.m3u8 +福州综合,http://live.zohi.tv/video/s10001-FZTV-1/index.m3u8 +福州影视,http://live.zohi.tv/video/s10001-yspd-2/index.m3u8 +福州生活,http://live.zohi.tv/video/s10001-shpd-3/index.m3u8 +福州少儿,http://live.zohi.tv/video/s10001-sepd-4/index.m3u8 +泉州新闻综合,http://live.qztvxwgj.com/live/news.m3u8 +泉州闽南语,http://live.qztvxwgj.com/live/mny.m3u8 +漳州新闻综合,http://31182.hlsplay.aodianyun.com/lms_31182/tv_channel_175.m3u8 +宁德新闻综合,http://220.161.247.82:8199/live/nd1_696.m3u8 +宁德公共频道,http://220.161.247.82:8199/live/nd2.m3u8 +三明新闻综合,http://stream.smntv.cn/smtv1/sd/live.m3u8 +三明公共频道,http://stream.smntv.cn/smtv2/sd/live.m3u8 +上杭综合频道,http://fjsh.chinashadt.com:1935/live/fjds.stream/playlist.m3u8 +新罗电视一套,http://stream.lyxltv.com/xltv/sd/live.m3u8 +新罗电视二套,http://stream.lyxltv.com/xinluotv/sd/live.m3u8 +宁化电视一套,http://fjnh.chinashadt.com:2036/live/stream:nh1.stream/playlist.m3u8 +晋江侨乡,http://stream.jinjiang.tv/1/sd/live.m3u8 +石狮综合,http://218.5.112.180:88/live/dssl/playlist.m3u8 +长乐综合,http://35908.hlsplay.aodianyun.com/guangdianyun_35908/tv_channel_327.m3u8 +甘南藏语频道,http://live.gnrtv.com:9600/live/live2/tzwj_video.m3u8 +敦煌综合频道,http://live.todaydunhuang.com:1935/live/live100/500K/tzwj_video.m3u8 +天水新闻综合,http://61.178.129.74:5021/live_hls/1/playlist.m3u8 +天水公共频道,http://61.178.129.74:5021/live_hls/3/playlist.m3u8 +广东经济科教HD,http://nclive.grtn.cn/tvs1hd/hd/live.m3u8 +广东珠江,http://nclive.grtn.cn/zjpd/sd/live.m3u8 +广东新闻,http://nclive.grtn.cn/xwpd/sd/live.m3u8 +广东房产,http://nclive.grtn.cn/fcpd/sd/live.m3u8 +广东国际,http://nclive.grtn.cn/gjpd/sd/live.m3u8 +嘉佳卡通,http://nclive.grtn.cn/jjkt/sd/live.m3u8 +高尔夫频道,http://nclive.grtn.cn/grfpd/sd/live.m3u8 +广东经济科教,http://nclive.grtn.cn/tvs1/sd/live.m3u8 +广东影视,http://nclive.grtn.cn/tvs4/sd/live.m3u8 +广东少儿,http://nclive.grtn.cn/tvs5/sd/live.m3u8 +南方购物,http://nclive.grtn.cn/nfgw/sd/live.m3u8 +蛇口综合,http://218.17.99.211:82/hls/d4encs75.m3u8 +清远综合,http://stream1.0763f.com/qyzh/sd/live.m3u8 +清远公共,http://stream1.0763f.com/qygg/sd/live.m3u8 +潮州综合,http://live.zscz0768.com/live/zhpd.m3u8 +潮州公共,http://live.zscz0768.com/live/ggpd.m3u8 +电白综合,http://gddb.chinashadt.com:1935/live/video1.stream/playlist.m3u8 +电白视窗,http://gddb.chinashadt.com:1935/live/video2.stream/playlist.m3u8 +开平综合,http://pili-live-hls.livekpdst.sobeycache.com/kpdst/gb1.m3u8 +开平生活,http://pili-live-hls.livekpdst.sobeycache.com/kpdst/zb2.m3u8 +番禺,http://live.pybtv.cn/channel1/sd/live.m3u8 +潮安综合,http://chaoan.chaoantv.com:8278/zongyi_1028/playlist.m3u8 +潮安影视,http://chaoan.chaoantv.com:8278/live/chaoanyingshi.m3u8 +增城综合,http://202.168.164.38:8083/videos/live/19/27/QEQXMtU5AUpwo/QEQXMtU5AUpwo.m3u8 +钦州综合频道,http://live.gxqztv.com/cspd1/sd/live.m3u8 +防城港新闻综合,http://221.7.232.46:10190/live/myStream/playlist.m3u8 +黔西南综合,http://live.qxndt.com/channel2/sd/live.m3u8 +黔西南公共,http://live.qxndt.com/channel3/sd/live.m3u8 +海口新闻综合,http://hls.hkbtv.cn/hkbtv/0a2dnq6ZoKKknKmL4K2dmqqW7KGgn6uWoqk/playlist.m3u8 +海口生活娱乐,http://hls.hkbtv.cn/hkbtv/0a2dnq6ZoKKknKiL4K2dmqqW7KGgn6uWoqc/playlist.m3u8 +海口双创频道,http://hls.hkbtv.cn/hkbtv/0a2dnq6ZoKKknKeL4K2dmqqW7KGgn6uWoqU/playlist.m3u8 +衡水影视娱乐,http://hls.hsrtv.cn/hls/hstv2.m3u8 +衡水公共频道,http://hls.hsrtv.cn/hls/hstv3.m3u8 +秦皇岛新闻,http://vod.qhdcm.com:1935/live/qhdtv1/800K/tzwj_video.m3u8 +秦皇岛政法,http://vod.qhdcm.com:1935/live/qhdtv2/800K/tzwj_video.m3u8 +秦皇岛影视,http://vod.qhdcm.com:1935/live/qhdtv3/800K/tzwj_video.m3u8 +辛集新闻频道,http://zsxj.chinashadt.com:1935/live/xjxw.stream_360p/playlist.m3u8 +辛集生活频道,http://zsxj.chinashadt.com:1935/live/xjsh.stream_360p/playlist.m3u8 +枣强综合,http://hbzq.chinashadt.com:1936/live/zaoqiang5.stream_360p/palylist.m3u8 +馆陶美丽乡村,http://hbgt.chinashadt.com:1935/live/stream:mlxc.stream_720p/playlist.m3u8 +滦南新闻综合,http://tv.lnshw.com.cn:3000/hls/pegdvlxq/index.m3u8 +沙河新闻综合,http://hbsh.chinashadt.com:2036/live/1.stream/playlist.m3u8 +吴桥综合,http://wuqiao.chinashadt.com:2035/live/di5.stream/playlist.m3u8 +吴桥生活,http://wuqiao.chinashadt.com:2035/live/di6.stream/playlist.m3u8 +赞皇综合,http://hbzz.chinashadt.com:2036/zhibo/4.stream/playlist.m3u8 +黄骅一套,http://hbhh.chinashadt.com:2111/live/hhtv.stream/playlist.m3u8 +黄骅二套,http://hbhh.chinashadt.com:2111/live/hhtv2.stream/playlist.m3u8 +黄骅影视,http://hbhh.chinashadt.com:2111/live/hhys.stream/playlist.m3u8 +黄骅互动,http://hbhh.chinashadt.com:2111/live/hdtv.stream/playlist.m3u8 +饶阳一套,http://hbry.chinashadt.com:1938/live/1005.stream_360p/playlist.m3u8 +饶阳二套,http://hbry.chinashadt.com:1938/live/1006.stream_360p/playlist.m3u8 +迁安新闻综合,http://app.qatv.cn:1936/live/stream:xwzh.stream_720p/playlist.m3u8 +迁安生活影视,http://app.qatv.cn:1937/live/stream:shfw.stream_720p/playlist.m3u8 +迁安快乐3频道,http://app.qatv.cn:1936/live/stream:kl3pd.stream_720p/playlist.m3u8 +永年民生频道,http://hbyn.chinashadt.com:1936/live/stream:ynms.stream_360p/playlist.m3u8 +隆化综合频道,http://hblh.chinashadt.com:2036/live/stream:lh1.stream/playlist.m3u8 +隆化影视频道,http://hblh.chinashadt.com:2036/live/stream:lh2.stream/playlist.m3u8 +沧县电视综合,http://hebcx.chinashadt.com:2036/live/10001.stream/playlist.m3u8 +霸州新闻频道,http://hbbz.chinashadt.com:2036/live/stream:bzxw.stream/playlist.m3u8 +霸州文化频道,http://hbbz.chinashadt.com:2036/live/stream:bzwh.stream/playlist.m3u8 +霸州公共频道,http://hbbz.chinashadt.com:2036/live/stream:bzgg.stream/playlist.m3u8 +霸州少儿频道,http://hbbz.chinashadt.com:2036/live/stream:bzse.stream/playlist.m3u8 +滦县综合频道,http://hblxx.chinashadt.com:2036/live/stream:lx1.stream/playlist.m3u8 +滦县综艺频道,http://hblxx.chinashadt.com:2036/live/stream:lx2.stream/playlist.m3u8 +高碑店一套,http://34540.hlsplay.aodianyun.com/guangdianyun_34540/tv_channel_206.m3u8 +鹿泉一套,http://hblq.chinashadt.com:2036/live/stream:luquan1.stream/playlist.m3u8 +赵县电视一套,http://hbzx.chinashadt.com:2036/zhibo/stream:zx1.stream_360p/playlist.m3u8 +晋州新闻频道,http://zhjz.chinashadt.com:2036/live/1.stream/playlist.m3u8 +深州综合频道,http://hbsz.chinashadt.com:2036/live/stream:sztv.stream/playlist.m3u8 +景县电视二套,http://hbjx.chinashadt.com:1935/live/stream:jx2.stream_360p/playlist.m3u8 +郑州教育频道,http://218.28.177.199:1935/live/mp4:500k/playlist.m3u8 +洛阳综合频道,http://live1.lytv.com.cn:1935/live/LYTV1-2/playlist.m3u8 +洛阳科教频道,http://live2.lytv.com.cn:1935/live/LYTV2-1/playlist.m3u8 +洛阳公共频道,http://live2.lytv.com.cn:1935/live/LYTV3-1/playlist.m3u8 +济源电视一套,http://218.28.111.98:81/hls/live2.m3u8 +鹤壁综合频道,http://pili-live-hls.hebitv.com/hebi/hebi.m3u8 +清丰有线频道,http://hnqf.chinashadt.com:2036/live/2.stream/playlist.m3u8 +清丰党建频道,http://hnqf.chinashadt.com:2036/live/4.stream/playlist.m3u8 +荆州新闻,http://33058.hlsplay.aodianyun.com/guangdianyun_33058/tv_channel_216.m3u8 +荆州垄上,http://33058.hlsplay.aodianyun.com/guangdianyun_33058/tv_channel_325.m3u8 +襄阳综合,http://xiangyang.live.cjyun.org/video/s10125-news_hd/index.m3u8 +襄阳公共,http://xiangyang.live.cjyun.org/video/s10125-education_hd/index.m3u8 +恩施综合,http://enshi.live.cjyun.org/video/s10070-eszh.m3u8 +恩施公共,http://enshi.live.cjyun.org/video/s10070-esgg.m3u8 +孝感新闻综合,http://xiaogan.live.cjyun.org/video/s10139-xg/index.m3u8 +孝感公共频道,http://xiaogan.live.cjyun.org/video/s10139-shpd/index.m3u8 +黄冈新闻频道,http://huanggang.live.cjyun.org/video/s10120-xwzh.m3u8 +黄冈公共频道,http://huanggang.live.cjyun.org/video/s10120-xwgg.m3u8 +仙桃新闻综合,http://36979.hlsplay.aodianyun.com/guangdianyun_36979/tv_channel_509.m3u8 +仙桃生活文体,http://36979.hlsplay.aodianyun.com/guangdianyun_36979/tv_channel_510.m3u8 +咸宁综合频道,http://xianning.live.cjyun.org/video/s10140-XNTV-1/index.m3u8 +利川新闻综合,http://lichuan.live.tempsource.cjyun.org/videotmp/s10093-lczh.m3u8 +利川公共频道,http://lichuan.live.tempsource.cjyun.org/videotmp/s10093-lcgg.m3u8 +孝昌新闻党建,http://xiaochang.live.cjyun.org/video/s10128-xcxw/index.m3u8 +孝昌生活频道,http://xiaochang.live.cjyun.org/video/s10128-xcsh/index.m3u8 +罗田综合,http://luotian.live.cjyun.org/video/s10013-LTZH/index.m3u8 +罗田旅游,http://luotian.live.cjyun.org/video/s10013-LTLY/index.m3u8 +红安综合,http://hongan.live.cjyun.org/video/s10063-HAZH.m3u8 +大悟综合,http://yunshangdawu.live.tempsource.cjyun.org/videotmp/s10129-dwzhpd.m3u8 +应城新闻综合,http://yingcheng.live.cjyun.org/video/s10135-YCZH/index.m3u8 +应城生活频道,http://yingcheng.live.cjyun.org/video/s10135-YCDJ/index.m3u8 +秭归新闻综合,http://zigui.live.cjyun.org/video/s10111-ZGTV1.m3u8 +大冶一套,http://dayeyun.live.tempsource.cjyun.org/videotmp/s10102-TC1T.m3u8 +大冶二套,http://dayeyun.live.tempsource.cjyun.org/videotmp/s10102-TC2T.m3u8 +嘉鱼新闻综合,http://jiayu.live.tempsource.cjyun.org/videotmp/s10131-jyzh.m3u8 +鹤峰综合频道,http://hefeng.live.tempsource.cjyun.org/videotmp/s10100-hftv.m3u8 +夷陵综合,http://yiling.live.cjyun.org/video/s10174-TC1T/index.m3u8 +广水新闻频道,http://guangshui.live.tempsource.cjyun.org/videotmp/s10146-GSXW.m3u8 +云梦综合频道,http://yunshangyunmeng.live.cjyun.org/video/s10130-ymzh.m3u8 +云梦党建农业,http://yunshangyunmeng.live.cjyun.org/video/s10130-ymdjny.m3u8 +娄底综合频道,http://218.77.102.118:1935/live/zonghe/playlist.m3u8 +娄底公共频道,http://218.77.102.118:1935/live/gonggong/playlist.m3u8 +宜章新闻综合,http://hnyz.chinashadt.com:2036/live/stream:tv1.stream/playlist.m3u8 +宜章社会法制,http://hnyz.chinashadt.com:2036/live/stream:tv2.stream/playlist.m3u8 +邵东综合频道,http://hnsd.chinashadt.com:2036/live/stream:shaodong.stream/playlist.m3u8 +双峰电视一套,http://hnsf.chinashadt.com:2036/zhuanma/tv1.stream_360p/playlist.m3u8 +南京新闻综合,http://live.nbs.cn/channels/njtv/xwzh/m3u8:500k/live.m3u8 +南京影视,http://live.nbs.cn/channels/njtv/yspd/m3u8:500k/live.m3u8 +南京生活,http://live.nbs.cn/channels/njtv/shpd/m3u8:500k/live.m3u8 +南京娱乐,http://live.nbs.cn/channels/njtv/ylpd/m3u8:500k/live.m3u8 +南京十八,http://live.nbs.cn/channels/njtv/sbpd/m3u8:500k/live.m3u8 +南京少儿,http://live.nbs.cn/channels/njtv/sepd/m3u8:500k/live.m3u8 +无锡生活,http://live-wx.wifiwx.com/wxtv4/sd/live.m3u8 +张家港新闻综合,http://3gvod.zjgonline.com.cn:1935/live/xinwenzonghe2/playlist.m3u8 +张家港社会生活,http://3gvod.zjgonline.com.cn:1935/live/shehuishenghuo2/playlist.m3u8 +江阴新闻综合,http://w3.wifijiangyin.com:1936/live/xwzh_gq/playlist.m3u8 +江阴民生频道,http://w3.wifijiangyin.com:1936/live/mspd_gq/playlist.m3u8 +宜兴新闻频道,http://live-dft-hls-yf.jstv.com/live/yixing_xw/online.m3u8 +新沂新闻频道,http://stream.yishuweb.cn:1935/live/live1/playlist.m3u8 +新沂生活频道,http://stream.yishuweb.cn:1935/live/live2/playlist.m3u8 +太仓新闻频道,http://58.211.172.37:1935/live/tcxwpc/playlist.m3u8 +太仓党建频道,http://58.211.172.37:1935/live/djpdpc/playlist.m3u8 +邳州综合频道,http://stream.pznews.com/pztv1/sd/live.m3u8 +邳州综艺频道,http://stream.pznews.com/pztv2/sd/live.m3u8 +句容新闻综合,http://218.3.92.100:1937/live/jrxwzh/playlist.m3u8 +句容生活频道,http://218.3.92.100:1937/live/shenghuo/playlist.m3u8 +句容影视频道,http://218.3.92.100:1937/live/yingshi/playlist.m3u8 +睢宁综合频道,http://jssn.chinashadt.com:2036/live/1002.stream/playlist.m3u8 +睢宁生活教育,http://jssn.chinashadt.com:2036/live/1003.stream/playlist.m3u8 +睢宁三农频道,http://jssn.chinashadt.com:2036/live/1004.stream/playlist.m3u8 +睢宁资讯频道,http://jssn.chinashadt.com:2036/live/1005.stream/playlist.m3u8 +泰兴新闻频道,http://sj.smarttaixing.com:1935/live/_definst_/txzb/playlist.m3u8 +靖江新闻综合,http://visit.jjbctv.com:1935/live/xwzhmb/playlist.m3u8 +滨海新闻综合,http://jsbh.chinashadt.com:2036/live/bh11.stream/playlist.m3u8 +宝应新闻综合,http://jsby.chinashadt.com:2035/live/by1.stream/playlist.m3u8 +宝应生活资讯,http://jsby.chinashadt.com:2035/live/by2.stream/playlist.m3u8 +栖霞新闻频道,http://pili-live-hls.140.i2863.com/i2863-140/live_140_236499.m3u8 +抚州综合频道,http://111.75.179.195:30767/video/live_vide.m3u8 +萍乡新闻综合,http://www.pxitv.com:8099/hls-live/livepkgr/_definst_/pxitvevent/pxtv1stream.m3u8 +萍乡教育频道,http://www.pxitv.com:8099/hls-live/livepkgr/_definst_/pxitvevent/pxtv2stream.m3u8 +德兴新闻综合,http://218.64.168.174:5011/vod/hls/c01/live.m3u8 +袁州综合频道,http://jxyz.chinashadt.com:8036/live/yz1.stream/playist.m3u8 +永新电视一套,http://jxyx.chinashadt.com:2036/live/1002.stream/playlist.m3u8 +永新电视二套,http://jxyx.chinashadt.com:2036/live/1003.stream/playlist.m3u8 +万载综合频道,http://jxwz.chinashadt.com:2036/live/tv1.stream/playlist.m3u8 +吉林教育,http://stream1.jletv.cn/jljy/sd/live.m3u8 +通化新闻,http://stream2.jlntv.cn/tonghua1/sd/live.m3u8 +吉林市新闻综合,http://stream2.jlntv.cn/jilin1/sd/live.m3u8 +农安新闻综合,http://stream2.jlntv.cn/naxw/sd/live.m3u8 +鞍山图文频道,http://live2.asbctv.com:8134/hls-live/livepkgr/_definst_/liveevent/3GtPeVD2t6OWb3SFZxUQL6FW0X7ojmndKJS9fdRjpdhgB71.m3u8 +银川生活,http://stream.ycgbtv.com.cn/ycxw/sd/live.m3u8 +安多卫视,http://118.122.239.157:1235/hls/hd-live.m3u8 +海南州藏语频道,http://live.hnzzzzzdst.com/channel1/sd/live.m3u8 +海西州综合频道,http://stream.haixitv.cn/1/sd/live.m3u8 +西安新闻综合,http://stream2.xiancity.cn/xatv1/sd/live.m3u8 +西安白鸽都市,http://stream2.xiancity.cn/xatv2/sd/live.m3u8 +西安文化影视,http://stream2.xiancity.cn/xatv4/sd/live.m3u8 +西安丝路频道,http://stream2.xiancity.cn/xatv5/sd/live.m3u8 +枣庄教育频道,http://stream.zzgd.tv/2/sd/live.m3u8 +枣庄公共频道,http://stream.zzgd.tv/3/sd/live.m3u8 +东营综合频道,http://stream.hhek.cn/xwzh/sd/live.m3u8 +东营公共频道,http://stream.hhek.cn/ggpd/sd/live.m3u8 +东营科教频道,http://stream.hhek.cn/dyjy/sd/live.m3u8 +德州新闻频道,http://video.dztv.tv:1935/live/xwzh_gq/playlist.m3u8 +德州公共频道,http://video.dztv.tv:1935/live/dzgg_gq/playlist.m3u8 +德州图文频道,http://video.dztv.tv:1935/live/dztw_gq/playlist.m3u8 +滨州公共电视剧,http://stream.bzcm.net/1/sd/live.m3u8 +东昌导视频道,http://sddc.chinashadt.com:1936/live/gonggong.stream/playlist.m3u8 +新泰综合频道,http://live.xtgdw.cn:1935/live/xtzh/playlist.m3u8 +新泰乡村党建,http://live.xtgdw.cn:1935/live/xtxc/playlist.m3u8 +新泰影视频道,http://live.xtgdw.cn:1935/live/xtys/playlist.m3u8 +龙口新闻综合,http://yslk.chinashadt.com:1635/live/stream:di1.stream/playlist.m3u8 +龙口生活频道,http://yslk.chinashadt.com:1635/live/stream:di2.stream/playlist.m3u8 +莒县电视二套,http://61.162.225.122:8181/live/test2.m3u8 +莒县图文频道,http://61.162.225.122:8181/live/test3.m3u8 +无棣综合频道,http://sdwd.chinashadt.com:1935/live/wdzh.stream/playlist.m3u8 +无棣综艺频道,http://sdwd.chinashadt.com:1935/live/wdzy.stream/playlist.m3u8 +临朐新闻频道,http://sdlqx.chinashadt.com:2036/live/lqxw.stream/playlist.m3u8 +临朐先锋频道,http://sdlqx.chinashadt.com:2036/live/lqxf.stream/playlist.m3u8 +青州综合频道,http://sdqz.chinashadt.com:2036/live/stream:1.stream/playlist.m3u8 +青州文化旅游,http://sdqz.chinashadt.com:2036/live/stream:3.stream/playlist.m3u8 +山西科教,http://sxxx.chinashadt.com:2037/live/4.stream/playlist.m3u8 +临汾综合频道,http://sxxx.chinashadt.com:2037/live/1.stream/playlist.m3u8 +晋中新闻频道,http://jzlive.jztvnews.com:8092/live/jzzh.m3u8 +晋中公共频道,http://jzlive.jztvnews.com:8092/live/jzgg.m3u8 +隰县新闻综合,http://sxxx.chinashadt.com:2037/live/2.stream/playlist.m3u8 +交城电视台,http://sxjc.chinashadt.com:2036/live/stream:jctv.stream/playlist.m3u8 +临县电视台,http://sxlx.chinashadt.com:2036/live/stream:lxtv.stream/playlist.m3u8 +兴县综合频道,http://59.48.244.99:8098/hls/xx/playlist.m3u8 +泽州新闻综合,http://live.zzbctv.com/channel1/sd/live.m3u8 +西山电视台,http://218.26.97.12:5021/live_hls/1/c01.m3u8 +遂宁新闻综合,http://snlive.scsntv.com:8091/live/xwzh.m3u8 +德阳新闻综合,http://scdytv.com:1935/live/xwpd_livevideo/palylist.m3u8 +德阳公共频道,http://scdytv.com:1935/live/ggpd_livevideo/palylist.m3u8 +巴中综合频道,http://30814.hlsplay.aodianyun.com/lms_30814/tv_channel_246.m3u8 +巴中公共频道,http://30814.hlsplay.aodianyun.com/lms_30814/tv_channel_247.m3u8 +松潘新闻综合,http://111.231.197.215:85/live/spxwzh_600k.m3u8 +九寨沟新闻综合,http://111.231.194.231:85/live/xwzh.m3u8 +仁寿新闻综合,http://118.122.224.176:8091/live/xwzh.m3u8 +仁寿生活资讯,http://118.122.224.176:8091/live/shzx.m3u8 +宣汉新闻综合,http://60.255.77.232/1001/1001.m3u8 +宣汉城市公众,http://60.255.77.232/1000/1000.m3u8 +江油新闻综合,http://vod.scjygd.com:1935/live/smil:xwzh_copy.smil/playlist.m3u8 +江油文化教育,http://vod.scjygd.com:1935/live/smil:whjy_copy.smil/playlist.m3u8 +安州新闻频道,http://60.255.137.43:1936/aztvch1/playlist.m3u8 +安州电视剧频道,http://60.255.137.43:1936/aztvch2/playlist.m3u8 +绵竹新闻综合,http://pili-live-hls.66.i2863.com/i2863-66/live_66_404312.m3u8 +壤塘综合频道,http://118.122.239.157:1236/hls/hd-live.m3u8 +冕宁新闻频道,http://live.sichuanmianning.com/live/xwpd.m3u8 +峨边电视台,http://218.6.224.15:8011/vms/videos/channellive/channel15/playlist.m3u8 +西青新闻综合,http://221.238.209.44:81/hls/live1.m3u8 +博州汉语综合,http://klmyyun.chinavas.com/hls/bozhou1.m3u8 +博州维语综合,http://klmyyun.chinavas.com/hls/bozhou3.m3u8 +七师新闻综合,http://klmyyun.chinavas.com/hls/qishi1.m3u8 +七师电影频道,http://klmyyun.chinavas.com/hls/qishi4.m3u8 +美丽云南,http://www.ynbit.cn:1935/cyds-mlyn/livestream/playlist.m3u8 +红河州新闻综合,http://live.hhtv.cc:9099/ch1/ch1.m3u8 +红河州经济生活,http://live.hhtv.cc:9099/ch2/ch2.m3u8 +迪庆藏语,http://stream01.dqtv123.com:1935/live/diqingzangyu.stream/playlist.m3u8 +绥江综合频道,http://60.160.23.32:6055/sjtv/sjtv.m3u8 +个旧综合,http://live.hhtv.cc:9098/gjtv/gjtv.m3u8 +红河县综合,http://live.hhtv.cc:9099/hhtv/hhtv.m3u8 +河口综合,http://live.hhtv.cc:9098/hktv/hktv.m3u8 +屏边综合,http://live.hhtv.cc:9098/pbtv/pbtv.m3u8 +元阳综合,http://live.hhtv.cc:9098/yytv/yytv.m3u8 +金华教育科技,http://stream.jinhua.com.cn/jykj/app/live.m3u8 +金华公共频道,http://stream2.jinhua.com.cn/jjsh/app/live.m3u8 +金华都市农村,http://stream.jinhua.com.cn/dsnc/app/live.m3u8 +舟山新闻综合,http://live.wifizs.cn/xwzh/sd/live.m3u8 +舟山公共生活,http://live.wifizs.cn/ggsh/sd/live.m3u8 +湖州公共民生,http://live2.hzitv.cn/tslslive/z6NexHK/hls/live_sd.m3u8 +温州经济科教,http://hls.dhtv.cn:8080/live/v2_12.m3u8 +温州都市生活,http://hls.dhtv.cn:8080/live/v3_13.m3u8 +温州公共频道,http://hls.dhtv.cn:8080/live/v4_14.m3u8 +萧山新闻综合,http://l.cztvcloud.com/channels/lantian/SXxiaoshan1/720p.m3u8 +萧山生活频道,http://l.cztvcloud.com/channels/lantian/SXxiaoshan2/720p.m3u8 +余姚新闻综合,http://l.cztvcloud.com/channels/lantian/SXyuyao1/720p.m3u8 +余姚姚江文化,http://l.cztvcloud.com/channels/lantian/SXyuyao3/720p.m3u8 +嵊州新闻综合,http://l.cztvcloud.com/channels/lantian/SXshengzhou1/720p.m3u8 +上虞新闻综合,http://l.cztvcloud.com/channels/lantian/SXshangyu1/720p.m3u8 +上虞经济文化,http://l.cztvcloud.com/channels/lantian/SXshangyu2/720p.m3u8 +上虞新商都,http://l.cztvcloud.com/channels/lantian/SXshangyu3/720p.m3u8 +新昌新闻综合,http://l.cztvcloud.com/channels/lantian/SXxinchang1/720p.m3u8 +新昌休闲影视,http://l.cztvcloud.com/channels/lantian/SXxinchang2/720p.m3u8 +海宁新闻综合,http://stream.haining.tv/hnxw/sd/live.m3u8 +海宁生活服务,http://stream.haining.tv/hnfw/sd/live.m3u8 +东阳影视生活,http://stream.dybtv.com/yssh/GQ/live.m3u8 +象山新闻综合,http://v.xstv.net/hls-live/live/_definst_/liveevent/2222.m3u8 +嘉善新闻综合,http://116.62.31.234:1935/jsgdxwzh/myStream/playlist.m3u8 +嘉善善文化,http://116.62.31.234:1935/jsgdswh/myStream/playlist.m3u8 +玉林新闻综合,http://nsul01u0.live2.danghongyun.com/live/hls/a8481e33232641feab2f4086838cfdcc/aa6e95340e9e4b77838ab9c69b1a2ab5-1.m3u8 +来宾综合,http://nsul01u0.live2.danghongyun.com/live/hls/35498cf667d94533bdaaac01ad6f2d59/5eaf1d1d0bbb4b828accb0f621919c78-1.m3u8 +崇左综合,http://nsul01u0.live2.danghongyun.com/live/hls/6514b1f2f5ae40f394f1ffdf98dd9368/af28e67a42ef4a82861bad7c9f857eee-1.m3u8 +河池新闻综合,http://nsul01u0.live2.danghongyun.com/live/hls/876e00ef99d54cad81e61bf8e9df9042/1700882b40204bb1bd1694823abcf461-1.m3u8 +桂林综合,http://nsul01u0.live2.danghongyun.com/live/hls/845e3ad6a37e418294f2063fe286262a/4f64f11649524c2f8a870073f3a13eb8-1.m3u8 +贵港综合,http://nsul01u0.live2.danghongyun.com/live/hls/8c4dd3abb3394a199d2420aecc747d2e/a4e9f842e77b4450b82e5b13561bdcd9-1.m3u8 +钦州综合,http://live.gxqztv.com/cspd1/sd/live.m3u8 +贺州综合,http://nsul01u0.live2.danghongyun.com/live/hls/1e9f8ba8fc9c4f4e960b48a480087f73/20a6d959c051443d83e97a3cd5ff4292-1.m3u8 +柳州新闻综合,http://liveplay.lztvnet.com/live/31750_cc3fcb0f68b311e992905cb9018cf0d4.m3u8 +柳州科教,http://liveplay.lztvnet.com/live/31750_e1bbfc0b68b311e992905cb9018cf0d4.m3u8 +CGTV,http://39.135.36.140:18890/000000001000/8428799834696888424/1.m3u8?channel-id=ystenlive&Contentid=8428799834696888424&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=8428799834696888424&owchid=ystenlive&owsid=1106497909461789280&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7RqKDfJDas7YyDZNJl7HttN1saAiHHRx97PWslNR2vzkU1dWcTZfUtlvjMMZgBZvORGIuGa%2b7fRg7bV0%2fSlWh1 +金鹰纪实,http://39.135.36.158:18890/000000001000/1000000002000011724/1.m3u8?channel-id=ystenlive&Contentid=1000000002000011724&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000011724&owchid=ystenlive&owsid=1106497909461431848&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhGRixuNJLUNu2DBYpc6QsaE3%2flx5n8V0jfiNYU%2fTgbW1jSw07dYEaQMRlC6v1JMQu +金鹰卡通,http://39.135.36.143:18890/000000001000/1000000002000016601/1.m3u8?channel-id=ystenlive&Contentid=1000000002000016601&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000016601&owchid=ystenlive&owsid=1106497909461440110&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjh3lvQbkJR7yvxA1RDMtL0LOgZJUasCVca4o22xp7Fqo70%2bkmwxtIe5WPGbFPdTEWf +嘉佳卡通,http://39.135.36.158:18890/000000001000/1000000002000025964/1.m3u8?channel-id=ystenlive&Contentid=1000000002000025964&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000025964&owchid=ystenlive&owsid=1106497909461445399&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhTdKQ4wsazi%2bjWctAkM%2b3AyHZX%2bK23G5GXJY0zYdFr53ZLGcc%2fpaa0eBryrKOGOCn +哈哈炫动,http://39.135.36.141:18890/000000001000/1000000002000000172/1.m3u8?channel-id=ystenlive&Contentid=1000000002000000172&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000000172&owchid=ystenlive&owsid=1106497909461453987&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhWcrsHswwWp2dWLb8s5W8TNE0OJVYRjGF0bAUDhLlZ%2fS%2buYp9XTsbJzJ2IhAUAbXB +卡酷少儿,http://39.135.36.158:18890/000000001000/7589856436881630561/1.m3u8?channel-id=ystenlive&Contentid=7589856436881630561&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=7589856436881630561&owchid=ystenlive&owsid=1106497909461461523&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6w5tj6QNQmxgPk9QJsy7%2fzSWjcIgWGBaWYpmGQ1JTlRh0%2b1GDs%2b%2fmAEmuKcn81VSv8Jmm8qRlsJnY7A7xx1NX%2b +优漫卡通,http://39.135.36.157:18890/000000001000/1000000002000010063/1.m3u8?channel-id=ystenlive&Contentid=1000000002000010063&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000010063&owchid=ystenlive&owsid=1106497909461609150&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhtaBjjE4TN9WTWZSJCyB7q9lx71XBn28Da%2bdFI9LQTRkZjhTxMpgayQKIC2eH%2bMbL +CETV1,http://39.135.36.146:18890/000000001000/1000000002000027253/1.m3u8?channel-id=ystenlive&Contentid=1000000002000027253&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000027253&owchid=ystenlive&owsid=1106497909461616097&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhOJwKbFFUvff7rym6ZRGjqhoGIqpkmAjf48GP9I33YEiXzrp2cuKEymd6COk8Pa3q +山东教育,http://39.135.36.153:18890/000000001000/1000000002000004097/1.m3u8?channel-id=ystenlive&Contentid=1000000002000004097&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000004097&owchid=ystenlive&owsid=1106497909461623363&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhQh378KcG4gga4vRnyBidEMtSo4pdNiVnB7cAOBwj3CyvL3T5WhKfQVwdHIJjtMT4 +黑莓电影,http://39.135.36.141:18890/000000001000/8785669936177902664/1.m3u8?channel-id=ystenlive&Contentid=8785669936177902664&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=8785669936177902664&owchid=ystenlive&owsid=1106497909461631220&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6jEmjAMUGy0nIP6jSu%2f7L4kcrIRnbleOKJQFIG34oz%2fEDJYj1%2f6O12Q90SehwN9wSgbQeB4w7iizkqjoW2e%2b8f +黑莓动画,http://39.135.36.141:18890/000000001000/6497762188035533951/1.m3u8?channel-id=ystenlive&Contentid=6497762188035533951&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6497762188035533951&owchid=ystenlive&owsid=1106497909461636297&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7yuzV0ONj3jLJ3hwVkzsTuqbBS2aSqqFpaY6XZKMHRlKo8mmc3pY99jwkF3YYIQ9U6aewUh4Nwm0T2s2uo6zdq +广西卫视,http://39.135.36.158:18890/000000001000/1000000002000019837/1.m3u8?channel-id=ystenlive&Contentid=1000000002000019837&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000019837&owchid=ystenlive&owsid=1106497909461204271&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhsj2zH%2fW8kf2eLOhwcRnwEP0%2bGJue26Xi8vK8GznvuoMqhqMjEnqzE06kO4aZ9KPy +湖南卫视,http://39.135.36.153:18890/000000001000/1000000001000009115/1.m3u8?channel-id=ystenlive&Contentid=1000000001000009115&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000009115&owchid=ystenlive&owsid=1106497909461209970&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRJ1HPTMtmQf%2bVwcp8RojByB2Rhtn7waHVWUQ9gcJ0mHLEp3xuYtoWp3K%2bdNVn%2bMR4 +浙江卫视,http://39.135.36.146:18890/000000001000/1000000001000009806/1.m3u8?channel-id=ystenlive&Contentid=1000000001000009806&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000009806&owchid=ystenlive&owsid=1106497909461218392&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRt6tuEx40ruFSJnrbh2BVWwXsEFuvV04XsE9ZOm50Z8cpDzo0JrXSxYrVj73IVRt9 +上海卫视,http://39.135.36.143:18890/000000001000/1000000001000030202/1.m3u8?channel-id=ystenlive&Contentid=1000000001000030202&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000030202&owchid=ystenlive&owsid=1106497909461236159&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaR5IXgk%2b6a%2bY1Viivj30IkCl065X8GSWgqnbGOJH69GYNl9jXWqt3b3Vkm63dGSY%2b5 +江苏卫视,http://39.135.36.157:18890/000000001000/1000000001000004684/1.m3u8?channel-id=ystenlive&Contentid=1000000001000004684&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000004684&owchid=ystenlive&owsid=1106497909461243101&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaR80rubnSCCYHmxBfxTMKdNm%2bh%2bLn%2bBGibQYrxMgSwIzfH44Sn0OHT9L7pQFHxSW%2fJ +北京卫视,http://39.135.36.143:18890/000000001000/1000000001000017156/1.m3u8?channel-id=ystenlive&Contentid=1000000001000017156&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000017156&owchid=ystenlive&owsid=1106497909461249865&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRV7KOtBVuvtVZFLcgrBAOKYd9hOl8T7nV%2fYYLzxPrqZvxI1UedirhXiKrowSY0GL9 +天津卫视,http://39.135.36.157:18890/000000001000/1000000001000000831/1.m3u8?channel-id=ystenlive&Contentid=1000000001000000831&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000000831&owchid=ystenlive&owsid=1106497909461255731&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRcs9zLA6x183T6XfyDHK2Forh1U1TuZtCxYnIsImE91weAhYebQgGPi666EsPHwzC +广东卫视,http://39.135.36.155:18890/000000001000/1000000001000028357/1.m3u8?channel-id=ystenlive&Contentid=1000000001000028357&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000028357&owchid=ystenlive&owsid=1106497909461262352&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaROVzE3kgfqbxbWUefjzmwWM6UWM1tPF3fcVILxO8TukKPE2BY%2fTje83gAnl%2fZNkb%2b +珠江卫视,http://39.135.36.151:18890/000000001000/1000000004000011655/1.m3u8?channel-id=ystenlive&Contentid=1000000004000011655&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000004000011655&owchid=ystenlive&owsid=1106497909461268935&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4vNKx96%2bA3ppi2THlI0VlIDxwgnRBxQnnbWKTW8MTwvyEFUHTa6diXnUM1ACyB1BC6aNBSsOM3YI3qaHRRxYZp +南方卫视,http://39.135.36.155:18890/000000001000/1000000002000011619/1.m3u8?channel-id=ystenlive&Contentid=1000000002000011619&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000011619&owchid=ystenlive&owsid=1106497909461277024&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhqSWAN1gOHXiNCpzkzcaOmsTwp2DyZ40cRRIhpnuB%2bW%2b75qTM61EOp0nB4FGyoQIk +深圳卫视,http://39.135.36.150:18890/000000001000/1000000001000011645/1.m3u8?channel-id=ystenlive&Contentid=1000000001000011645&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000011645&owchid=ystenlive&owsid=1106497909461286475&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRi%2fGQBc72yY6Quo0JMFE7sAOH9P3BRKKjlume5S4R4Q4D5A%2fuxi3rN%2bHd%2bNxeQD8d +山东卫视,http://39.135.36.142:18890/000000001000/1000000001000012807/1.m3u8?channel-id=ystenlive&Contentid=1000000001000012807&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000012807&owchid=ystenlive&owsid=1106497909461291586&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaR3cBsIsjm7UHdGO3a4NjD1C4TiYtYt%2by66pvMI%2bkz57DAkgjzetftIzpJRR8RWa0K +湖北卫视,http://39.135.36.152:18890/000000001000/6956052407855047826/1.m3u8?channel-id=ystenlive&Contentid=6956052407855047826&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=6956052407855047826&owchid=ystenlive&owsid=1106497909461296919&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5Z%2bo9LRgIMhzyly%2bN8KnqBuGO27GhSxZzEXYI6euRzJ3HshWQhVCNxJrt91pPA8t7cjGpkhpIVoXJ0Jyemr0DA +安徽卫视,http://39.135.36.157:18890/000000001000/4774346722046993363/1.m3u8?channel-id=ystenlive&Contentid=4774346722046993363&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=4774346722046993363&owchid=ystenlive&owsid=1106497909461303710&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6rtwuCbF0UBw1ECKohiyVXtAaM2LAoJTgBkO9sqSP7vGKF4XQrqmpBPeC9CblENbpBoei4M1GZJUNAFlnpSFVM +东南卫视,http://39.135.36.154:18890/000000001000/1000000002000009263/1.m3u8?channel-id=ystenlive&Contentid=1000000002000009263&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000009263&owchid=ystenlive&owsid=1106497909461310172&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhM1XYZKCRYYY%2ff447%2bzETLijqfFgMTSA9x9T2lf3pyhagZIF%2fdE1lc49i65lODYA%2f +江西卫视,http://39.135.36.158:18890/000000001000/1000000001000013731/1.m3u8?channel-id=ystenlive&Contentid=1000000001000013731&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000013731&owchid=ystenlive&owsid=1106497909461316198&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRQxb4dqC07SZV%2bYcygMME6A9OMzcDPgMD6e%2f%2fHx5xyjuJRcCBeGZaKds6mdw4roN8 +四川卫视,http://39.135.36.152:18890/000000001000/1000000002000016825/1.m3u8?channel-id=ystenlive&Contentid=1000000002000016825&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000016825&owchid=ystenlive&owsid=1106497909461321397&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhwC686TkK%2f3k22PorZBLr8k69BtHofhbIyPVBrp9KppkHStTOpUrH7YEsmM6BR8Uo +贵州卫视,http://39.135.36.145:18890/000000001000/1000000002000003169/1.m3u8?channel-id=ystenlive&Contentid=1000000002000003169&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000003169&owchid=ystenlive&owsid=1106497909461328035&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhEobBU2fUvDIVr2YUAB3sQC3mtTDqCyM2IHfZcfgwbCVw3In3iCPMx3CBGKKivBM4 +重庆卫视,http://39.135.36.150:18890/000000001000/1000000002000018937/1.m3u8?channel-id=ystenlive&Contentid=1000000002000018937&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000018937&owchid=ystenlive&owsid=1106497909461333042&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhUG5grAC0rFEDUfNPlNhZzLoghzkGon0cjoqXWi7%2bGPbWnsToB9Z5BcGamUzvzuTi +海南卫视,http://39.135.36.145:18890/000000001000/7899627377857656087/1.m3u8?channel-id=ystenlive&Contentid=7899627377857656087&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=7899627377857656087&owchid=ystenlive&owsid=1106497909461339969&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5i%2fZjjyS5L6EOFFL3fbg69BynM9g1BjsNuzPfTl1pjliidPbwX2KKhA1G%2baZCwU1wvv%2b2csO1bRnJwTKoBnicl +河北卫视,http://39.135.36.146:18890/000000001000/1000000002000017118/1.m3u8?channel-id=ystenlive&Contentid=1000000002000017118&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000017118&owchid=ystenlive&owsid=1106497909461347463&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhCqGL1zPomfLadkujcaGzSGdRg4tEgiolyrwzgikVtMZiTQsF6T0wJRw9axwi4LXY +辽宁卫视,http://39.135.36.150:18890/000000001000/1000000002000024033/1.m3u8?channel-id=ystenlive&Contentid=1000000002000024033&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000024033&owchid=ystenlive&owsid=1106497909461352974&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhQBci%2f2KtFqbPb5lYHzQlehPnBUBV7gDU5NsQ1fq2DyLArxZhG%2bC4a49jTs%2bwbEKo +黑龙江卫视,http://39.135.36.140:18890/000000001000/8467838254824392379/1.m3u8?channel-id=ystenlive&Contentid=8467838254824392379&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=8467838254824392379&owchid=ystenlive&owsid=1106497909461358444&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5eLzTptYlaHwBbi5jFcfGGajSKACYh%2bxMIkH12jcM41WvzLTRYworzrZ3FKkyeJf%2fWTgBHYgXtjL76Tybav9u%2b +甘肃卫视,http://39.135.36.158:18890/000000001000/1000000002000017827/1.m3u8?channel-id=ystenlive&Contentid=1000000002000017827&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000017827&owchid=ystenlive&owsid=1106497909461366475&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhA4sBZEsqnSa3KvsIaVI9wPS8Gj6lJe1Zo41ze%2fWmzecpyT4Tmxoc1paT1vcrQhVS +青海卫视,http://39.135.36.147:18890/000000001000/1000000002000013359/1.m3u8?channel-id=ystenlive&Contentid=1000000002000013359&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000013359&owchid=ystenlive&owsid=1106497909461374163&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhJ4u8mZ9HohO4vJAcHWQKsu0WB2heV8z3%2bnCiQyrISnc%2fLQjwPdTUSlBahL%2bKNKpM +山西卫视,http://39.135.36.150:18890/000000001000/1000000002000021220/1.m3u8?channel-id=ystenlive&Contentid=1000000002000021220&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000021220&owchid=ystenlive&owsid=1106497909461381684&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhBGE2Bozg3VsjEsUfSwW1u%2f9d7qakC2cNwU6d3XLtivLzsKwupm4i1w5mp8nPnKP8 +云南卫视,http://39.135.36.157:18890/000000001000/1000000002000024694/1.m3u8?channel-id=ystenlive&Contentid=1000000002000024694&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000024694&owchid=ystenlive&owsid=1106497909461387812&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjh5LeWQtTPRcwTT4zmEXlA%2fwzvDSa%2fxaofg6Rpl19xhoQ1lNgovjV%2baMdiH1BrPHH%2b +陕西卫视,http://39.135.36.139:18890/000000001000/1000000002000007495/1.m3u8?channel-id=ystenlive&Contentid=1000000002000007495&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000007495&owchid=ystenlive&owsid=1106497909461393057&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhC1U23M2CL94H7Jl9UsXCcDV0kHzvpufT%2f4%2bgoUc31ou2LTka7qAY0hPTMutW5mQ%2b +吉林卫视,http://39.135.36.157:18890/000000001000/6042486520432105075/1.m3u8?channel-id=ystenlive&Contentid=6042486520432105075&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=6042486520432105075&owchid=ystenlive&owsid=1106497909461400661&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4zsyYJ9%2f94ZJUxUEiCPKz71GdIgOKPVNKAV5cZDiBiTfpeXwtOnUwYO06%2bu%2fL6TfF%2fffImHwCRpMFmrhzVqshX +宁愿卫视,http://39.135.36.150:18890/000000001000/1000000002000031451/1.m3u8?channel-id=ystenlive&Contentid=1000000002000031451&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000031451&owchid=ystenlive&owsid=1106497909461406396&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhdYL5WAeBmY961KZAiDk7oIQRwL3YBarKlFU8QNIToCi96iZhaB6NBJIISIjQ00jB +内蒙古卫视,http://39.135.36.138:18890/000000001000/1000000002000014080/1.m3u8?channel-id=ystenlive&Contentid=1000000002000014080&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000014080&owchid=ystenlive&owsid=1106497909461412819&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjhN3VZo%2fq60rUnbic%2fTx5hxEUA%2fCrpP4GEvV3vfXDDDKv4OC8OhxCTOd9DFYTiOuf7 +新疆卫视,http://39.135.36.146:18890/000000001000/1000000002000029441/1.m3u8?channel-id=ystenlive&Contentid=1000000002000029441&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=1000000002000029441&owchid=ystenlive&owsid=1106497909461419044&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5oj7lZFbEKIj3xJcvQPkjh5I4MdhcP3Mp5W80M2R4dfnt8vf6miKZMTn2f0J2ZVbDi2MMl6qImE0%2bmFOeDvrFW +西藏卫视,http://39.135.36.141:18890/000000001000/6603041244077933770/1.m3u8?channel-id=ystenlive&Contentid=6603041244077933770&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=bd8bb70bdb2b54bd84b587dffa024f7621vv&usergroup=g21077200000&version=1.0&owaccmark=6603041244077933770&owchid=ystenlive&owsid=1106497909461425998&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4rU4xzu091vKo8roYmr5h0BUDfpV78hsy2ysppzSDfUZCxoKss4LitbPhVYxcC0QN4CD2KiJutsirhMo3jfYAi +香港卫视,http://zhibo.hkstv.tv/livestream/mutfysrq/playlist.m3u8 +香港有线电视,http://cloud-play.hhalloy.com/live/390f07f18f550fb6e60c0c80264cdcc1.flv +星卫HD电影,http://cloud-play.hhalloy.com/live/41e05f3849c21412aa8b347f18adb3f6.flv +美亚电影,http://cloud-play.hhalloy.com/live/4a1141f101530bff4fc0e9229625e6b5.flv +CNN NEWS,http://cloud-play.hhalloy.com/live/5ff1924613169c0b7148e528d0cfe0fd.flv +SKY NEWS,http://cloud-play.hhalloy.com/live/64a4807c0cf482cffe922d7b8f091303.flv +NHK WORLD,http://cloud-play.hhalloy.com/live/1b06c6242b2fd17ab11a21d70abb2e67.flv +BBC World News,http://cloud-play.hhalloy.com/live/6d735caeaf70f8901aa00f86aefc4dde.flv +BBC Lifestyle,http://cloud-play.hhalloy.com/live/5e80f4a9e17c991df381030c65856687.flv +BBC earth,http://cloud-play.hhalloy.com/live/f7146ac8e65cb75112431f87ddcea22e.flv +FOX News,http://cloud-play.hhalloy.com/live/b78a7c4f460285596b53bfa802eca8e8.flv +FOX HD,http://cloud-play.hhalloy.com/live/c2c91afe09bad325929734624c19d07b.flv +FOX SPORTS[HD],http://cloud-play.hhalloy.com/live/b00b46e382e81efd9902a848c9b89101.flv +FOX SPORTS2[HD],http://cloud-play.hhalloy.com/live/a726b0d8db38a23435c5c3ba95507d3e.flv +FOX SPORTS3,http://cloud-play.hhalloy.com/live/1a4ff6880b679dd340e42a9b61fe2d9f.flv +FOX MOVIES[HD],http://cloud-play.hhalloy.com/live/b3d2208824d1ca27dad3068e376ab557.flv +FOX CRIME,http://cloud-play.hhalloy.com/live/833d6cdeed807b755e6c449832b26621.flv +HBO HD,http://cloud-play.hhalloy.com/live/13e83b20bc716e68221da438d761d352.flv +HBO Hits,http://cloud-play.hhalloy.com/live/c971b59822c6a91fab4bad8ca9b45f6b.flv +HBO Signature,http://cloud-play.hhalloy.com/live/fcdd3a3c591bdd0b07a17a92cb555cc1.flv +HBO Family,http://cloud-play.hhalloy.com/live/7e7ed5cc99029fd0d27e25009d7abdac.flv +Discovery Asia,http://cloud-play.hhalloy.com/live/f325e0ce8ddf55c2df916b6f2bc0e07c.flv +Discovery[HD],http://cloud-play.hhalloy.com/live/ef2748398207873cae12b151ae78b0af.flv +Discovery科学[HD],http://cloud-play.hhalloy.com/live/f82bcb85f1a67e5b4754f7be0661dc72.flv +Channel V,http://cloud-play.hhalloy.com/live/c8ade260941e368acfdb110a04811b3e.flv +MTV Live,http://cloud-play.hhalloy.com/live/116911efa30e70c9cf64ea9a0e990a05.flv +DWTV,http://cloud-play.hhalloy.com/live/a4aa25e01a432729323f4d0778605887.flv +TVN,http://cloud-play.hhalloy.com/live/060e39b20b7616170ba4ba63c53bc336.flv +Channel V,http://cloud-play.hhalloy.com/live/c8ade260941e368acfdb110a04811b3e.flv +TVBS欢乐台[HD],http://cloud-play.hhalloy.com/live/5e81e3b3e2d8b887db0bc2976558c7ea.flv +TVBS[HD],http://cloud-play.hhalloy.com/live/f94be038bca84147bbf132d8ddd9bb39.flv +卫视中文台[HD],http://cloud-play.hhalloy.com/live/a08a123b4af3aebb4e19b82f64952c9e.flv +TVB 翡翠台,http://cloud-play.hhalloy.com/live/b3a93cbbd1908e81783879747bb3090a.flv +TVB J2,http://cloud-play.hhalloy.com/live/9de1ac6a9a4642e1aac41462c6159b92.flv +新加坡亚洲新闻台,http://cloud-play.hhalloy.com/live/1aab6cf57296bdefc6f4bea94702782a.flv +中视新闻[HD],http://cloud-play.hhalloy.com/live/cf4d66edc142b2f0cc8c71bca56b2268.flv +纬来育乐[HD],http://cloud-play.hhalloy.com/live/5cd65f73313b022253084c489a6705c8.flv +中天娱乐[HD],http://cloud-play.hhalloy.com/live/25ea449d554a16ec584e82d039065e5f.flv +东森超视[HD],http://cloud-play.hhalloy.com/live/47d46d26bba55dd674454ad46c569ffa.flv +韩国娱乐台,http://cloud-play.hhalloy.com/live/8ae61414f7e2972598956105e2e9969d.flv +星卫娱乐,http://cloud-play.hhalloy.com/live/4c3c2a7fe5ffc33e45bca04f983f02b0.flv +寰宇综合,http://cloud-play.hhalloy.com/live/82b78befe54a601876654e1db3e3741a.flv +爱尔达综合,http://cloud-play.hhalloy.com/live/c614a26c0e0fb521c5cdfa10ed7f2089.flv +ET综合台,http://cloud-play.hhalloy.com/live/f6e19af652637cfde3c0f5d34822b4b5.flv +靖天资讯,http://cloud-play.hhalloy.com/live/e81342a5e0ecde1ee634f19b50fab501.flv +靖天综合,http://cloud-play.hhalloy.com/live/7a7b662db65f478451144355efa0f02b.flv +公视[HD],http://cloud-play.hhalloy.com/live/0be9e52678b937320897033d90bb268a.flv +公视3[HD],http://cloud-play.hhalloy.com/live/514590fdb3ba8e3f2c3a15dd13037f31.flv +台视[HD],http://cloud-play.hhalloy.com/live/bec346d29d4c665d04db41d28a4e033f.flv +台视综合,http://cloud-play.hhalloy.com/live/a8905b7e88b656b83c0f5d8bf5771430.flv +华视[HD],http://cloud-play.hhalloy.com/live/0bdf94d7f68fe3ece32048144cbf9a23.flv +中视[HD],http://cloud-play.hhalloy.com/live/318e4839a23f9ff15e327de9bcb31687.flv +霹雳台湾台[HD],http://cloud-play.hhalloy.com/live/14b736ee363e84918a8c43c69691faaa.flv +Hakkatv[HD],http://cloud-play.hhalloy.com/live/9535868a6a173399d3913cab3bb61675.flv +TITV原住民电视台[HD],http://cloud-play.hhalloy.com/live/8f44c933620b603a874a18ed1bb9a033.flv +LIFE TIME,http://cloud-play.hhalloy.com/live/d8ab211a4f23fe8e143757d13ade9b32.flv +TRACE Sports,http://cloud-play.hhalloy.com/live/3b88f91a420e6cd59cd034ccf2a05c10.flv +八大综合[HD],http://cloud-play.hhalloy.com/live/a26d25ad9eaabca42fa6d526199d61e5.flv +东风37台,http://cloud-play.hhalloy.com/live/0b2e19ee2374470b5dede1013afcb4b5.flv +三立台湾台[HD],http://cloud-play.hhalloy.com/live/e71635b53bb874a085b2a469802bbc81.flv +三立都会台[HD],http://cloud-play.hhalloy.com/live/4abe46a5faf4865e251ac981287a6e20.flv +年代MUCH[HD],http://cloud-play.hhalloy.com/live/3d20cf4de65aadb4d2b2e30ad3974750.flv +JET综合[HD],http://cloud-play.hhalloy.com/live/c4fcaea7013c6b1d6aef9f1d0e99871e.flv +FOX HD,http://cloud-play.hhalloy.com/live/c2c91afe09bad325929734624c19d07b.flv +高点综合[HD],http://cloud-play.hhalloy.com/live/f11ea1c1918059c58b42c637fa9dc678.flv +公视2,http://cloud-play.hhalloy.com/live/236c80ba515e5bf302f3db6f4d009914.flv +亚洲综合,http://cloud-play.hhalloy.com/live/8e08d22adcc7748ceedc31006b55f7de.flv +中视经典,http://cloud-play.hhalloy.com/live/75249ac8b464466a9c41c669bd27260a.flv +靖天戏剧,http://cloud-play.hhalloy.com/live/4c3b3fa6235fce99e794a16e096c2e1b.flv +龙华戏剧,http://cloud-play.hhalloy.com/live/b40ec839440a97d24d0aee0c69d186a1.flv +龙华偶像,http://cloud-play.hhalloy.com/live/046d62141df9366aa54a66b22e095e24.flv +八大戏剧[HD],http://cloud-play.hhalloy.com/live/6d7d7a9c22ba9aa4e411e3f7567763d8.flv +Warner TV,http://cloud-play.hhalloy.com/live/a645bdeafb1216c23352144c3505bd8c.flv +AXN,http://cloud-play.hhalloy.com/live/c762110b3eef8bcccce5863643dd66aa.flv +彩昌影剧台,http://cloud-play.hhalloy.com/live/b93ac92b703885f3cfe39bad8aa689d1.flv +BLUE ANT EXTREME,http://cloud-play.hhalloy.com/live/7b3b2e1d0006091415635226a2ac5d86.flv +BLUE ANT ENTERTAINMET,http://cloud-play.hhalloy.com/live/41005bf306743766c5affb055bc5c164.flv +EYE TV戏剧台,http://cloud-play.hhalloy.com/live/69a400e45b6fbd61c8182736ec80e013.flv +HITS[HD],http://cloud-play.hhalloy.com/live/e6d6d3927102ce6e0e99187b52946497.flv +东森戏剧[HD],http://cloud-play.hhalloy.com/live/17cdea424a288175c834060c58b3bb4e.flv +龙华影剧,http://cloud-play.hhalloy.com/live/d2e1d697b31906f91d7e19a5f06f64ed.flv +三立戏剧,http://cloud-play.hhalloy.com/live/bdc9e5f7487003c20223fd67f25c7ee7.flv +非凡新闻[HD],http://cloud-play.hhalloy.com/live/408a2834f703f2162d0d5b5789344c39.flv +TV5 MONDE,http://cloud-play.hhalloy.com/live/a9dd7099d0abf47c5e17f8038234df22.flv +CNN NEWS,http://cloud-play.hhalloy.com/live/5ff1924613169c0b7148e528d0cfe0fd.flv +东森新闻[HD],http://cloud-play.hhalloy.com/live/b237f97b0e9e21e88e0bdaae40730332.flv +东森财经新闻[HD],http://cloud-play.hhalloy.com/live/10e21c98ff74745141a386d91da24c56.flv +中天新闻[HD],http://cloud-play.hhalloy.com/live/e1a397539e76f45bbbf39d1467024aa3.flv +FOX News,http://cloud-play.hhalloy.com/live/b78a7c4f460285596b53bfa802eca8e8.flv +SKY NEWS,http://cloud-play.hhalloy.com/live/64a4807c0cf482cffe922d7b8f091303.flv +NHK WORLD,http://cloud-play.hhalloy.com/live/1b06c6242b2fd17ab11a21d70abb2e67.flv +寰宇新闻2台,http://cloud-play.hhalloy.com/live/0d192b1fb482857fb4694a12c2718302.flv +BBC World News,http://cloud-play.hhalloy.com/live/6d735caeaf70f8901aa00f86aefc4dde.flv +靖天映画,http://cloud-play.hhalloy.com/live/4364abb0a9f358049a535f4692cd49b5.flv +靖天电影,http://cloud-play.hhalloy.com/live/5634d5c8ee5afeb118df8decf5eb6c56.flv +FOX MOVIES[HD],http://cloud-play.hhalloy.com/live/b3d2208824d1ca27dad3068e376ab557.flv +CINEMAX,http://cloud-play.hhalloy.com/live/9bece52b2f72795cc2f588f3d9e4eed3.flv +壹电影,http://cloud-play.hhalloy.com/live/eb53b692ccbe8c836bc20be6734a9555.flv +纬来电影,http://cloud-play.hhalloy.com/live/4f10b67646969a422a5490deaaabbc69.flv +东森电影[HD],http://cloud-play.hhalloy.com/live/d2325cfdfd53364263d307573f78e3ce.flv +东森洋片[HD],http://cloud-play.hhalloy.com/live/24b15906d2250c062c0f0b5339e166b2.flv +龙华电影,http://cloud-play.hhalloy.com/live/0e5dee9e8021ce3b9ec9bb78e9710555.flv +龙华经典,http://cloud-play.hhalloy.com/live/669a67f26ad4b9f68664bfcaefc9553e.flv +龙华洋片,http://cloud-play.hhalloy.com/live/b7829653660ec5e84c70e7f3a01e1e6c.flv +好莱坞电影[HD],http://cloud-play.hhalloy.com/live/8e678565884cdebd00f8b3121b3b7ee1.flv +影迷纪实台,http://cloud-play.hhalloy.com/live/a1d2d2be053776bb01c1aac37ac2dee4.flv +CatchPlay电影台,http://cloud-play.hhalloy.com/live/65e80e1e0cd763a0302d7aa2a1135b0b.flv +HBO Hits,http://cloud-play.hhalloy.com/live/c971b59822c6a91fab4bad8ca9b45f6b.flv +HBO Signature,http://cloud-play.hhalloy.com/live/fcdd3a3c591bdd0b07a17a92cb555cc1.flv +HBO Family,http://cloud-play.hhalloy.com/live/7e7ed5cc99029fd0d27e25009d7abdac.flv +LS TIME龙祥电影,http://cloud-play.hhalloy.com/live/a5da9875c963d704ac5dd8f866869723.flv +卫视电影台,http://cloud-play.hhalloy.com/live/4499fb1dcef8c7a9f64276bf71bfc5b4.flv +博斯高球1[HD],http://cloud-play.hhalloy.com/live/4870a14ca0496e434825594643eea173.flv +博斯高球2[HD],http://cloud-play.hhalloy.com/live/9dd0941038e16fd8207f4c485c2fd34b.flv +博斯魅力[HD],http://cloud-play.hhalloy.com/live/906ff5c1e590fdc0f41744077f56672a.flv +博斯无限[HD],http://cloud-play.hhalloy.com/live/8c9a98717ee9e5136636c3bedbb852b8.flv +博斯网球[HD],http://cloud-play.hhalloy.com/live/cf415a2419c61638eefa5eb8c5a65922.flv +博斯运动2[HD],http://cloud-play.hhalloy.com/live/c71aa3f9ef9e92531a06863b9a731849.flv +博斯运动1[HD],http://cloud-play.hhalloy.com/live/1cebe1e25e9c69e2ed2e1e6012aeb2d3.flv +FOX SPORTS[HD],http://cloud-play.hhalloy.com/live/b00b46e382e81efd9902a848c9b89101.flv +FOX SPORTS2[HD],http://cloud-play.hhalloy.com/live/a726b0d8db38a23435c5c3ba95507d3e.flv +欧洲体育[HD],http://cloud-play.hhalloy.com/live/96681c92588f5254e1c9f8fcb41e9d64.flv +ELEVVEN SPORTS PLUS,http://cloud-play.hhalloy.com/live/b599c0682fbb5364078cb9e3093228a6.flv +ELEVVEN SPORTS 2,http://cloud-play.hhalloy.com/live/94283c6401f80334d9acd488b649830b.flv +FOX SPORTS 3,http://cloud-play.hhalloy.com/live/1a4ff6880b679dd340e42a9b61fe2d9f.flv +纬来体育[HD],http://cloud-play.hhalloy.com/live/464311a99c6465a1f36681b73c62fa83.flv +智林体育台,http://cloud-play.hhalloy.com/live/12b7289a05d4cb3c2b79f38b030e2548.flv +靖洋卡通,http://cloud-play.hhalloy.com/live/8fa63f69fe90ce0597aa6d4b7c262810.flv +MOMO亲子台,http://cloud-play.hhalloy.com/live/0c795e6e7f8e067dd4110a57375a71b9.flv +CN卡通,http://cloud-play.hhalloy.com/live/c865782e4a131efe17651165835ca37e.flv +ANIMAX,http://cloud-play.hhalloy.com/live/33de03293563010671a856688d63d4ee.flv +迪斯尼卡通,http://cloud-play.hhalloy.com/live/198038b134ad459d9cc251038c74685a.flv +梦工厂动画,http://cloud-play.hhalloy.com/live/aae9c139f056e6c003448ba1e4908ee3.flv +I-FUN动漫台,http://cloud-play.hhalloy.com/live/9cd9d87c4ccbf7f28284990a1c3d4569.flv +曼迪日本台,http://cloud-play.hhalloy.com/live/d9445086fd2dd474087674f638f2a8ed.flv +BabyTV,http://cloud-play.hhalloy.com/live/d7ede3e748413a7ad065d29dbe542149.flv +Babyfirst,http://cloud-play.hhalloy.com/live/efd423af0e64fd82c1cc29e909eb4303.flv +My kids,http://cloud-play.hhalloy.com/live/9bb01fa9902e14cd5811f5474283171b.flv +NICK 卡通,http://cloud-play.hhalloy.com/live/a81b6e417028b6d72ed3e6ee7c42619b.flv +东森幼幼[HD],http://cloud-play.hhalloy.com/live/0c0a03db510687f73c455afcc220386b.flv +龙华动画,http://cloud-play.hhalloy.com/live/4a3c4fbd39ddf82979cf3ecf3cd942c8.flv +靖天卡通,http://cloud-play.hhalloy.com/live/6bbfbe0fb0dc5ce3f8db00d8fae9ae5c.flv +ANIMAX HD,http://cloud-play.hhalloy.com/live/13b6c6ecbb388c105fd9d98338162abb.flv +寰宇财经,http://cloud-play.hhalloy.com/live/77c9bab3af161386df16ad9d8a3f3541.flv +台视财经,http://cloud-play.hhalloy.com/live/c5d061725e49943973c43a404b913f17.flv +Bloombreg TV,http://cloud-play.hhalloy.com/live/ab2450af4c80b52d0810eceaf055abee.flv +NewTV古装,http://39.135.36.150:18890/000000001000/6859053933687922163/1.m3u8?channel-id=ystenlive&Contentid=6859053933687922163&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6859053933687922163&owchid=ystenlive&owsid=1106497909461643183&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7rI6cyOBdMQcbb7pGYvKkkE4PU3Zf45kDZim939dEFvAtUmU8crfqEUv5zpewkRlr9zZahSqXGjBKN9OvmeMwv +NewTV动作,http://39.135.36.146:18890/000000001000/8103864434730665389/1.m3u8?channel-id=ystenlive&Contentid=8103864434730665389&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=8103864434730665389&owchid=ystenlive&owsid=1106497909461651262&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6gc5lrV9LORe1gi%2brvWfZqjqWg5r9sHf%2bhUiRSDpBuWg5lRQBeU9YctiSzPH6gfVkWNbz7C4olsbRCQkf1hNrZ +NewTV军旅,http://39.135.36.156:18890/000000001000/7485075951068666323/1.m3u8?channel-id=ystenlive&Contentid=7485075951068666323&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=7485075951068666323&owchid=ystenlive&owsid=1106497909461660587&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7gYwRY3Wxxxjm4eCFATbicSFfA3OO5y8oXZJsD0pdpNF5XUqv6ZoXjgdtsapPA003lukcFW5PcqCPu9LmSAwaU +NewTV家庭,http://39.135.36.154:18890/000000001000/6316377948248689070/1.m3u8?channel-id=ystenlive&Contentid=6316377948248689070&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6316377948248689070&owchid=ystenlive&owsid=1106497909461667557&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4ZwpjUZzRJ311OOUZgk%2fdzXH6qIpYr0YPi6NvoFlPR1BKc5nFG3fYCgRA5KoFSBO69EQ0AB6jYRoTGtX%2bXoSmh +NewTV惊悚,http://39.135.36.153:18890/000000001000/7151256057701199617/1.m3u8?channel-id=ystenlive&Contentid=7151256057701199617&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=7151256057701199617&owchid=ystenlive&owsid=1106497909461673183&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7WcU4uUemDr%2bvU%2bvnnf3N5iO4bkU4W0ueDoorDr5ibxhAm%2f7T1v8XBQNX%2bapKXQ2%2fK9yjYdVWnw2Bihh8x%2bgGK +NewTV海外,http://39.135.36.138:18890/000000001000/7681593242002292003/1.m3u8?channel-id=ystenlive&Contentid=7681593242002292003&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=7681593242002292003&owchid=ystenlive&owsid=1106497909461684320&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6duq37iJuE%2fAq4jgKsH77XOP4Et6zhgVTiPZi9lOHM23AIuPDem5ywKZGTAm3ZYV4bg0FTwS32NZpO0MD9F11W +NewTV搏击,http://39.135.36.154:18890/000000001000/bokesen/1.m3u8?channel-id=ystenlive&Contentid=bokesen&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=bokesen&owchid=ystenlive&owsid=1106497909461689613&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7tWwcJ9gAtxn4aPYIw71ppLozLIK9YQrvbqFru4XbE8FIhvh4VgXNnv8f9IP4gfSA%3d +NewTV明星大片,http://39.135.36.143:18890/000000001000/5595720619887440144/1.m3u8?channel-id=ystenlive&Contentid=5595720619887440144&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=5595720619887440144&owchid=ystenlive&owsid=1106497909461695855&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE6YXxE0nCCxd3dck4q0SwSBlg2o%2fvyI82ry5doiaWJPH9u%2fHCOos%2ffJGJ56Qg2QVr1cCX3bbMrMBnTh%2bHCkuVIP +NewTV爱情喜剧,http://39.135.36.152:18890/000000001000/8393829412396288037/1.m3u8?channel-id=ystenlive&Contentid=8393829412396288037&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=8393829412396288037&owchid=ystenlive&owsid=1106497909461701287&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4y7uVHwAxWluJXzuOABih3FGGfr%2bsJzle%2bv7q7mmo7sH%2b2t%2bWjDtNUzUdL8QTk%2bIUtEVXTAMGlgOpmFrzdrKNl +NewTV精品大剧,http://39.135.36.147:18890/000000001000/7882297361445410858/1.m3u8?channel-id=ystenlive&Contentid=7882297361445410858&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=7882297361445410858&owchid=ystenlive&owsid=1106497909461708013&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4G3gHhbopAXv1%2bwSMC13LXLIuhzr0myUm7odTYlfUIkKrQcNEkHc7TnPLGe1r4%2bIX7AhIXtKagjAfjVTqFHQE4 +NewTV功夫,http://39.135.36.155:18890/000000001000/5897056882324761054/1.m3u8?channel-id=ystenlive&Contentid=5897056882324761054&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=5897056882324761054&owchid=ystenlive&owsid=1106497909461714898&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7F7WgeLO%2bfyIWPYXQQMhNtCo5WrxR%2bhkEBJzZk8A5S%2bUclQim%2ffZXtk%2bP4F8ROcQNAlQJtGhciSrbmmnbiZQWc +NewTV金牌综艺,http://39.135.36.140:18890/000000001000/6399725674632152632/1.m3u8?channel-id=ystenlive&Contentid=6399725674632152632&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6399725674632152632&owchid=ystenlive&owsid=1106497909461719323&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE4gyKcpvop%2bJI182Bs2kqZG345lJmBteJiRcq6kB86C9F3lxBSs1xa6%2bdgOwB1WRIKDdF3P8H%2bLGMiwAhepZKru +NewTV军事评论,http://39.135.36.151:18890/000000001000/5822616274253344775/1.m3u8?channel-id=ystenlive&Contentid=5822616274253344775&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=5822616274253344775&owchid=ystenlive&owsid=1106497909461724106&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7%2baKbhkowsYIbIX%2fDf65zZplfMot6mRkOGBkot%2bjE4A8Wm%2bKVEkV%2fcPOkvsemBIenlZSBuNy85BFE%2b0UBbzIgQ +NewTV农业致富,http://39.135.36.147:18890/000000001000/6193684637634073625/1.m3u8?channel-id=ystenlive&Contentid=6193684637634073625&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6193684637634073625&owchid=ystenlive&owsid=1106497909461729529&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7wjRXywerl7HoD%2bJ8krwUOzhLEwHQymxgjBufQTPa%2bdlXx%2bGBQLAIX%2bfssQZb%2fjX3XANYjuYXkdYX5N1o%2b7hmV +NewTV精品记录,http://39.135.36.156:18890/000000001000/6298506997017621594/1.m3u8?channel-id=ystenlive&Contentid=6298506997017621594&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6298506997017621594&owchid=ystenlive&owsid=1106497909461739335&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5Z%2fEzyUAZDVIPoiwNPLYgjJvkohoXFTsC5VYOGHUU7RlueMvRrGKmSZC%2bNKYW4Mlhq%2bt9ZsVsg39%2bFutggbU%2f7 +NewTV健康有约,http://39.135.36.155:18890/000000001000/7820874641606664941/1.m3u8?channel-id=ystenlive&Contentid=7820874641606664941&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=7820874641606664941&owchid=ystenlive&owsid=1106497909461745819&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE5qWkmkT2TXMLlfHzXJDPRjWZjitMMZdXIPlgQOHqalAjnZ%2bnAyI8gVeuqRanEvNgZ6w0N1hxkH6zHVX54bK3KE +NewTV精品体育,http://39.135.36.157:18890/000000001000/6460382139625130259/1.m3u8?channel-id=ystenlive&Contentid=6460382139625130259&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6460382139625130259&owchid=ystenlive&owsid=1106497909461751360&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7bXyHXx9pcAUwTaLb5AbAmkHYZnpwVd9P8mvmphlj1JalYdRW8FBsCqY%2f8wxvQntk%2bssuunsLwIBwjlBeIJxeC +NewTV潮妈辣婆,http://39.135.36.147:18890/000000001000/6516734029835465177/1.m3u8?channel-id=ystenlive&Contentid=6516734029835465177&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=6516734029835465177&owchid=ystenlive&owsid=1106497909461757416&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7lpjlDkCigeV92%2fGgzDbl17YJnmK%2bNapvzR3hZbQitGUDQ%2f2RfKI5ienTpN%2bdmcS6qzJsR4R%2fYKs50I6pDfn83 +NewTV炫舞未来,http://39.135.36.157:18890/000000001000/1000000001000000515/1.m3u8?channel-id=ystenlive&Contentid=1000000001000000515&livemode=1&stbId=005203FF000360100001001A34C0CD33&userToken=4ef1f6fdd53988bdf19472c73151206f21vv&usergroup=g21077200000&version=1.0&owaccmark=1000000001000000515&owchid=ystenlive&owsid=1106497909461764488&AuthInfo=yOLXJswzZFfV3FvB8MhHuElKGJKLbU5H0jB3qAhfSE7AORAoVDZDWbFnJ0sXJEaRNwKLc81VtMnWmF2ZM43fEHzlD22rx2n%2flxPrsDq9A4qonSPaCT%2bEq8mzJT5jo5U4 +TVB 翡翠台,http://cloud-play.hhalloy.com/live/b3a93cbbd1908e81783879747bb3090a.flv +TVB 星河,http://cloud-play.hhalloy.com/live/e70f35708baededbbd1d0963f76981a1.flv +TVB 功夫,http://cloud-play.hhalloy.com/live/cfd2b3912b756d6d4965f018fd7d3717.flv +TVB 明珠台,http://cloud-play.hhalloy.com/live/e5b375085720fd04cec615352224b493.flv +TVB J2,http://cloud-play.hhalloy.com/live/9de1ac6a9a4642e1aac41462c6159b92.flv +香港有线电视603,http://cloud-play.hhalloy.com/live/390f07f18f550fb6e60c0c80264cdcc1.flv +居家幸福,http://cloud-play.hhalloy.com/live/891dfa401663622b29ab70c16ea2273e.flv +TVBS[HD],http://cloud-play.hhalloy.com/live/f94be038bca84147bbf132d8ddd9bb39.flv +TVBS精彩台,http://cloud-play.hhalloy.com/live/15379cc75ee0fb41ab2fb3a11f3d909f.flv +TVBS欢乐台[HD],http://cloud-play.hhalloy.com/live/5e81e3b3e2d8b887db0bc2976558c7ea.flv +公视[HD],http://cloud-play.hhalloy.com/live/0be9e52678b937320897033d90bb268a.flv +公视2,http://cloud-play.hhalloy.com/live/236c80ba515e5bf302f3db6f4d009914.flv +公视3[HD],http://cloud-play.hhalloy.com/live/514590fdb3ba8e3f2c3a15dd13037f31.flv +台视[HD],http://cloud-play.hhalloy.com/live/bec346d29d4c665d04db41d28a4e033f.flv +台视综合,http://cloud-play.hhalloy.com/live/a8905b7e88b656b83c0f5d8bf5771430.flv +华视[HD],http://cloud-play.hhalloy.com/live/0bdf94d7f68fe3ece32048144cbf9a23.flv +中视[HD],http://cloud-play.hhalloy.com/live/318e4839a23f9ff15e327de9bcb31687.flv +中视经典,http://cloud-play.hhalloy.com/live/75249ac8b464466a9c41c669bd27260a.flv +中天娱乐[HD],http://cloud-play.hhalloy.com/live/25ea449d554a16ec584e82d039065e5f.flv +中天综合,http://cloud-play.hhalloy.com/live/64ce4daa355bd6784904e72fabb7fa3e.flv +中天新闻[HD],http://cloud-play.hhalloy.com/live/e1a397539e76f45bbbf39d1467024aa3.flv +靖天国际,http://cloud-play.hhalloy.com/live/cbd38069eb1e8b2c04e356c22baac506.flv +靖天映画,http://cloud-play.hhalloy.com/live/4364abb0a9f358049a535f4692cd49b5.flv +靖天电影,http://cloud-play.hhalloy.com/live/5634d5c8ee5afeb118df8decf5eb6c56.flv +靖天戏剧,http://cloud-play.hhalloy.com/live/4c3b3fa6235fce99e794a16e096c2e1b.flv +靖天育乐,http://cloud-play.hhalloy.com/live/b4b4eb536ffc346864d2dcc03adedd85.flv +靖天欢乐,http://cloud-play.hhalloy.com/live/4da43dff7cd731ffb9bbe9a85b029536.flv +靖天日本,http://cloud-play.hhalloy.com/live/031b3e399e9530310abc135a0b19a8ac.flv +靖天资讯,http://cloud-play.hhalloy.com/live/e81342a5e0ecde1ee634f19b50fab501.flv +靖天综合,http://cloud-play.hhalloy.com/live/7a7b662db65f478451144355efa0f02b.flv +东森电影[HD],http://cloud-play.hhalloy.com/live/d2325cfdfd53364263d307573f78e3ce.flv +东森洋片[HD],http://cloud-play.hhalloy.com/live/24b15906d2250c062c0f0b5339e166b2.flv +东森戏剧[HD],http://cloud-play.hhalloy.com/live/17cdea424a288175c834060c58b3bb4e.flv +东森超视[HD],http://cloud-play.hhalloy.com/live/47d46d26bba55dd674454ad46c569ffa.flv +东森综合[HD],http://cloud-play.hhalloy.com/live/7485194388c0ca1d43a664701afb2ff2.flv +东森新闻[HD],http://cloud-play.hhalloy.com/live/b237f97b0e9e21e88e0bdaae40730332.flv +东森财经新闻[HD],http://cloud-play.hhalloy.com/live/10e21c98ff74745141a386d91da24c56.flv +DIVA,http://cloud-play.hhalloy.com/live/2ff14655a982c6d2be2a8b0c5649d257.flv +HBO HD,http://cloud-play.hhalloy.com/live/13e83b20bc716e68221da438d761d352.flv +HBO Hits,http://cloud-play.hhalloy.com/live/c971b59822c6a91fab4bad8ca9b45f6b.flv +HBO Signature,http://cloud-play.hhalloy.com/live/fcdd3a3c591bdd0b07a17a92cb555cc1.flv +HBO Family,http://cloud-play.hhalloy.com/live/7e7ed5cc99029fd0d27e25009d7abdac.flv +福克斯家庭影院,http://cloud-play.hhalloy.com/live/440b3d3c474813d7ead7d3a795978e69.flv +FOX MOVIES[HD],http://cloud-play.hhalloy.com/live/b3d2208824d1ca27dad3068e376ab557.flv +FX HD,http://cloud-play.hhalloy.com/live/245532ab74af9be852014a93e292f690.flv +FOX HD,http://cloud-play.hhalloy.com/live/c2c91afe09bad325929734624c19d07b.flv +FOX CRIME,http://cloud-play.hhalloy.com/live/833d6cdeed807b755e6c449832b26621.flv +CINEMAX,http://cloud-play.hhalloy.com/live/9bece52b2f72795cc2f588f3d9e4eed3.flv +Cinema World,http://cloud-play.hhalloy.com/live/357252de83720e30d40c00bfba69c497.flv +CNEX,http://cloud-play.hhalloy.com/live/a079e0f13033fc06d42cd0e9e40913ee.flv +CRIME,http://cloud-play.hhalloy.com/live/3b19a19852e7bdc6b6f238108c94cb82.flv +AXN,http://cloud-play.hhalloy.com/live/c762110b3eef8bcccce5863643dd66aa.flv +好莱坞电影[HD],http://cloud-play.hhalloy.com/live/8e678565884cdebd00f8b3121b3b7ee1.flv +影迷纪实台,http://cloud-play.hhalloy.com/live/a1d2d2be053776bb01c1aac37ac2dee4.flv +CatchPlay电影台,http://cloud-play.hhalloy.com/live/65e80e1e0cd763a0302d7aa2a1135b0b.flv +LS TIME龙祥电影,http://cloud-play.hhalloy.com/live/a5da9875c963d704ac5dd8f866869723.flv +壹电影,http://cloud-play.hhalloy.com/live/eb53b692ccbe8c836bc20be6734a9555.flv +卫视电影台,http://cloud-play.hhalloy.com/live/4499fb1dcef8c7a9f64276bf71bfc5b4.flv +卫视洋片台,http://cloud-play.hhalloy.com/live/78c4edcada009192a9b1f8976b5692ab.flv +卫视中文台[HD],http://cloud-play.hhalloy.com/live/a08a123b4af3aebb4e19b82f64952c9e.flv +卫视合家欢,http://cloud-play.hhalloy.com/live/277056149034cc5fb133537bc411c2c9.flv +纬来电影,http://cloud-play.hhalloy.com/live/4f10b67646969a422a5490deaaabbc69.flv +纬来精彩台,http://cloud-play.hhalloy.com/live/c311c72c22313d2991be335ea4872f46.flv +纬来育乐[HD],http://cloud-play.hhalloy.com/live/5cd65f73313b022253084c489a6705c8.flv +纬来戏剧[HD],http://cloud-play.hhalloy.com/live/82605f105052ccaef7bb5d55ebc1341d.flv +纬来日本[HD],http://cloud-play.hhalloy.com/live/8bb9e07d9ed0c8bccd750b0f15206b73.flv +纬来综合[HD],http://cloud-play.hhalloy.com/live/932044d200ab730968a8f9bc67feaef5.flv +龙华电影,http://cloud-play.hhalloy.com/live/0e5dee9e8021ce3b9ec9bb78e9710555.flv +龙华经典,http://cloud-play.hhalloy.com/live/669a67f26ad4b9f68664bfcaefc9553e.flv +龙华洋片,http://cloud-play.hhalloy.com/live/b7829653660ec5e84c70e7f3a01e1e6c.flv +龙华影剧,http://cloud-play.hhalloy.com/live/d2e1d697b31906f91d7e19a5f06f64ed.flv +龙华戏剧,http://cloud-play.hhalloy.com/live/b40ec839440a97d24d0aee0c69d186a1.flv +龙华偶像,http://cloud-play.hhalloy.com/live/046d62141df9366aa54a66b22e095e24.flv +八大第一[HD],http://cloud-play.hhalloy.com/live/5e147a8d04ab43725d40e72fd7169952.flv +八大娱乐[HD],http://cloud-play.hhalloy.com/live/31c5b2c0fa7ac37b2e1447befb076d08.flv +八大综合[HD],http://cloud-play.hhalloy.com/live/a26d25ad9eaabca42fa6d526199d61e5.flv +八大戏剧[HD],http://cloud-play.hhalloy.com/live/6d7d7a9c22ba9aa4e411e3f7567763d8.flv +三立综合,http://cloud-play.hhalloy.com/live/16eda25701fe842c519d881c68829ead.flv +三立台湾台[HD],http://cloud-play.hhalloy.com/live/e71635b53bb874a085b2a469802bbc81.flv +三立都会台[HD],http://cloud-play.hhalloy.com/live/4abe46a5faf4865e251ac981287a6e20.flv +三立戏剧,http://cloud-play.hhalloy.com/live/bdc9e5f7487003c20223fd67f25c7ee7.flv +星卫HD电影,http://cloud-play.hhalloy.com/live/41e05f3849c21412aa8b347f18adb3f6.flv +美亚电影,http://cloud-play.hhalloy.com/live/4a1141f101530bff4fc0e9229625e6b5.flv +欧洲电影,http://cloud-play.hhalloy.com/live/2d2f46a778c93f01b614213456fc97fc.flv +法国时尚,http://cloud-play.hhalloy.com/live/f737108ad740b942b32d751b0577d534.flv +LUXE.TV,http://cloud-play.hhalloy.com/live/5eb27870debdb04d89a6246b163c2da5.flv +ELTV生活英语,http://cloud-play.hhalloy.com/live/094cb0c295f8bde2de59d5f421230dbd.flv +Discovery Asia,http://cloud-play.hhalloy.com/live/f325e0ce8ddf55c2df916b6f2bc0e07c.flv +Discovery[HD],http://cloud-play.hhalloy.com/live/ef2748398207873cae12b151ae78b0af.flv +Discovery科学[HD],http://cloud-play.hhalloy.com/live/f82bcb85f1a67e5b4754f7be0661dc72.flv +国家地理悠人,http://cloud-play.hhalloy.com/live/0293b493509468a0a896adea05ad5e30.flv +国家地理野生,http://cloud-play.hhalloy.com/live/a4540237835700ece1fc1e54ce826125.flv +国家地理HD,http://cloud-play.hhalloy.com/live/1b4017a457de80eec599895ec807e124.flv +BBC earth,http://cloud-play.hhalloy.com/live/f7146ac8e65cb75112431f87ddcea22e.flv +AMC日舞,http://cloud-play.hhalloy.com/live/40d0812307cd389be76c358de7f4913e.flv +WaKaWaka Japan,http://cloud-play.hhalloy.com/live/6fab3a8298ba5097394c5fdcdea8ea81.flv +BoomErang卡通,http://cloud-play.hhalloy.com/live/65796ce70deacc164cf2eb854ad43994.flv +Travel Channel,http://cloud-play.hhalloy.com/live/2f1e104da16f66b93ad4d873326b19eb.flv +亚洲旅游台[HD],http://cloud-play.hhalloy.com/live/a7003032346b06ad6a610ce1751be6a4.flv +动物星球[HD],http://cloud-play.hhalloy.com/live/eb7d8081fb5400bb7bfa08c8bcd8c45d.flv +TLC旅游生活[HD],http://cloud-play.hhalloy.com/live/2389cbac5b421dd5b069a232f3d321bc.flv +EYE TV旅游台,http://cloud-play.hhalloy.com/live/6d6535e5e44f88df204129354e77b2a7.flv +美食星球,http://cloud-play.hhalloy.com/live/7f2e2b78b85222886ccb3792c905408e.flv +亚洲美食,http://cloud-play.hhalloy.com/live/13e17ff9d96096b87e7902d77452ae76.flv +Smart知识台,http://cloud-play.hhalloy.com/live/641befebabe286484103e2980e05694d.flv +历史频道,http://cloud-play.hhalloy.com/live/998ce23199bda76900024601f6dd859d.flv +历史频道2,http://cloud-play.hhalloy.com/live/b4d47c14a4665a2ef43d657ea6384c27.flv +E!Entertainment,http://cloud-play.hhalloy.com/live/284df67673a590b64593e0127029b0b2.flv +Outoor,http://cloud-play.hhalloy.com/live/fa1bc78d17a433dfd3214271efe7e82b.flv +达西文频道,http://cloud-play.hhalloy.com/live/6d5a837a6f42e9d82be9243e51a91d50.flv +Z频道,http://cloud-play.hhalloy.com/live/30a7edb2f6c42bd079dd4910806decde.flv +影迷电影台,http://cloud-play.hhalloy.com/live/991d0a1e4fc3c270d037fae11c587741.flv +华艺影剧台,http://cloud-play.hhalloy.com/live/49d33b7521ceef2115572e8906e9f906.flv +DMAX[HD],http://cloud-play.hhalloy.com/live/41a76576ae78436eb0951f2aee0c9bda.flv +BBC Lifestyle,http://cloud-play.hhalloy.com/live/5e80f4a9e17c991df381030c65856687.flv +爱尔达影视,http://cloud-play.hhalloy.com/live/0916fef64c4baab95f7097d001e4c27e.flv +Warner TV,http://cloud-play.hhalloy.com/live/a645bdeafb1216c23352144c3505bd8c.flv +彩昌影剧台,http://cloud-play.hhalloy.com/live/b93ac92b703885f3cfe39bad8aa689d1.flv +BLUE ANT EXTREME,http://cloud-play.hhalloy.com/live/7b3b2e1d0006091415635226a2ac5d86.flv +BLUE ANT ENTERTAINMET,http://cloud-play.hhalloy.com/live/41005bf306743766c5affb055bc5c164.flv +EYE TV戏剧台,http://cloud-play.hhalloy.com/live/69a400e45b6fbd61c8182736ec80e013.flv +HITS[HD],http://cloud-play.hhalloy.com/live/e6d6d3927102ce6e0e99187b52946497.flv +TVN,http://cloud-play.hhalloy.com/live/060e39b20b7616170ba4ba63c53bc336.flv +MTV Live,http://cloud-play.hhalloy.com/live/116911efa30e70c9cf64ea9a0e990a05.flv +国兴卫视[HD],http://cloud-play.hhalloy.com/live/148acbf5aac2d7a9afc4b6ab6e8f05ec.flv +NHK[HD],http://cloud-play.hhalloy.com/live/6c2713799277ea6ea2d3bfd0d4c31f88.flv +高点育乐[HD],http://cloud-play.hhalloy.com/live/ab3024fd5d5b0e84cbcd0bc0085cf043.flv +Channel V,http://cloud-play.hhalloy.com/live/c8ade260941e368acfdb110a04811b3e.flv +韩国娱乐台,http://cloud-play.hhalloy.com/live/8ae61414f7e2972598956105e2e9969d.flv +星卫娱乐,http://cloud-play.hhalloy.com/live/4c3c2a7fe5ffc33e45bca04f983f02b0.flv +寰宇综合,http://cloud-play.hhalloy.com/live/82b78befe54a601876654e1db3e3741a.flv +爱尔达综合,http://cloud-play.hhalloy.com/live/c614a26c0e0fb521c5cdfa10ed7f2089.flv +ET综合台,http://cloud-play.hhalloy.com/live/f6e19af652637cfde3c0f5d34822b4b5.flv +霹雳台湾台[HD],http://cloud-play.hhalloy.com/live/14b736ee363e84918a8c43c69691faaa.flv +Hakkatv[HD],http://cloud-play.hhalloy.com/live/9535868a6a173399d3913cab3bb61675.flv +TITV原住民电视台[HD],http://cloud-play.hhalloy.com/live/8f44c933620b603a874a18ed1bb9a033.flv +LIFE TIME,http://cloud-play.hhalloy.com/live/d8ab211a4f23fe8e143757d13ade9b32.flv +TRACE Sports,http://cloud-play.hhalloy.com/live/3b88f91a420e6cd59cd034ccf2a05c10.flv +东风37台,http://cloud-play.hhalloy.com/live/0b2e19ee2374470b5dede1013afcb4b5.flv +年代MUCH[HD],http://cloud-play.hhalloy.com/live/3d20cf4de65aadb4d2b2e30ad3974750.flv +JET综合[HD],http://cloud-play.hhalloy.com/live/c4fcaea7013c6b1d6aef9f1d0e99871e.flv +高点综合[HD],http://cloud-play.hhalloy.com/live/f11ea1c1918059c58b42c637fa9dc678.flv +亚洲综合,http://cloud-play.hhalloy.com/live/8e08d22adcc7748ceedc31006b55f7de.flv +MY101综合台,http://cloud-play.hhalloy.com/live/6c4078ac7601f5787aef2f8b88dd449c.flv +壹综合,http://cloud-play.hhalloy.com/live/3cec0560564363facfd892d88b741c62.flv +博斯高球1[HD],http://cloud-play.hhalloy.com/live/4870a14ca0496e434825594643eea173.flv +博斯高球2[HD],http://cloud-play.hhalloy.com/live/9dd0941038e16fd8207f4c485c2fd34b.flv +博斯魅力[HD],http://cloud-play.hhalloy.com/live/906ff5c1e590fdc0f41744077f56672a.flv +博斯无限[HD],http://cloud-play.hhalloy.com/live/8c9a98717ee9e5136636c3bedbb852b8.flv +博斯网球[HD],http://cloud-play.hhalloy.com/live/cf415a2419c61638eefa5eb8c5a65922.flv +博斯运动2[HD],http://cloud-play.hhalloy.com/live/c71aa3f9ef9e92531a06863b9a731849.flv +博斯运动1[HD],http://cloud-play.hhalloy.com/live/1cebe1e25e9c69e2ed2e1e6012aeb2d3.flv +FOX SPORTS[HD],http://cloud-play.hhalloy.com/live/b00b46e382e81efd9902a848c9b89101.flv +FOX SPORTS2[HD],http://cloud-play.hhalloy.com/live/a726b0d8db38a23435c5c3ba95507d3e.flv +欧洲体育[HD],http://cloud-play.hhalloy.com/live/96681c92588f5254e1c9f8fcb41e9d64.flv +ELEVVEN SPORTS PLUS,http://cloud-play.hhalloy.com/live/b599c0682fbb5364078cb9e3093228a6.flv +ELEVVEN SPORTS 2,http://cloud-play.hhalloy.com/live/94283c6401f80334d9acd488b649830b.flv +FOX SPORTS 3,http://cloud-play.hhalloy.com/live/1a4ff6880b679dd340e42a9b61fe2d9f.flv +纬来体育[HD],http://cloud-play.hhalloy.com/live/464311a99c6465a1f36681b73c62fa83.flv +智林体育台,http://cloud-play.hhalloy.com/live/12b7289a05d4cb3c2b79f38b030e2548.flv +靖洋卡通,http://cloud-play.hhalloy.com/live/8fa63f69fe90ce0597aa6d4b7c262810.flv +MOMO亲子台,http://cloud-play.hhalloy.com/live/0c795e6e7f8e067dd4110a57375a71b9.flv +CN卡通,http://cloud-play.hhalloy.com/live/c865782e4a131efe17651165835ca37e.flv +ANIMAX,http://cloud-play.hhalloy.com/live/33de03293563010671a856688d63d4ee.flv +迪斯尼卡通,http://cloud-play.hhalloy.com/live/198038b134ad459d9cc251038c74685a.flv +梦工厂动画,http://cloud-play.hhalloy.com/live/aae9c139f056e6c003448ba1e4908ee3.flv +I-FUN动漫台,http://cloud-play.hhalloy.com/live/9cd9d87c4ccbf7f28284990a1c3d4569.flv +曼迪日本台,http://cloud-play.hhalloy.com/live/d9445086fd2dd474087674f638f2a8ed.flv +BabyTV,http://cloud-play.hhalloy.com/live/d7ede3e748413a7ad065d29dbe542149.flv +Babyfirst,http://cloud-play.hhalloy.com/live/efd423af0e64fd82c1cc29e909eb4303.flv +My kids,http://cloud-play.hhalloy.com/live/9bb01fa9902e14cd5811f5474283171b.flv +NICK 卡通,http://cloud-play.hhalloy.com/live/a81b6e417028b6d72ed3e6ee7c42619b.flv +东森幼幼[HD],http://cloud-play.hhalloy.com/live/0c0a03db510687f73c455afcc220386b.flv +龙华动画,http://cloud-play.hhalloy.com/live/4a3c4fbd39ddf82979cf3ecf3cd942c8.flv +靖天卡通,http://cloud-play.hhalloy.com/live/6bbfbe0fb0dc5ce3f8db00d8fae9ae5c.flv +ANIMAX HD,http://cloud-play.hhalloy.com/live/13b6c6ecbb388c105fd9d98338162abb.flv +寰宇财经,http://cloud-play.hhalloy.com/live/77c9bab3af161386df16ad9d8a3f3541.flv +台视财经,http://cloud-play.hhalloy.com/live/c5d061725e49943973c43a404b913f17.flv +Bloombreg TV,http://cloud-play.hhalloy.com/live/ab2450af4c80b52d0810eceaf055abee.flv +中视新闻[HD],http://cloud-play.hhalloy.com/live/cf4d66edc142b2f0cc8c71bca56b2268.flv +DWTV,http://cloud-play.hhalloy.com/live/a4aa25e01a432729323f4d0778605887.flv +新加坡亚洲新闻台,http://cloud-play.hhalloy.com/live/1aab6cf57296bdefc6f4bea94702782a.flv +寰宇新闻[HD],http://cloud-play.hhalloy.com/live/4677cf6625ce01b236bbb58f99094d51.flv +寰宇新闻2台,http://cloud-play.hhalloy.com/live/0d192b1fb482857fb4694a12c2718302.flv +欧洲新闻,http://cloud-play.hhalloy.com/live/7c52797bf1ca2da52c212bdead1d607c.flv +非凡新闻[HD],http://cloud-play.hhalloy.com/live/408a2834f703f2162d0d5b5789344c39.flv +TV5 MONDE,http://cloud-play.hhalloy.com/live/a9dd7099d0abf47c5e17f8038234df22.flv +CNN NEWS,http://cloud-play.hhalloy.com/live/5ff1924613169c0b7148e528d0cfe0fd.flv +FOX News,http://cloud-play.hhalloy.com/live/b78a7c4f460285596b53bfa802eca8e8.flv +SKY NEWS,http://cloud-play.hhalloy.com/live/64a4807c0cf482cffe922d7b8f091303.flv +翡翠台,http://23kds.lctv.52live.win/hls/52FCT.m3u8 +无线财经,http://23kds.lctv.52live.win/hls/J5WXCJ.m3u8 +明珠台,http://23kds.lctv.52live.win/hls/mmzzt.m3u8 +互动新闻,http://23kds.lctv.52live.win/hls/TVBXW.m3u8 +TVB星河,http://23kds.lctv.52live.win/hls/TVBXH.m3u8 +有线新闻,http://23kds.lctv.52live.win/hls/YXXWT.m3u8 +RHK31,http://23kds.lctv.52live.win/hls/RHK31.m3u8 +RHK32,http://23kds.lctv.52live.win/hls/RHK32.m3u8 +ViUTV高清,http://ggfdvcbg.000webhostapp.com/video/viutv +TVB翡翠台,http://ggfdvcbg.000webhostapp.com/video/tvbfc +有线新闻台,http://ggfdvcbg.000webhostapp.com/video/tvbyx +无线新闻台,http://ggfdvcbg.000webhostapp.com/video/tvbwx +香港电影,http://sousou2.top/dl/migu.php?id=621640582 +now直播台,http://23kds.lctv.52live.win/hls/nowlive.m3u8 +now体育台,http://23kds.lctv.52live.win/hls/nowty.m3u8 \ No newline at end of file diff --git a/app/src/main/java/com/example/adapter/MyBaGvPhoneBackupAdapter.java b/app/src/main/java/com/example/adapter/MyBaGvPhoneBackupAdapter.java new file mode 100644 index 0000000..9e5b193 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyBaGvPhoneBackupAdapter.java @@ -0,0 +1,79 @@ +package com.example.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyPhoneBackups; +import com.example.wgjrouter.R; + +import java.util.List; + +public class MyBaGvPhoneBackupAdapter extends BaseAdapter { + Context context; + List myPhoneBackupsList; + + public MyBaGvPhoneBackupAdapter(Context context, List myPhoneBackupsList){ + this.context = context; + this.myPhoneBackupsList = myPhoneBackupsList; + } + + @Override + public int getCount() { + return myPhoneBackupsList.size(); + } + + @Override + public Object getItem(int position) { + return myPhoneBackupsList.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder viewHolder; + int[] defaultPic = {R.mipmap.copy_icon_pic,R.mipmap.copy_icon_video,R.mipmap.copy_icon_music}; + + if(convertView == null){ + convertView = View.inflate(context, R.layout.item_gv_phonebackup,null); + viewHolder = new ViewHolder(); + viewHolder.item_gv_iv = convertView.findViewById(R.id.item_gv_iv); + viewHolder.item_gv_tv_title = convertView.findViewById(R.id.item_gv_tv_title); + viewHolder.item_gv_tv_counts = convertView.findViewById(R.id.item_gv_tv_counts); + convertView.setTag(viewHolder); + }else{ + viewHolder = (ViewHolder) convertView.getTag(); + } + + MyPhoneBackups myBaGvPhoneBackup = myPhoneBackupsList.get(position); + + switch (myBaGvPhoneBackup.getFileType()){ + case 0: + viewHolder.item_gv_iv.setImageResource(defaultPic[0]); + break; + case 1: + viewHolder.item_gv_iv.setImageResource(defaultPic[1]); + break; + case 2: + viewHolder.item_gv_iv.setImageResource(defaultPic[2]); + break; + } + + viewHolder.item_gv_tv_title.setText(myBaGvPhoneBackup.getFileTitle()); + viewHolder.item_gv_tv_counts.setText(myBaGvPhoneBackup.getFileCounts() + "项"); + return convertView; + } + + private class ViewHolder{ + ImageView item_gv_iv; + TextView item_gv_tv_title; + TextView item_gv_tv_counts; + } +} diff --git a/app/src/main/java/com/example/adapter/MyBaLvAPInfosAdapter.java b/app/src/main/java/com/example/adapter/MyBaLvAPInfosAdapter.java new file mode 100644 index 0000000..5bec771 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyBaLvAPInfosAdapter.java @@ -0,0 +1,95 @@ +package com.example.adapter; + +import android.content.Context; +import android.graphics.Color; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyBaLvApInfos; +import com.example.wgjrouter.R; + +import java.util.List; + +public class MyBaLvAPInfosAdapter extends BaseAdapter { + + private Context context; + private List myBaLvAPInfosList; + + int[] wifipic = {R.mipmap.wifi1,R.mipmap.wifi2,R.mipmap.wifi3,R.mipmap.wifi4}; + + public MyBaLvAPInfosAdapter(Context context,List myBaLvAPInfosList){ + this.context = context; + this.myBaLvAPInfosList = myBaLvAPInfosList; + } + + @Override + public int getCount() { + return myBaLvAPInfosList.size(); + } + + @Override + public Object getItem(int position) { + return myBaLvAPInfosList.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder viewHolder; + + if(convertView == null){ + convertView = View.inflate(context,R.layout.item_lv_apinfos,null); + viewHolder = new ViewHolder(); + viewHolder.item_tv_apname = convertView.findViewById(R.id.item_tv_apname); + viewHolder.item_iv_encry = convertView.findViewById(R.id.item_iv_encry); + viewHolder.item_iv_aplevel = convertView.findViewById(R.id.item_iv_aplevel); + convertView.setTag(viewHolder); + }else{ + viewHolder = (ViewHolder) convertView.getTag(); + } + + MyBaLvApInfos myBaLvAPInfos = myBaLvAPInfosList.get(position); + viewHolder.item_tv_apname.setText(myBaLvAPInfos.getAPssid()); + + if(myBaLvAPInfos.getAPbridged()){ + //当前AP已被桥接 + viewHolder.item_tv_apname.setTextColor(Color.BLUE); + }else{ + viewHolder.item_tv_apname.setTextColor(Color.GRAY); + } + + if(myBaLvAPInfos.getAPencrypt().equals("")){ + //未识别的加密 + viewHolder.item_iv_encry.setVisibility(View.INVISIBLE); + }else{ + viewHolder.item_iv_encry.setVisibility(View.VISIBLE); + } + + if(Math.abs(myBaLvAPInfos.getAPsignal()) > 88){ + //信号很差 + viewHolder.item_iv_aplevel.setImageResource(wifipic[0]); + }else if(Math.abs(myBaLvAPInfos.getAPsignal()) > 77){ + viewHolder.item_iv_aplevel.setImageResource(wifipic[1]); + }else if(Math.abs(myBaLvAPInfos.getAPsignal()) > 66){ + viewHolder.item_iv_aplevel.setImageResource(wifipic[2]); + } else{ + viewHolder.item_iv_aplevel.setImageResource(wifipic[3]); + } + + return convertView; + } + + private class ViewHolder{ + TextView item_tv_apname; + ImageView item_iv_encry; + ImageView item_iv_aplevel; + } +} diff --git a/app/src/main/java/com/example/adapter/MyBaLvDevicesAdater.java b/app/src/main/java/com/example/adapter/MyBaLvDevicesAdater.java new file mode 100644 index 0000000..4a185a1 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyBaLvDevicesAdater.java @@ -0,0 +1,93 @@ +package com.example.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyBaLvDevices; +import com.example.wgjrouter.R; + +import java.util.List; + +public class MyBaLvDevicesAdater extends BaseAdapter { + private Context context; + private List myBaLvDevicesList; + + int[] imgSource = {R.mipmap.icon_yes,R.mipmap.icon_no}; + + public MyBaLvDevicesAdater(Context context, List myBaLvDevicesList){ + this.context = context; + this.myBaLvDevicesList = myBaLvDevicesList; + } + + @Override + public int getCount() { + return myBaLvDevicesList.size(); + } + + @Override + public Object getItem(int position) { + return myBaLvDevicesList.get(position); + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder viewHolder; + + if(convertView == null){ + convertView = View.inflate(context,R.layout.item_lv_devices,null); + viewHolder = new ViewHolder(); + viewHolder.item_tv_devname = convertView.findViewById(R.id.item_tv_devname); + viewHolder.item_tv_devip = convertView.findViewById(R.id.item_tv_devip); + viewHolder.item_tv_devmac = convertView.findViewById(R.id.item_tv_devmac); + viewHolder.item_iv_devaccnet = convertView.findViewById(R.id.item_iv_devaccnet); + viewHolder.item_iv_devaccsha = convertView.findViewById(R.id.item_iv_devaccsha); + viewHolder.item_iv_devbindmac = convertView.findViewById(R.id.item_iv_devbindmac); + convertView.setTag(viewHolder); + }else{ + viewHolder = (ViewHolder) convertView.getTag(); + } + + MyBaLvDevices myBaLvDevices = myBaLvDevicesList.get(position); + viewHolder.item_tv_devname.setText(myBaLvDevices.getDevName()); + viewHolder.item_tv_devip.setText(myBaLvDevices.getDevIP()); + viewHolder.item_tv_devmac.setText(myBaLvDevices.getDevMac()); + + if(myBaLvDevices.getDevAccNet().equals("ENABLE")){ + viewHolder.item_iv_devaccnet.setImageResource(imgSource[0]); + }else{ + viewHolder.item_iv_devaccnet.setImageResource(imgSource[1]); + } + + if(myBaLvDevices.getDevAccSha().equals("ENABLE")){ + viewHolder.item_iv_devaccsha.setImageResource(imgSource[0]); + }else{ + viewHolder.item_iv_devaccsha.setImageResource(imgSource[1]); + } + + if(myBaLvDevices.getDevBindMAC().equals("UNBIND")){ + viewHolder.item_iv_devbindmac.setImageResource(imgSource[1]); + }else{ + viewHolder.item_iv_devbindmac.setImageResource(imgSource[0]); + } + + return convertView; + } + + private class ViewHolder{ + TextView item_tv_devname; + TextView item_tv_devip; + TextView item_tv_devmac; + ImageView item_iv_devaccnet; + ImageView item_iv_devaccsha; + ImageView item_iv_devbindmac; + } +} diff --git a/app/src/main/java/com/example/adapter/MyFgTransLvAdapter.java b/app/src/main/java/com/example/adapter/MyFgTransLvAdapter.java new file mode 100644 index 0000000..3fd0498 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyFgTransLvAdapter.java @@ -0,0 +1,31 @@ +package com.example.adapter; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; + +import java.util.List; + +public class MyFgTransLvAdapter extends FragmentPagerAdapter { + String[] pageTitle = {"下载中","上传中"}; + private List fragmentList; + + public MyFgTransLvAdapter(FragmentManager fm,List fragmentList) { + super(fm); + this.fragmentList = fragmentList; + } + + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } + + public CharSequence getPageTitle(int position){ + return pageTitle[position]; + } +} diff --git a/app/src/main/java/com/example/adapter/MyFgVpFpaAdapter.java b/app/src/main/java/com/example/adapter/MyFgVpFpaAdapter.java new file mode 100644 index 0000000..eed14f1 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyFgVpFpaAdapter.java @@ -0,0 +1,26 @@ +package com.example.adapter; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; + +import java.util.List; + +public class MyFgVpFpaAdapter extends FragmentPagerAdapter { + List fragmentList; + + public MyFgVpFpaAdapter(FragmentManager fm, List fragmentList) { + super(fm); + this.fragmentList = fragmentList; + } + + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/example/adapter/MyRecBackupsAdapter.java b/app/src/main/java/com/example/adapter/MyRecBackupsAdapter.java new file mode 100644 index 0000000..d2d0ad3 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyRecBackupsAdapter.java @@ -0,0 +1,112 @@ +package com.example.adapter; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyPhoneBackups; +import com.example.wgjrouter.R; + +import java.util.List; + +public class MyRecBackupsAdapter extends RecyclerView.Adapter { + Context context; + List myPhoneBackupsList; + + public MyRecBackupsAdapter(Context context, List myPhoneBackupsList){ + this.context = context; + this.myPhoneBackupsList = myPhoneBackupsList; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + MyViewHolder viewHolder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_rec_phonebackup,viewGroup,false)); + return viewHolder; + } + + public interface OnItemListener{ + void onItemClick(View view, int position); + void onItemLongClick(View view,int position); + } + + private OnItemListener onItemListener; + + public void setOnItemListener(OnItemListener onItemListener){ + this.onItemListener = onItemListener; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) { + int[] defaultPic = {R.mipmap.copy_icon_pic,R.mipmap.copy_icon_file,R.mipmap.copy_icon_music, + R.mipmap.copy_icon_wechat,R.mipmap.copy_icon_app,R.mipmap.copy_icon_massage, + R.mipmap.copy_icon_phone,R.mipmap.copy_icon_addressbook}; + + MyPhoneBackups myPhoneBackups = myPhoneBackupsList.get(position); + + ((MyViewHolder)viewHolder).item_rec_backup_iv_typepic.setImageResource(defaultPic[myPhoneBackups.getFileType()]); + ((MyViewHolder)viewHolder).item_rec_backup_tv_title.setText(myPhoneBackups.getFileTitle()); + + if(myPhoneBackups.isAutoUpload()){ + ((MyViewHolder)viewHolder).item_rec_backup_tv_state.setText("已开启"); + }else{ + ((MyViewHolder)viewHolder).item_rec_backup_tv_state.setText("关闭"); + } + + if(onItemListener != null){ + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemClick(viewHolder.itemView,pos); + } + }); + viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemLongClick(viewHolder.itemView,pos); + return true; + } + }); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) { + super.onBindViewHolder(viewHolder, position, payloads); + if(payloads.isEmpty()){ + onBindViewHolder(viewHolder,position); + }else{ + if(payloads.get(0).toString().equals("true")){ + ((MyViewHolder)viewHolder).item_rec_backup_tv_state.setText("已开启"); + }else{ + ((MyViewHolder)viewHolder).item_rec_backup_tv_state.setText("关闭"); + } + } + } + + @Override + public int getItemCount() { + return myPhoneBackupsList.size(); + } + + private class MyViewHolder extends RecyclerView.ViewHolder{ + ImageView item_rec_backup_iv_typepic; + TextView item_rec_backup_tv_title; + TextView item_rec_backup_tv_state; + + public MyViewHolder(@NonNull View itemView) { + super(itemView); + item_rec_backup_iv_typepic = itemView.findViewById(R.id.item_rec_backup_iv_typepic); + item_rec_backup_tv_title = itemView.findViewById(R.id.item_rec_backup_tv_title); + item_rec_backup_tv_state = itemView.findViewById(R.id.item_rec_backup_tv_state); + } + } +} diff --git a/app/src/main/java/com/example/adapter/MyRecFilesAdapter.java b/app/src/main/java/com/example/adapter/MyRecFilesAdapter.java new file mode 100644 index 0000000..4173700 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyRecFilesAdapter.java @@ -0,0 +1,298 @@ +package com.example.adapter; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyRecFileInfos; +import com.example.event.MessageEvent; +import com.example.utils.MyDateUtils; +import com.example.utils.MyFileUtils; +import com.example.wgjrouter.R; +import com.squareup.picasso.Picasso; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class MyRecFilesAdapter extends RecyclerView.Adapter { + + private Context context; + private EventBus eventBus; + private int routerType = 0; + private String routerHost = ""; + private List myFgLvInfosList; + private int MODE_CHOICE = 0;//默认非选择模式 + private HashMap selectStateMap = new HashMap<>();; + private List selectList = new ArrayList<>(); + private boolean canInitData = true; + + public MyRecFilesAdapter(Context context,EventBus eventBus,int routerType, String routerHost, List myFgLvInfosList){ + this.context = context; + this.eventBus = eventBus; + this.routerType = routerType; + this.routerHost = routerHost; + this.myFgLvInfosList = myFgLvInfosList; + } + + //配置路由参数(切换路由器时) + public void initRouterParams(int routerType, String routerHost){ + this.routerType = routerType; + this.routerHost = routerHost; + } + + //是否初始化选中状态列表 + public void setCanInitData(boolean canInitData){ + this.canInitData = canInitData; + } + + //初始化选择状态 + private void initStateMap(){ + selectStateMap.clear(); + + for(int i = 0;i < myFgLvInfosList.size();i++){ + selectStateMap.put(i,false); + } + } + + //设置单选、多选模式 + public void setMultiChoiceMode(int Mode){ + MODE_CHOICE = Mode; + notifyDataSetChanged(); + } + + //获取单选、多选模式 + public int getMultiChoiceMode(){ + return MODE_CHOICE; + } + + //全选 + public void selectAll(){ + for(int i = 0;i < selectStateMap.size();i++){ + selectStateMap.put(i,true); + } + + notifyItemRangeChanged(0,selectStateMap.size(),true); + } + + //全不选 + public void selectNone(){ + for(int i = 0;i < selectStateMap.size();i++){ + selectStateMap.put(i,false); + } + + notifyItemRangeChanged(0,selectStateMap.size(),false); + } + + //判断当前是否全部选择 + public boolean isSelectAll(){ + boolean isSelectAll = true; + for(int i = 0;i < selectStateMap.size();i++){ + if(!selectStateMap.get(i)){ + isSelectAll = false; + } + } + return isSelectAll; + } + + //返回选择的项目位置 + public List getSelectItemIndex(){ + selectList.clear(); + + for(int i = 0;i < selectStateMap.size();i++){ + if(selectStateMap.get(i)){ + selectList.add(i); + } + } + return selectList; + } + + //判断当前可否刷新界面,提供给 SwipeRefreshLayout + public boolean canFresh(){ + return MODE_CHOICE == 0 ? true:false; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + MyViewHolder myViewHolder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_lv_file_infos,viewGroup,false)); + return myViewHolder; + } + + public interface OnItemListener{ + void onItemClick(View view,int position); + void onItemLongClick(View view,int position); + } + + private OnItemListener onItemListener; + + public void setOnItemListener(OnItemListener onItemListener){ + this.onItemListener = onItemListener; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, final int position) { + int[] defaultPic = {R.mipmap.isapk,R.mipmap.isdir,R.mipmap.isexcel,R.mipmap.isword, + R.mipmap.isppt,R.mipmap.isexe,R.mipmap.isini,R.mipmap.isiso, + R.mipmap.islink,R.mipmap.ispdf,R.mipmap.ispsd,R.mipmap.istxt, + R.mipmap.isjar, R.mipmap.iszip,R.mipmap.ispic,R.mipmap.isvideo, + R.mipmap.istorrent,R.mipmap.ismusic,R.mipmap.isnothing}; + + final MyRecFileInfos mfli = myFgLvInfosList.get(position); + + if(MODE_CHOICE == 1){ + //多选功能 + ((MyViewHolder)viewHolder).cb_file_select.setVisibility(View.VISIBLE); + }else{ + ((MyViewHolder)viewHolder).cb_file_select.setVisibility(View.GONE); + } + + ((MyViewHolder)viewHolder).cb_file_select.setOnCheckedChangeListener(null); + + if(selectStateMap.get(position)){ + ((MyViewHolder)viewHolder).cb_file_select.setChecked(true); + }else{ + ((MyViewHolder)viewHolder).cb_file_select.setChecked(false); + } + + ((MyViewHolder)viewHolder).cb_file_select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(isChecked){ + selectStateMap.put(position,true); + }else{ + selectStateMap.put(position,false); + } + + eventBus.post(new MessageEvent(22,getSelectItemIndex().size(),"",1,"","")); + } + }); + + ((MyViewHolder)viewHolder).tv_file_title.setText(mfli.getFileTitle()); + + boolean isFile = mfli.getIsFile(); + + if(isFile){ + ((MyViewHolder)viewHolder).tv_file_size.setText(String.valueOf(mfli.getFileSize() + " " + mfli.getSizeUnit())); + }else{ + /** + * 文件夹--显示子项数目 + * 注:需打开显示子项开关(耗时操作) + */ + ((MyViewHolder)viewHolder).tv_file_size.setText(String.valueOf(mfli.getItemCount())); + } + + ((MyViewHolder)viewHolder).tv_file_date.setText(MyDateUtils.getInstance().getCurrentDate(mfli.getFileDate())); + + String httpFilePath = mfli.getFilePath(); + String httpPicUrl = ""; + + switch (routerType){ + case 0: + httpPicUrl = httpFilePath.substring((httpFilePath.indexOf("/holl/") + 5),httpFilePath.length()); + break; + case 1: + httpPicUrl = httpFilePath.substring((httpFilePath.indexOf("@192.168.80.1/") + 14),httpFilePath.length()); + break; + } + + httpPicUrl = routerHost + httpPicUrl; + + String fileUrl = httpFilePath.toLowerCase(); + + int label = -1; + + if(isFile){ + label = MyFileUtils.getInstance().checkFileType(fileUrl); + if(label == 14){ + //加载网络图片 + Picasso.get().load(httpPicUrl) + .resize(100,100) + .centerInside() + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .tag("getPhotoTag") + .into(((MyViewHolder)viewHolder).iv_file_img); + }else{ + ((MyViewHolder)viewHolder).iv_file_img.setImageResource(defaultPic[label]); + } + }else{ + //文件夹 + ((MyViewHolder)viewHolder).iv_file_img.setImageResource(R.mipmap.isdir); + } + + if(onItemListener != null){ + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemClick(viewHolder.itemView,pos); + } + }); + + viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemLongClick(viewHolder.itemView,pos); + return true; + } + }); + } + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) { + if(payloads.isEmpty()){ + if(canInitData){ + //重新加载数据时初始 + initStateMap(); + canInitData = false; + } + onBindViewHolder(viewHolder,position); + }else{ + if(payloads.get(0).toString().equals("true")){ + ((MyViewHolder)viewHolder).cb_file_select.setChecked(true); + selectStateMap.put(position,true); + }else if(payloads.get(0).toString().equals("false")){ + ((MyViewHolder)viewHolder).cb_file_select.setChecked(false); + selectStateMap.put(position,false); + } + + eventBus.post(new MessageEvent(22,getSelectItemIndex().size(),"",1,"","")); + } + } + + @Override + public int getItemCount() { + return myFgLvInfosList.size(); + } + + private class MyViewHolder extends RecyclerView.ViewHolder{ + CheckBox cb_file_select; + ImageView iv_file_img; + TextView tv_file_title; + TextView tv_file_size; + TextView tv_file_date; + + public MyViewHolder(@NonNull View itemView) { + super(itemView); + + cb_file_select = itemView.findViewById(R.id.item_cb_fileselect); + iv_file_img = itemView.findViewById(R.id.item_iv_filepic); + tv_file_title = itemView.findViewById(R.id.item_tv_filename); + tv_file_size = itemView.findViewById(R.id.item_tv_filesize); + tv_file_date = itemView.findViewById(R.id.item_tv_filedate); + } + } +} diff --git a/app/src/main/java/com/example/adapter/MyRecImageBackupAdapter.java b/app/src/main/java/com/example/adapter/MyRecImageBackupAdapter.java new file mode 100644 index 0000000..fb132f0 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyRecImageBackupAdapter.java @@ -0,0 +1,277 @@ +package com.example.adapter; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SwitchCompat; +import android.util.Log; +import android.util.SparseBooleanArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyPhoneBackups; +import com.example.event.MessageEvent; +import com.example.wgjrouter.R; +import com.squareup.picasso.Picasso; + +import org.greenrobot.eventbus.EventBus; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class MyRecImageBackupAdapter extends RecyclerView.Adapter { + private Context context; + private EventBus eventBus; + private List myPhoneBackupsList; + private Set autoUpDirSet; + private boolean canInitData = true; + private HashMap selectStateMap = new HashMap<>();; + private List selectList = new ArrayList<>(); + private List autoUpDirList = new ArrayList<>(); + + public MyRecImageBackupAdapter(Context context, EventBus eventBus, List myPhoneBackupsList, Set autoUpDirSet){ + this.context = context; + this.eventBus = eventBus; + this.myPhoneBackupsList = myPhoneBackupsList; + this.autoUpDirSet = autoUpDirSet; + + Log.d("zouguo","构造函数"); + //初始化本地上传文件夹列表 + initBackupDirList(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + MyViewHolder myViewHolder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_rec_autoback_list,viewGroup,false)); + return myViewHolder; + } + + //是否初始化选中状态列表 + public void setCanInitData(boolean canInitData){ + this.canInitData = canInitData; + } + + //初始化上传文件夹列表 + private void initBackupDirList(){ + autoUpDirList.clear(); + + for(String str : autoUpDirSet){ + autoUpDirList.add(str); + } + } + + //初始化选中状态列表 + private void initStateMap(){ + selectStateMap.clear(); + + for(int i = 0;i < myPhoneBackupsList.size();i++){ + //判断当前文件夹是否已开启自动上传 + if(autoUpDirList.contains(myPhoneBackupsList.get(i).getFileTitle())){ + selectStateMap.put(i,true); + }else{ + selectStateMap.put(i,false); + } + } + } + + //全选 + public void selectAll(){ + for(int i = 0;i < selectStateMap.size();i++){ + selectStateMap.put(i,true); + } + + notifyItemRangeChanged(0,selectStateMap.size(),true); + } + + //全不选 + public void selectNone(){ + for(int i = 0;i < selectStateMap.size();i++){ + selectStateMap.put(i,false); + } + + notifyItemRangeChanged(0,selectStateMap.size(),false); + } + + //判断当前是否全部选择 + public boolean isSelectAll(){ + boolean isSelectAll = true; + for(int i = 0;i < selectStateMap.size();i++){ + if(!selectStateMap.get(i)){ + isSelectAll = false; + } + } + return isSelectAll; + } + + //返回选择的项目位置 + public List getSelectItemIndex(){ + selectList.clear(); + + for(int i = 0;i < selectStateMap.size();i++){ + if(selectStateMap.get(i)){ + selectList.add(i); + } + } + return selectList; + } + + public interface OnItemListener{ + void onItemClick(View view,int position); + } + + private OnItemListener onItemListener; + + public void setOnItemListener(OnItemListener onItemListener){ + this.onItemListener = onItemListener; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, final int position) { + MyPhoneBackups myPhoneBackup = myPhoneBackupsList.get(position); + + ((MyViewHolder)viewHolder).item_rec_autobackup_tv_title.setText(myPhoneBackup.getFileTitle()); + ((MyViewHolder)viewHolder).item_rec_autobackup_tv_counts.setText(myPhoneBackup.getFileCounts() + "项"); + + ((MyViewHolder)viewHolder).item_rec_autobackup_sc.setOnCheckedChangeListener(null); + + if(selectStateMap.get(position)){ + ((MyViewHolder)viewHolder).item_rec_autobackup_sc.setChecked(true); + }else{ + ((MyViewHolder)viewHolder).item_rec_autobackup_sc.setChecked(false); + } + + ((MyViewHolder)viewHolder).item_rec_autobackup_sc.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(isChecked){ + selectStateMap.put(position,true); + }else{ + selectStateMap.put(position,false); + } + + eventBus.post(new MessageEvent(33,getSelectItemIndex().size(),"",1,"","")); + } + }); + + String fileUrl = myPhoneBackup.getFirstItemUrl(); + int fileType = checkFileType(fileUrl); + + switch (fileType){ + case 14: + File file = new File(fileUrl); + Picasso.get().load(file) + .tag("getPhotoTag") + .into(((MyViewHolder)viewHolder).item_rec_autobackup_iv_pic_itempic); + break; + case 15: + break; + default: + break; + } + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemClick(viewHolder.itemView,pos); + } + }); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) { + if(payloads.isEmpty()){ + if(canInitData){ + initStateMap(); + canInitData = false; + } + onBindViewHolder(viewHolder,position); + }else{ + if(payloads.get(0).toString().equals("true")){ + //选中 + ((MyViewHolder)viewHolder).item_rec_autobackup_sc.setChecked(true); + selectStateMap.put(position,true); + }else if(payloads.get(0).toString().equals("false")){ + //不选中 + ((MyViewHolder)viewHolder).item_rec_autobackup_sc.setChecked(false); + selectStateMap.put(position,false); + } + + eventBus.post(new MessageEvent(33,getSelectItemIndex().size(),"",1,"","")); + } + } + + @Override + public int getItemCount() { + return myPhoneBackupsList.size(); + } + + private class MyViewHolder extends RecyclerView.ViewHolder{ + ImageView item_rec_autobackup_iv_pic; + ImageView item_rec_autobackup_iv_pic_itempic; + TextView item_rec_autobackup_tv_title; + TextView item_rec_autobackup_tv_counts; + SwitchCompat item_rec_autobackup_sc; + + public MyViewHolder(@NonNull View itemView) { + super(itemView); + item_rec_autobackup_iv_pic = itemView.findViewById(R.id.item_rec_autobackup_iv_pic); + item_rec_autobackup_iv_pic_itempic = itemView.findViewById(R.id.item_rec_autobackup_iv_pic_itempic); + item_rec_autobackup_tv_title = itemView.findViewById(R.id.item_rec_autobackup_tv_title); + item_rec_autobackup_tv_counts = itemView.findViewById(R.id.item_rec_autobackup_tv_counts); + item_rec_autobackup_sc = itemView.findViewById(R.id.item_rec_autobackup_sc); + } + } + + private int checkFileType(String fileUrl){ + int label = 1; + + if(fileUrl.endsWith("png") || fileUrl.endsWith("jpg") || fileUrl.endsWith("bmp") || fileUrl.endsWith("gif") || fileUrl.endsWith("jpeg") || fileUrl.endsWith("ico")){ + label = 14; + } else if(fileUrl.endsWith("apk")){ + label = 0; + } else if(fileUrl.endsWith("xls") || fileUrl.endsWith("xlsx")){ + label = 2; + } else if(fileUrl.endsWith("doc") || fileUrl.endsWith("docx")){ + label = 3; + } else if(fileUrl.endsWith("ppt") || fileUrl.endsWith("pptx")){ + label = 4; + } else if(fileUrl.endsWith("exe")){ + label = 5; + } else if(fileUrl.endsWith("ini")){ + label = 6; + } else if(fileUrl.endsWith("iso")){ + label = 7; + } else if(fileUrl.endsWith("link")){ + label = 8; + } else if(fileUrl.endsWith("pdf")){ + label = 9; + } else if(fileUrl.endsWith("psd")){ + label = 10; + } else if(fileUrl.endsWith("txt")){ + label = 11; + } else if(fileUrl.endsWith("jar")){ + label = 12; + } else if(fileUrl.endsWith("zip") || fileUrl.endsWith("rar") || fileUrl.endsWith("tar") || fileUrl.endsWith("7z")){ + label = 13; + } else if(fileUrl.endsWith("avi") || fileUrl.endsWith("mov") || fileUrl.endsWith("mp4") || fileUrl.endsWith("mkv") || fileUrl.endsWith("wmv") || fileUrl.endsWith("flv") || fileUrl.endsWith("rmvb")){ + label = 15; + } else if(fileUrl.endsWith("torrent")) { + label = 16; + }else if(fileUrl.endsWith("mp3") || fileUrl.endsWith("wma") || fileUrl.endsWith("wav")){ + label = 17; + }else{ + label = 18; + } + + return label; + } +} diff --git a/app/src/main/java/com/example/adapter/MyRecRemoteFileAdapter.java b/app/src/main/java/com/example/adapter/MyRecRemoteFileAdapter.java new file mode 100644 index 0000000..ca5c3dc --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyRecRemoteFileAdapter.java @@ -0,0 +1,124 @@ +package com.example.adapter; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.bean.MyRecRemoteFileInfos; +import com.example.utils.MyFileUtils; +import com.example.wgjrouter.R; +import com.squareup.picasso.Picasso; + +import java.util.List; + +public class MyRecRemoteFileAdapter extends RecyclerView.Adapter { + + private Context context; + private List myRecRemoteFileInfos; + + public MyRecRemoteFileAdapter(Context context,List myRecRemoteFileInfos){ + this.context = context; + this.myRecRemoteFileInfos = myRecRemoteFileInfos; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_rec_remote_file_infos,viewGroup,false)); + return holder; + } + + public interface OnItemListener{ + void onItemClick(View view,int position); + void onItemLongClick(View view,int position); + } + + private OnItemListener onItemListener; + + public void setOnItemListener(OnItemListener onItemListener){ + this.onItemListener = onItemListener; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) { + int[] defaultPic = {R.mipmap.isapk,R.mipmap.isdir,R.mipmap.isexcel,R.mipmap.isword, + R.mipmap.isppt,R.mipmap.isexe,R.mipmap.isini,R.mipmap.isiso, + R.mipmap.islink,R.mipmap.ispdf,R.mipmap.ispsd,R.mipmap.istxt, + R.mipmap.isjar, R.mipmap.iszip,R.mipmap.ispic,R.mipmap.isvideo, + R.mipmap.istorrent,R.mipmap.ismusic,R.mipmap.isnothing}; + + MyRecRemoteFileInfos myRecRemoteFileInfo = myRecRemoteFileInfos.get(position); + + String title = myRecRemoteFileInfo.getTitle(); + String url = myRecRemoteFileInfo.getUrl(); + ((MyViewHolder)viewHolder).item_rec_tv.setText(title); + + //以/结尾的为文件夹 + boolean isFile = !myRecRemoteFileInfo.getTitle().endsWith("/"); + int label = -1; + + if(isFile){ + label = MyFileUtils.getInstance().checkFileType(title); + if(label == 14){ + //加载网络图片 + //Picasso.get().setIndicatorsEnabled(true); + Picasso.get().load(url) + .resize(100,100) + .centerInside() + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .tag("getPhotoTag") + .into(((MyViewHolder)viewHolder).item_rec_iv); + }else{ + ((MyViewHolder)viewHolder).item_rec_iv.setImageResource(defaultPic[label]); + } + }else{ + //文件夹 + if(title.equals("../")){ + ((MyViewHolder)viewHolder).item_rec_iv.setImageBitmap(null); + }else{ + ((MyViewHolder)viewHolder).item_rec_iv.setImageResource(R.mipmap.isdir); + } + } + + if(onItemListener != null){ + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemClick(viewHolder.itemView,pos); + } + }); + + viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemLongClick(viewHolder.itemView,pos); + return true; + } + }); + } + } + + @Override + public int getItemCount() { + return myRecRemoteFileInfos.size(); + } + + private class MyViewHolder extends RecyclerView.ViewHolder{ + ImageView item_rec_iv; + TextView item_rec_tv; + + public MyViewHolder(View itemView){ + super(itemView); + item_rec_iv = itemView.findViewById(R.id.item_rec_iv); + item_rec_tv = itemView.findViewById(R.id.item_rec_tv); + } + } +} diff --git a/app/src/main/java/com/example/adapter/MyRecTransAdapter.java b/app/src/main/java/com/example/adapter/MyRecTransAdapter.java new file mode 100644 index 0000000..1ebf919 --- /dev/null +++ b/app/src/main/java/com/example/adapter/MyRecTransAdapter.java @@ -0,0 +1,223 @@ +package com.example.adapter; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.example.bean.TaskInfo; +import com.example.samba.MultiDownloadService; +import com.example.utils.MyDateUtils; +import com.example.utils.MyFileUtils; +import com.example.wgjrouter.R; + +import java.util.List; + +public class MyRecTransAdapter extends RecyclerView.Adapter { + private Context context = null; + private List taskInfoList = null; + + public MyRecTransAdapter(Context context,List taskInfoList) { + this.context = context; + this.taskInfoList = taskInfoList; + } + + /** + * 更新进度条 + * @param id + * @param progress + */ + public void updateProgressbar(int id,long progress){ + notifyItemChanged(id,progress); + } + + /** + * 获取下载队列 + * @return + */ + public List getTransEnqueueList(){ + return taskInfoList; + } + + /** + * 判断任务是否在下载队列中 + * @param url + * @return + */ + public boolean isTaskExists(String url){ + boolean isExists = false; + + for(TaskInfo taskInfo : taskInfoList){ + if(url.equals(taskInfo.getFileUrl())){ + isExists = true; + } + } + + return isExists; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { + MyViewHolder myViewHolder = new MyViewHolder(View.inflate(context,R.layout.item_lv_trans_infos,null)); + return myViewHolder; + } + + public interface OnItemListener{ + void onItemClick(View view,int position); + void onItemLongClick(View view,int position); + } + + private OnItemListener onItemListener; + + public void setOnItemListener(OnItemListener onItemListener){ + this.onItemListener = onItemListener; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) { + int[] defaultPic = {R.mipmap.isapk,R.mipmap.isdir,R.mipmap.isexcel,R.mipmap.isword, + R.mipmap.isppt,R.mipmap.isexe,R.mipmap.isini,R.mipmap.isiso, + R.mipmap.islink,R.mipmap.ispdf,R.mipmap.ispsd,R.mipmap.istxt, + R.mipmap.isjar, R.mipmap.iszip,R.mipmap.ispic,R.mipmap.isvideo, + R.mipmap.istorrent,R.mipmap.ismusic,R.mipmap.isnothing}; + int[] transType = {R.mipmap.isupload,R.mipmap.isdownload}; + + TaskInfo taskInfo = taskInfoList.get(position); + String fileUrl = taskInfo.getFileUrl(); + String gap = taskInfo.getTranGap(); + String state = taskInfo.getTranState(); + + ((MyViewHolder)viewHolder).fg_transfer_filetype_iv.setImageResource(defaultPic[MyFileUtils.getInstance().checkFileType(fileUrl)]); + ((MyViewHolder)viewHolder).fg_transfer_filename_tv.setText(taskInfo.getFileName()); + ((MyViewHolder)viewHolder).fg_transfer_filelength_tv.setText(MyFileUtils.getInstance().formatFileSize(taskInfo.getFileLength(),0)); + ((MyViewHolder)viewHolder).fg_transfer_gap_tv.setText(gap); + + if(state.equals("完成")){ + ((MyViewHolder)viewHolder).fg_transfer_pb.setVisibility(View.GONE); + ((MyViewHolder)viewHolder).fg_transfer_pb.setProgress(100); + }else{ + ((MyViewHolder)viewHolder).fg_transfer_pb.setVisibility(View.VISIBLE); + ((MyViewHolder)viewHolder).fg_transfer_pb.setProgress(taskInfo.getTranProgress()); + } + + if(gap.equals("")){ + ((MyViewHolder)viewHolder).fg_transfer_finished_tv.setText(""); + ((MyViewHolder)viewHolder).fg_transfer_time_tv.setText(MyDateUtils.getInstance().getSimpleTimeFromMillis(taskInfo.getTranTime())); + }else{ + ((MyViewHolder)viewHolder).fg_transfer_finished_tv.setText(MyFileUtils.getInstance().formatFileSize(taskInfo.getTranFinished(),0)); + } + + if(taskInfo.isShowDirection()){ + ((MyViewHolder)viewHolder).fg_transfer_type_iv.setImageResource(transType[taskInfo.getUpOrDownOrRemote()]); + } + + viewHolder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemClick(viewHolder.itemView,pos); + } + }); + + viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + int pos = viewHolder.getLayoutPosition(); + onItemListener.onItemLongClick(viewHolder.itemView,pos); + return true; + } + }); + + //暂停、开始 + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position,List payloads) { + //更新Index + TaskInfo taskInfo = taskInfoList.get(position); + taskInfo.setIndexs(position); + + if(payloads.isEmpty()){ + onBindViewHolder(viewHolder,position); + }else{ + List payloadList = (List) payloads.get(0); + + if(payloadList.get(0).toString().equals("downloadProgress")){ + int progress = Integer.parseInt(payloadList.get(1).toString()); + String speed = payloadList.get(2).toString(); + long finished = Long.parseLong(payloadList.get(3).toString()); + long length = Long.parseLong(payloadList.get(4).toString()); + long usetime = Long.parseLong(payloadList.get(5).toString()); + + ((MyViewHolder)viewHolder).fg_transfer_pb.setProgress(progress); + ((MyViewHolder)viewHolder).fg_transfer_time_tv.setText(speed); + ((MyViewHolder)viewHolder).fg_transfer_finished_tv.setText(MyFileUtils.getInstance().formatFileSize(finished,0)); + ((MyViewHolder)viewHolder).fg_transfer_gap_tv.setText("/"); + ((MyViewHolder)viewHolder).fg_transfer_filelength_tv.setText(MyFileUtils.getInstance().formatFileSize(length,0)); + + taskInfo.setTranState("正在下载"); + taskInfo.setTranProgress(progress); + taskInfo.setTranFinished(finished); + taskInfo.setTranGap("/"); + taskInfo.setFileLength(length); + taskInfo.setTranTime(usetime); + }else if(payloadList.get(0).toString().equals("downloadOK")){ + int progress = Integer.parseInt(payloadList.get(1).toString()); + String speed = payloadList.get(2).toString(); + long finished = Long.parseLong(payloadList.get(3).toString()); + long length = Long.parseLong(payloadList.get(4).toString()); + + Log.d("zouguo","完成:" + payloadList.toString()); + + ((MyViewHolder)viewHolder).fg_transfer_pb.setProgress(progress); + ((MyViewHolder)viewHolder).fg_transfer_time_tv.setText(speed); + ((MyViewHolder)viewHolder).fg_transfer_finished_tv.setText(""); + ((MyViewHolder)viewHolder).fg_transfer_gap_tv.setText(""); + ((MyViewHolder)viewHolder).fg_transfer_filelength_tv.setText(MyFileUtils.getInstance().formatFileSize(length,0)); + + taskInfo.setTranState("完成"); + taskInfo.setTranProgress(progress); + taskInfo.setTranGap(""); + taskInfo.setTranFinished(finished); + } + } + } + + @Override + public int getItemCount() { + return taskInfoList.size(); + } + + class MyViewHolder extends RecyclerView.ViewHolder{ + ImageView fg_transfer_filetype_iv; + TextView fg_transfer_filename_tv; + ProgressBar fg_transfer_pb; + TextView fg_transfer_finished_tv; + TextView fg_transfer_gap_tv; + TextView fg_transfer_filelength_tv; + TextView fg_transfer_time_tv; + ImageView fg_transfer_type_iv; + + public MyViewHolder(View itemView) { + super(itemView); + + fg_transfer_filetype_iv = itemView.findViewById(R.id.fg_transfer_filetype_iv); + fg_transfer_filename_tv = itemView.findViewById(R.id.fg_transfer_filename_tv); + fg_transfer_pb = itemView.findViewById(R.id.fg_transfer_pb); + fg_transfer_finished_tv = itemView.findViewById(R.id.fg_transfer_finished_tv); + fg_transfer_gap_tv = itemView.findViewById(R.id.fg_transfer_gap_tv); + fg_transfer_filelength_tv = itemView.findViewById(R.id.fg_transfer_filelength_tv); + fg_transfer_time_tv = itemView.findViewById(R.id.fg_transfer_time_tv); + fg_transfer_type_iv = itemView.findViewById(R.id.fg_transfer_type_iv); + + fg_transfer_pb.setMax(100); + } + } +} diff --git a/app/src/main/java/com/example/bean/MyBaLvApInfos.java b/app/src/main/java/com/example/bean/MyBaLvApInfos.java new file mode 100644 index 0000000..ff37c5e --- /dev/null +++ b/app/src/main/java/com/example/bean/MyBaLvApInfos.java @@ -0,0 +1,50 @@ +package com.example.bean; + +public class MyBaLvApInfos { + + private int apindex; + private String apssid; + private int apsignal; + private String apencrypt; + private boolean apbridged; + + public int getAPindex() { + return apindex; + } + + public void setAPindex(int apindex) { + this.apindex = apindex; + } + + public String getAPssid() { + return apssid; + } + + public void setAPssid(String apssid) { + this.apssid = apssid; + } + + public int getAPsignal() { + return apsignal; + } + + public void setAPsignal(int apsignal) { + this.apsignal = apsignal; + } + + public String getAPencrypt() { + return apencrypt; + } + + public void setAPencrypt(String apencrypt) { + this.apencrypt = apencrypt; + } + + public boolean getAPbridged() { + return apbridged; + } + + public void setAPbridged(boolean apbridged) { + this.apbridged = apbridged; + } +} diff --git a/app/src/main/java/com/example/bean/MyBaLvDevices.java b/app/src/main/java/com/example/bean/MyBaLvDevices.java new file mode 100644 index 0000000..03e1495 --- /dev/null +++ b/app/src/main/java/com/example/bean/MyBaLvDevices.java @@ -0,0 +1,59 @@ +package com.example.bean; + +public class MyBaLvDevices { + + private String devName; + private String devIP; + private String devMac; + private String devAccNet; + private String devAccSha; + private String devBindMAC; + + public String getDevName() { + return devName; + } + + public void setDevName(String devName) { + this.devName = devName; + } + + public String getDevIP() { + return devIP; + } + + public void setDevIP(String devIP) { + this.devIP = devIP; + } + + public String getDevMac() { + return devMac; + } + + public void setDevMac(String devMac) { + this.devMac = devMac; + } + + public String getDevAccNet() { + return devAccNet; + } + + public void setDevAccNet(String devAccNet) { + this.devAccNet = devAccNet; + } + + public String getDevAccSha() { + return devAccSha; + } + + public void setDevAccSha(String devAccSha) { + this.devAccSha = devAccSha; + } + + public String getDevBindMAC() { + return devBindMAC; + } + + public void setDevBindMAC(String devBindMAC) { + this.devBindMAC = devBindMAC; + } +} diff --git a/app/src/main/java/com/example/bean/MyPhoneBackups.java b/app/src/main/java/com/example/bean/MyPhoneBackups.java new file mode 100644 index 0000000..cb3761d --- /dev/null +++ b/app/src/main/java/com/example/bean/MyPhoneBackups.java @@ -0,0 +1,49 @@ +package com.example.bean; + +public class MyPhoneBackups { + private int fileType; + private String fileTitle; + private int fileCounts; + private boolean autoUpload; + private String firstItemUrl; + + public int getFileType() { + return fileType; + } + + public void setFileType(int fileType) { + this.fileType = fileType; + } + + public String getFileTitle() { + return fileTitle; + } + + public void setFileTitle(String fileTitle) { + this.fileTitle = fileTitle; + } + + public int getFileCounts() { + return fileCounts; + } + + public void setFileCounts(int fileCounts) { + this.fileCounts = fileCounts; + } + + public boolean isAutoUpload() { + return autoUpload; + } + + public void setAutoUpload(boolean autoUpload) { + this.autoUpload = autoUpload; + } + + public String getFirstItemUrl() { + return firstItemUrl; + } + + public void setFirstItemUrl(String firstItemUrl) { + this.firstItemUrl = firstItemUrl; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/bean/MyRecFileInfos.java b/app/src/main/java/com/example/bean/MyRecFileInfos.java new file mode 100644 index 0000000..8374082 --- /dev/null +++ b/app/src/main/java/com/example/bean/MyRecFileInfos.java @@ -0,0 +1,76 @@ +package com.example.bean; + +public class MyRecFileInfos { + private String filePath; + private String fileTitle; + private long fileSize; + private long fileDate; + private String sizeUnit; + private int itemCount; + private boolean isFile; + private boolean isSelected; + + public boolean getIsFile() { + return isFile; + } + + public void setIsFile(boolean isFile) { + this.isFile = isFile; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFileTitle() { + return fileTitle; + } + + public void setFileTitle(String fileTitle) { + this.fileTitle = fileTitle; + } + + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } + + public String getSizeUnit() { + return sizeUnit; + } + + public void setSizeUnit(String sizeUnit) { + this.sizeUnit = sizeUnit; + } + + public int getItemCount() { + return itemCount; + } + + public void setItemCount(int itemCount) { + this.itemCount = itemCount; + } + + public long getFileDate() { + return fileDate; + } + + public void setFileDate(long fileDate) { + this.fileDate = fileDate; + } + + public boolean isSelected() { + return isSelected; + } + + public void setSelected(boolean selected) { + isSelected = selected; + } +} diff --git a/app/src/main/java/com/example/bean/MyRecRemoteFileInfos.java b/app/src/main/java/com/example/bean/MyRecRemoteFileInfos.java new file mode 100644 index 0000000..c79d54e --- /dev/null +++ b/app/src/main/java/com/example/bean/MyRecRemoteFileInfos.java @@ -0,0 +1,22 @@ +package com.example.bean; + +public class MyRecRemoteFileInfos { + private String url; + private String title; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/app/src/main/java/com/example/bean/SmbFileInfos.java b/app/src/main/java/com/example/bean/SmbFileInfos.java new file mode 100644 index 0000000..23ee11b --- /dev/null +++ b/app/src/main/java/com/example/bean/SmbFileInfos.java @@ -0,0 +1,139 @@ +package com.example.bean; + +public class SmbFileInfos { + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public long getDate() { + return date; + } + + public void setDate(long date) { + this.date = date; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getCsize() { + return cSize; + } + + public void setCsize(long cSize) { + this.cSize = cSize; + } + + public boolean isCanRead() { + return canRead; + } + + public void setCanRead(boolean canRead) { + this.canRead = canRead; + } + + public boolean getIsCanWrite() { + return canWrite; + } + + public void setCanWrite(boolean canWrite) { + this.canWrite = canWrite; + } + + public boolean getIsFile() { + return isFile; + } + + public void setIsFile(boolean isFile) { + this.isFile = isFile; + } + + public boolean getIsDir() { + return isDir; + } + + public void setIsDir(boolean isDir) { + this.isDir = isDir; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getCtype() { + return cType; + } + + public int getCounts() { + return counts; + } + + public void setCounts(int counts) { + this.counts = counts; + } + + public void setCtype(String cType) { + this.cType = cType; + } + + public String getParentUrl() { + return parentUrl; + } + + public void setParentUrl(String parentUrl) { + this.parentUrl = parentUrl; + } + + public String getCanoniUrl() { + return canoniUrl; + } + + public void setCanoniUrl(String canoniUrl) { + this.canoniUrl = canoniUrl; + } + + public String getSizeUnit() { + return sizeUnit; + } + + public void setSizeUnit(String sizeUnit) { + this.sizeUnit = sizeUnit; + } + + private String name; + private long size; + private long date; + private long time; + private long cSize; + private String sizeUnit; + private boolean canRead; + private boolean canWrite; + private boolean isFile; + private boolean isDir; + private int type; + private int counts;//包含子项数目 + private String cType; + private String parentUrl;//父路径 + private String canoniUrl;//完整路径 +} diff --git a/app/src/main/java/com/example/bean/TaskInfo.java b/app/src/main/java/com/example/bean/TaskInfo.java new file mode 100644 index 0000000..5dbe20b --- /dev/null +++ b/app/src/main/java/com/example/bean/TaskInfo.java @@ -0,0 +1,189 @@ +package com.example.bean; + +import org.litepal.crud.LitePalSupport; + +import java.io.Serializable; + +public class TaskInfo extends LitePalSupport implements Serializable { + private int id; + private int indexs; + private String fileName;//文件名 + private String fileUrl;//下载地址 + private long fileLength;//文件大小 + private String dirPath;//文件夹路径 + private String tranSpeed;//速率 + private long tranFinished;//已传输大小 + private long tranTime;//耗时 + private String tranState;//传输状态:1.正在传输、2.等待传输、3.完成 + private int tranProgress;//传输进度 + private String tranGap;//仅仅是已下载、文件长度之间的分隔符 + private int upOrDownOrRemote;//标记上传、下载、远程下载 + private boolean showDirection;//是否显示传输流方向 + + public TaskInfo() { + + } + + /** + * + * @param id + * @param indexs + * @param fileName + * @param fileUrl + * @param dirPath + * @param tranSpeed + * @param tranTime + * @param tranState + * @param tranProgress + * @param tranFinished + * @param tranGap + * @param fileLength + * @param upOrDownOrRemote + * @param showDirection + */ + public TaskInfo(int id, int indexs, String fileName, String fileUrl, String dirPath, String tranSpeed, long tranTime,String tranState,int tranProgress, long tranFinished,String tranGap, long fileLength, int upOrDownOrRemote, boolean showDirection) { + this.id = id; + this.indexs = indexs; + this.fileName = fileName; + this.fileUrl = fileUrl; + this.dirPath = dirPath; + this.tranSpeed = tranSpeed; + this.tranTime = tranTime; + this.tranState = tranState; + this.tranProgress = tranProgress; + this.tranFinished = tranFinished; + this.tranGap = tranGap; + this.fileLength = fileLength; + this.upOrDownOrRemote = upOrDownOrRemote; + this.showDirection = showDirection; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getIndexs() { + return indexs; + } + + public void setIndexs(int indexs) { + this.indexs = indexs; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFileUrl() { + return fileUrl; + } + + public void setFileUrl(String fileUrl) { + this.fileUrl = fileUrl; + } + + public long getTranTime() { + return tranTime; + } + + public void setTranTime(long tranTime) { + this.tranTime = tranTime; + } + + public int getUpOrDownOrRemote() { + return upOrDownOrRemote; + } + + public void setUpOrDownOrRemote(int upOrDownOrRemote) { + this.upOrDownOrRemote = upOrDownOrRemote; + } + + public String getTranState() { + return tranState; + } + + public void setTranState(String tranState) { + this.tranState = tranState; + } + + public String getTranSpeed() { + return tranSpeed; + } + + public int getTranProgress() { + return tranProgress; + } + + public void setTranProgress(int tranProgress) { + this.tranProgress = tranProgress; + } + + public void setTranSpeed(String tranSpeed) { + this.tranSpeed = tranSpeed; + } + + public String getDirPath() { + return dirPath; + } + + public void setDirPath(String dirPath) { + this.dirPath = dirPath; + } + + public long getFileLength() { + return fileLength; + } + + public void setFileLength(long fileLength) { + this.fileLength = fileLength; + } + + public String getTranGap() { + return tranGap; + } + + public void setTranGap(String tranGap) { + this.tranGap = tranGap; + } + + public long getTranFinished() { + return tranFinished; + } + + public void setTranFinished(long fileFinished) { + this.tranFinished = tranFinished; + } + + public boolean isShowDirection() { + return showDirection; + } + + public void setShowDirection(boolean showDirection) { + this.showDirection = showDirection; + } + + @Override + public String toString() { + return "TaskInfo{" + + "id=" + id + + ", indexs=" + indexs + + ", fileName='" + fileName + '\'' + + ", fileUrl='" + fileUrl + '\'' + + ", fileLength=" + fileLength + + ", dirPath='" + dirPath + '\'' + + ", tranSpeed='" + tranSpeed + '\'' + + ", tranFinished=" + tranFinished + + ", tranTime=" + tranTime + + ", upOrDownOrRemote=" + upOrDownOrRemote + + ", showDirection=" + showDirection + + '}'; + } +} diff --git a/app/src/main/java/com/example/bean/ThreadInfo.java b/app/src/main/java/com/example/bean/ThreadInfo.java new file mode 100644 index 0000000..8a31b00 --- /dev/null +++ b/app/src/main/java/com/example/bean/ThreadInfo.java @@ -0,0 +1,62 @@ +package com.example.bean; + +import org.litepal.crud.LitePalSupport; + +public class ThreadInfo extends LitePalSupport { + private int id; + private String url; + private long start; + private long ends; + private int finished; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public long getStart() { + return start; + } + + public void setStart(long start) { + this.start = start; + } + + public long getEnd() { + return ends; + } + + public void setEnd(long ends) { + this.ends = ends; + } + + public int getFinished() { + return finished; + } + + public void setFinished(int finished) { + this.finished = finished; + } + + @Override + public String toString() { + return "ThreadInfo{" + + "id=" + id + + ", url='" + url + '\'' + + ", start=" + start + + ", end=" + ends + + ", finished=" + finished + + '}'; + } +} diff --git a/app/src/main/java/com/example/consts/Consts.java b/app/src/main/java/com/example/consts/Consts.java new file mode 100644 index 0000000..5b7875b --- /dev/null +++ b/app/src/main/java/com/example/consts/Consts.java @@ -0,0 +1,114 @@ +package com.example.consts; + +public final class Consts { + public static final String NET_HOST_HOLL = "http://192.168.80.1"; + public static final String ROOT_URL_HOLL = "smb://root:holl0311@192.168.80.1/holl/";//固定 + public static final String CANONI_URL_HOLL = "smb://root:holl0311@192.168.80.1/holl/";//随着目录的进入和回退而变化 + + /** + * + * smbpasswd -a root新增root用户配置密码 + */ + + public static final String TELNETHOST = "192.168.80.1"; + public static final int TELNETPORT = 23; + public static final String SOCKETHOST = "192.168.80.1"; + public static final int SOCKETPORT = 7888; + + //Tcp通信协议如下 + public static final String ROUTER_BEATS = ""; + public static final String ROUTER_SET_WIFI = "**&&0"; + //扫描周围AP信息 + public static final String ROUTER_SCAN_AP = ""; + //设置无线中继--(无效) + @Deprecated + public static final String ROUTER_SET_REPEATER = "LEDEw12345679"; + //获取中继的无线SSID + public static final String ROUTER_GET_REPEATER = ""; + //获取硬件版本、固件版本 + public static final String ROUTER_GET_VERSION = ""; + //获取硬盘、WIFI、MAC信息 + public static final String ROUTER_GET_INFOS = ""; + public static final String ROUTER_GET_INFO = ""; + //当前连接设备(包含操作权限) + public static final String ROUTER_ON_DEVICES = ""; + //重启、关机--(无效) + @Deprecated + public static final String ROUTER_SHUT_OR_REBOOT = "0"; + //恢复出厂设置(内部MD5加密) + public static final String RESTORE_ROUTER_BYSOCKET_FIRST = "02:00:00:00:00:00"; + public static final String RESTORE_ROUTER_BYSOCKET_TWO = "21232f297a57a5a743894a0e4a801fc3"; + public static final String RESTORE_ROUTER_BYSOCKET_THREE = "116e8505bdba16773829d490f1de37a0"; + public static final String RESTORE_ROUTER_BYSOCKET_OVER = "1"; + //访问权限控制 + public static final String ROUTER_PHONE_PERMISSION = ""; + + //Telnet命令操作如下 + public static final String CHANGE_WIFI_SSID = "uci set wireless.@wifi-iface[0].ssid=**"; + public static final String CHANGE_WIFI_KEY = "uci set wireless.@wifi-iface[0].key=**"; + public static final String CHANGE_WIFI_ENCR = "uci set wireless.@wifi-iface[0].encryption=psk-mixed+ccmp"; + public static final String CHANGE_WIFI_COMMIT = "uci commit wireless && wifi &"; + + //单独获取WiFi名称、密码 + public static final String GET_WIFI_SSID = "uci get wireless.@wifi-iface[0].ssid"; + public static final String GET_WIFI_KEY = "uci get wireless.@wifi-iface[0].key"; + + //开启中继(每次关机后开机、被桥接WIFI消失需要重新开启) + //配置 wan_wifi 网络接口 + public static final String REPEATER_SET_NETWORK_FIRST = "uci set network.wan_wifi=interface"; + public static final String REPEATER_SET_NETWORK_TWO = "uci set network.wan_wifi.ifname=wlan0"; + public static final String REPEATER_SET_NETWORK_THREE = "uci set network.wan_wifi.proto=dhcp"; + public static final String REPEATER_SET_NETWORK_OVER = "uci commit network"; + //配置 STA 接口,新增时应确保 无线桥接 处于关闭状态 + public static final String REPEATER_SET_WIRELESS_FIRST = "uci add wireless wifi-iface"; + public static final String REPEATER_SET_WIRELESS_TWO = "uci set wireless.@wifi-iface[-1].device=radio0"; + public static final String REPEATER_SET_WIRELESS_THREE = "uci set wireless.@wifi-iface[-1].network=wan_wifi"; + public static final String REPEATER_SET_WIRELESS_FOUR = "uci set wireless.@wifi-iface[-1].mode=sta"; + public static final String REPEATER_SET_WIRELESS_FIVE = "uci set wireless.@wifi-iface[-1].ssid=**"; + public static final String REPEATER_SET_WIRELESS_SIX = "uci set wireless.@wifi-iface[-1].encryption=**"; + public static final String REPEATER_SET_WIRELESS_SEVEN = "uci set wireless.@wifi-iface[-1].key=**"; + public static final String REPEATER_SET_WIRELESS_OVER = "uci commit wireless"; + //配置 apconfig文件,增加当前中继信息 + public static final String REPEATER_SET_APCONFIG_FIRST = "uci add apconfig AP0"; + public static final String REPEATER_SET_APCONFIG_TWO = "uci set apconfig.@AP0[-1].name=**"; + public static final String REPEATER_SET_APCONFIG_THREE = "uci set apconfig.@AP0[-1].key=**"; + //public static final String REPEATER_SET_APCONFIG_FOUR = "uci set apconfig.@AP0[-1].chanel=**"; + public static final String REPEATER_SET_APCONFIG_FIVE = "uci set apconfig.@AP0[-1].encryption=**"; + public static final String REPEATER_SET_APCONFIG_OVER = "uci commit apconfig"; + //配置中继开启标志 + public static final String REPEATER_ON_STASTATUS = "sed -i \"s/Wifi_Route=0/Wifi_Route=1/g\" /etc/config/StaStatus"; + + //关闭中继 + public static final String REPEATER_DEL_NETWORK = "uci delete network.wan_wifi"; + public static final String REPEATER_DEL_WIRELESS = "uci delete wireless.@wifi-iface[-1]"; + public static final String REPEATER_DEL_APCONFIG = "uci delete apconfig.@AP0[-1]"; + //配置中继关闭标志 + public static final String REPEATER_OFF_STASTATUS = "sed -i \"s/Wifi_Route=1/Wifi_Route=0/g\" /etc/config/StaStatus"; + + //判断中继是否开启,通过检测配置文件,mode为sta,代表中继的配置文件正常 + public static final String REPEATER_CHECK_STATUS = "uci get wireless.@wifi-iface[-1].mode"; + //获取中继开启时的AP名 + public static final String REPEATERED_GET_APNAME = "uci get apconfig.@AP0[-1].name"; + + //获取路由器网关 + public static final String GET_ROUTER_GATEWAY = "uci get network.lan.ipaddr"; + //软关机,重新开机后中继正常 + public static final String SHUTDOWN_ROUTER = "reboot"; + //脚本关机,安全stop后关机 + public static final String SHUTDOWN_ROUTER_BYSH = "poweroff.sh"; + //脚本恢复出厂设置 + public static final String RESTORE_ROUTER_BYSH = "reset.sh"; + + //网络配置服务生效 + public static final String NETWORK_WIFI_RELAOD = "wifi"; + public static final String NETWORK_SERVICE_REINIT = "/etc/init.d/dnsmasq restart"; + + //恢复出厂设置 + public static final String RESTORE_ROUTER_NETWORK = "uci delete network.wan_wifi"; //必须先做开启中继检测 + public static final String RESTORE_ROUTER_WIRELESS = "uci delete wireless.@wifi-iface[-1]"; + public static final String RESTORE_ROUTER_APCONFIG = "uci delete apconfig.@AP0[-1]"; + public static final String RESTORE_ROUTER_STASTATUS = "sed -i \"s/Wifi_Route=1/Wifi_Route=0/g\" /etc/config/StaStatus"; + public static final String RESTORE_ROUTER_WANSTATUS = "sed -i \"s/status=1/status=0/g\" /etc/config/WanStatus"; + + //jffs2reset: This will erase all settings and remove any installed packages. Are you sure? +} diff --git a/app/src/main/java/com/example/database/FileTrans.java b/app/src/main/java/com/example/database/FileTrans.java new file mode 100644 index 0000000..98fce09 --- /dev/null +++ b/app/src/main/java/com/example/database/FileTrans.java @@ -0,0 +1,124 @@ +package com.example.database; + +import org.litepal.annotation.Column; +import org.litepal.crud.LitePalSupport; + +public class FileTrans extends LitePalSupport { + + private int id; + private int fileType;//标记文件类型 + @Column(unique = true, nullable = false) + private String fileName; + private long fileLength; + private long fileTranTime; + private String filePath; + private String dirPath; + private int upOrDown;//标记上传、下载 + private String fileTime; + + public FileTrans() { + } + + public FileTrans(int id, int fileType, String fileName, long fileLength, long fileTranTime, String filePath, String dirPath, int upOrDown, String fileTime) { + this.id = id; + this.fileType = fileType; + this.fileName = fileName; + this.fileLength = fileLength; + this.fileTranTime = fileTranTime; + this.filePath = filePath; + this.dirPath = dirPath; + this.upOrDown = upOrDown; + this.fileTime = fileTime; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getFileType() { + return fileType; + } + + public void setFileType(int fileType) { + this.fileType = fileType; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public long getFileTranTime() { + return fileTranTime; + } + + public void setFileTranTime(long fileTranTime) { + this.fileTranTime = fileTranTime; + } + + public long getFileLength() { + return fileLength; + } + + public void setFileLength(long fileLength) { + this.fileLength = fileLength; + } + + public int getUpOrDown() { + return upOrDown; + } + + /** + * 0-上传 + * 1-下载 + * @param upOrDown + */ + public void setUpOrDown(int upOrDown) { + this.upOrDown = upOrDown; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getDirPath() { + return dirPath; + } + + public void setDirPath(String dirPath) { + this.dirPath = dirPath; + } + + public String getFileTime() { + return fileTime; + } + + public void setFileTime(String fileTime) { + this.fileTime = fileTime; + } + + @Override + public String toString() { + return "FileTrans{" + + "id=" + id + + ", fileType=" + fileType + + ", fileName='" + fileName + '\'' + + ", fileTranTime=" + fileTranTime + + ", filePath='" + filePath + '\'' + + ", dirPath='" + dirPath + '\'' + + ", upOrDown=" + upOrDown + + ", fileTime='" + fileTime + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/example/database/LiveVideoList.java b/app/src/main/java/com/example/database/LiveVideoList.java new file mode 100644 index 0000000..9215159 --- /dev/null +++ b/app/src/main/java/com/example/database/LiveVideoList.java @@ -0,0 +1,63 @@ +package com.example.database; + +import org.litepal.annotation.Column; +import org.litepal.crud.LitePalSupport; + +public class LiveVideoList extends LitePalSupport { + private int id; + @Column(nullable = false) + private String liveName; + @Column(nullable = false) + private String liveUrls; + private int liveType; + private int isPlay; + private int isCollect; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getLiveName() { + return liveName; + } + + public void setLiveName(String liveName) { + this.liveName = liveName; + } + + public String getLiveUrls() { + return liveUrls; + } + + public void setLiveUrls(String liveUrls) { + this.liveUrls = liveUrls; + } + + public int getLiveType() { + return liveType; + } + + public void setLiveType(int liveType) { + this.liveType = liveType; + } + + public int getIsPlay() { + return isPlay; + } + + public void setIsPlay(int isPlay) { + this.isPlay = isPlay; + } + + public int getIsCollect() { + return isCollect; + } + + public void setIsCollect(int isCollect) { + this.isCollect = isCollect; + } +} diff --git a/app/src/main/java/com/example/event/MessageEvent.java b/app/src/main/java/com/example/event/MessageEvent.java new file mode 100644 index 0000000..2ef9502 --- /dev/null +++ b/app/src/main/java/com/example/event/MessageEvent.java @@ -0,0 +1,68 @@ +package com.example.event; + +public class MessageEvent { + + private int eventType; + private int fileType; + private String fileName; + private String eventDirPath; + private String eventFileUrl; + private int upOrDownOrRemote; + + public MessageEvent(int eventType,int fileType,String fileName,int upOrDownOrRemote, String eventDirPath, String eventFileUrl){ + this.eventType = eventType; + this.fileType = fileType; + this.fileName = fileName; + this.upOrDownOrRemote = upOrDownOrRemote; + this.eventDirPath = eventDirPath; + this.eventFileUrl = eventFileUrl; + } + + public int getFileType() { + return fileType; + } + + public void setFileType(int fileType) { + this.fileType = fileType; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public int getUpOrDownOrRemote() { + return upOrDownOrRemote; + } + + public void setUpOrDownOrRemote(int upOrDownOrRemote) { + this.upOrDownOrRemote = upOrDownOrRemote; + } + + public int getEventType() { + return eventType; + } + + public void setEventType(int eventType) { + this.eventType = eventType; + } + + public String getEventDirPath() { + return eventDirPath; + } + + public void setEventDirPath(String eventDirPath) { + this.eventDirPath = eventDirPath; + } + + public String getEventFileUrl() { + return eventFileUrl; + } + + public void setEventFileUrl(String eventFileUrl) { + this.eventFileUrl = eventFileUrl; + } +} diff --git a/app/src/main/java/com/example/samba/MultiDownloadService.java b/app/src/main/java/com/example/samba/MultiDownloadService.java new file mode 100644 index 0000000..a159f4e --- /dev/null +++ b/app/src/main/java/com/example/samba/MultiDownloadService.java @@ -0,0 +1,125 @@ +package com.example.samba; + +import android.app.Service; +import android.content.Intent; +import android.os.Environment; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.util.Log; + +import com.example.bean.TaskInfo; + +import java.io.File; +import java.io.RandomAccessFile; +import java.net.MalformedURLException; +import java.util.LinkedHashMap; +import java.util.Map; + +import jcifs.smb.SmbFile; + +public class MultiDownloadService extends Service { + public static final String DOWNLOAD_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/com.example.wgjrouter/"; + public static final String ACTION_START = "ACTION_START"; + public static final String ACTION_STOP = "ACTION_STOP"; + public static final String ACTION_STOP_ALL = "ACTION_STOP_ALL"; + public static final String ACTION_UPDATE = "ACTION_UPDATE"; + public static final String ACTION_FINISHED = "ACTION_FINISHED"; + public static final int MSG_INIT = 0; + private InitThread mInitThread = null; + private Map mTasks = new LinkedHashMap<>(); + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + //获得Activity传递的参数 + if(intent != null && intent.getAction().equals(ACTION_START)){ + TaskInfo taskInfo = (TaskInfo) intent.getSerializableExtra("fileInfo"); + //启动初始化线程 + mInitThread = new InitThread(taskInfo); + MultiDownloadTask.mExecutorService.execute(mInitThread); + }else if(intent != null && intent.getAction().equals(ACTION_STOP)){ + TaskInfo taskInfo = (TaskInfo) intent.getSerializableExtra("fileInfo"); + //从下载集合中取出下载任务 + MultiDownloadTask task = mTasks.get(taskInfo.getIndexs()); + if(task != null){ + //停止下载任务 + task.isPause = true; + } + }else if(intent != null && intent.getAction().equals(ACTION_STOP_ALL)){ + Log.d("zouguo","全部暂停本地:" + mTasks.toString()); + for(int i = 0;i < mTasks.size();i++){ + MultiDownloadTask task = mTasks.get(i); + if(task != null){ + //停止任务 + task.isPause = true; + } + } + } + return super.onStartCommand(intent, flags, startId); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case MSG_INIT: + TaskInfo taskInfo = (TaskInfo) msg.obj; + + //启动下载任务 + MultiDownloadTask mTask = new MultiDownloadTask(MultiDownloadService.this, taskInfo,1); + mTask.download(); + //把下载任务加载到集合 + mTasks.put(taskInfo.getIndexs(),mTask); + break; + } + } + }; + + class InitThread extends Thread{ + private TaskInfo taskInfo; + + public InitThread(TaskInfo taskInfo) { + this.taskInfo = taskInfo; + } + + @Override + public void run() { + RandomAccessFile raf = null; + try { + //连接网络文件 + SmbFile smbFile = new SmbFile(taskInfo.getFileUrl()); + //获得文件长度 + long length = smbFile.getContentLength(); + //在本地创建文件 + File fileDir = new File(DOWNLOAD_PATH); + if(!fileDir.exists()){ + fileDir.mkdir(); + } + File file = new File(fileDir, taskInfo.getFileName()); + raf = new RandomAccessFile(file,"rwd"); + //设置本地文件长度 + raf.setLength(length); + taskInfo.setFileLength(length); + handler.obtainMessage(MSG_INIT, taskInfo).sendToTarget(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (Exception e){ + e.printStackTrace(); + } finally { + try { + if(raf != null){ + raf.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/app/src/main/java/com/example/samba/MultiDownloadTask.java b/app/src/main/java/com/example/samba/MultiDownloadTask.java new file mode 100644 index 0000000..58aa72c --- /dev/null +++ b/app/src/main/java/com/example/samba/MultiDownloadTask.java @@ -0,0 +1,249 @@ +package com.example.samba; + +import android.content.Context; +import android.content.Intent; + +import com.example.bean.TaskInfo; +import com.example.bean.ThreadInfo; +import com.example.samba.thread.ThreadDAO; +import com.example.samba.thread.ThreadDAOImpl; +import com.example.utils.MyFileUtils; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import jcifs.smb.SmbException; +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileInputStream; + +public class MultiDownloadTask { + private Context mContext; + private TaskInfo taskInfo; + private ThreadDAO threadDAO; + private long mFinished = 0; + public boolean isPause = false; + private int mThreadCount;//分块下载线程数 + private List mThreadList = null; + private long speedNotiSize = 10 * 1024 * 1024;//超过10M的更新时间慢 + private int slowNotiInternal = 1000;//慢时间间隔(大于speedNotiSize) + private int fastNotiInternal = 100;//快更新时间 + public static ExecutorService mExecutorService = Executors.newFixedThreadPool(2);//固定线程池 + + public MultiDownloadTask(Context mContext, TaskInfo taskInfo, int mThreadCount) { + this.mContext = mContext; + this.taskInfo = taskInfo; + this.mThreadCount = mThreadCount; + threadDAO = new ThreadDAOImpl(); + } + + public void download(){ + //读取数据库的线程信息 + List threadList = threadDAO.getThreadInfos(taskInfo.getFileUrl()); + + if(threadList.size() == 0){ + //获取每个线程下载长度 + long length = taskInfo.getFileLength() / mThreadCount; + for(int i = 0;i < mThreadCount;i++){ + //创建线程信息 + ThreadInfo threadInfo = new ThreadInfo(); + threadInfo.setId(i); + threadInfo.setUrl(taskInfo.getFileUrl()); + threadInfo.setStart(i * length); + threadInfo.setEnd((i + 1) * length - 1); + threadInfo.setFinished(0); + + if(i == mThreadCount - 1){ + threadInfo.setEnd(taskInfo.getFileLength()); + } + + //添加到线程集合 + threadList.add(threadInfo); + //向数据库插入线程信息 + threadDAO.insertThread(threadInfo); + } + } + + mThreadList = new ArrayList<>(); + //启动多线程分块下载 + for(ThreadInfo threadInfo : threadList){ + DownloadThread downloadThread = new DownloadThread(threadInfo); + MultiDownloadTask.mExecutorService.execute(downloadThread);//加入线程池 + mThreadList.add(downloadThread); + } + } + + /** + * 判断是否所有线程执行完毕 + */ + private synchronized void checkAllThreadsFinished(){ + boolean allFinished = true; + + for(DownloadThread thread : mThreadList){ + if(!thread.isFinished){ + allFinished = false; + break; + } + } + + if(allFinished){ + //删除线程信息 + threadDAO.deleteThread(taskInfo.getFileUrl()); + + //发送任务完成广播 + Intent intent = new Intent(MultiDownloadService.ACTION_FINISHED); + intent.putExtra("downloadFinishFileinfo", taskInfo); + mContext.sendBroadcast(intent); + } + } + + class DownloadThread extends Thread{ + private ThreadInfo mThreadInfo; + public boolean isFinished = false;//标记线程是否结束 + + public DownloadThread(ThreadInfo mThreadInfo) { + this.mThreadInfo = mThreadInfo; + } + + @Override + public void run() { + SmbFileInputStream sfis = null; + BufferedOutputStream bos = null; + RandomAccessFile raf = null; + try { + //设置下载位置 + SmbFile smbFile = new SmbFile(mThreadInfo.getUrl()); + long start = mThreadInfo.getStart() + mThreadInfo.getFinished(); + +// Log.d("zouguo","---------------线程:" + mThreadInfo.getId() + "-----------------"); +// Log.d("zouguo","初始start:" + start); +// Log.d("zouguo","getEnd():" + mThreadInfo.getEnd()); +// Log.d("zouguo","--------------------------------"); + + smbFile.setRequestProperty("Range","bytes=" + start + "-" + mThreadInfo.getEnd()); + //设置文件写入位置 + File file = new File(MultiDownloadService.DOWNLOAD_PATH, taskInfo.getFileName()); + raf = new RandomAccessFile(file,"rwd"); + raf.seek(start); + + mFinished += mThreadInfo.getFinished(); + +// Log.d("zouguo","已下载getFinished():" + mThreadInfo.getFinished()); +// Log.d("zouguo","总计下载mFinished:" + mFinished); +// Log.d("zouguo","开始下载:" + mThreadInfo.toString()); +// Log.d("zouguo","起始位start:" + start); +// Log.d("zouguo","--------------------------------"); + + //开始下载 + sfis = new SmbFileInputStream(smbFile); + bos = new BufferedOutputStream(new FileOutputStream(file)); + + byte[] buffer = new byte[8 * 1024]; + int bufferzLen = -1; + long beginTime = System.currentTimeMillis(); + long notiTime = System.currentTimeMillis(); + + Intent intent = new Intent(MultiDownloadService.ACTION_UPDATE); + + int i = 0; + while((bufferzLen = sfis.read(buffer)) != -1){ + bos.write(buffer,0,bufferzLen); + bos.flush(); + + //累加整个文件的完成进度 + mFinished += bufferzLen; + //累加每个线程完成的进度 + mThreadInfo.setFinished(mThreadInfo.getFinished() + bufferzLen); + + i++; + + long notifiedTime = System.currentTimeMillis() - notiTime; + long consumeTime = System.currentTimeMillis() - beginTime; + if(taskInfo.getFileLength() > speedNotiSize){ + //文件大的刷新慢 + if(notifiedTime > slowNotiInternal){ + notiTime = System.currentTimeMillis(); + + long speed = i * bufferzLen; + + intent.putExtra("index", taskInfo.getIndexs()); + intent.putExtra("downloadProgress",(int)(mFinished * 1.0f / taskInfo.getFileLength() * 100)); + intent.putExtra("downloadSpeed", MyFileUtils.getInstance().formatTranSpeed(speed,2)); + intent.putExtra("downloadFinished",mFinished); + intent.putExtra("downloadFileLength",taskInfo.getFileLength()); + intent.putExtra("downloadUseTime",consumeTime); + mContext.sendBroadcast(intent); + + taskInfo.setTranTime(consumeTime); + + i = 0; + } + }else{ + //文件比较小,刷新要快 + if(notifiedTime > fastNotiInternal){ + notiTime = System.currentTimeMillis(); + + long speed = i * bufferzLen; + + intent.putExtra("index", taskInfo.getIndexs()); + intent.putExtra("downloadProgress",(int)(mFinished * 1.0f / taskInfo.getFileLength() * 100)); + intent.putExtra("downloadSpeed", MyFileUtils.getInstance().formatTranSpeed(speed,2)); + intent.putExtra("downloadFinished",mFinished); + intent.putExtra("downloadFileLength",taskInfo.getFileLength()); + intent.putExtra("downloadUseTime",consumeTime); + mContext.sendBroadcast(intent); + + taskInfo.setTranTime(consumeTime); + + i = 0; + } + } + + //下载暂停,保存进度 + if(isPause){ + threadDAO.updateThread(mThreadInfo.getId(),mThreadInfo.getUrl(),mThreadInfo.getFinished()); + return; + } + } + + //标识线程执行完毕 + isFinished = true; + //检查下载任务是否完成 + checkAllThreadsFinished(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (SmbException e) { + e.printStackTrace(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e){ + e.printStackTrace(); + } finally { + try { + if(sfis != null){ + sfis.close(); + } + if(bos != null){ + bos.close(); + } + if(raf != null){ + raf.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/app/src/main/java/com/example/samba/MultiRemoteDownloadService.java b/app/src/main/java/com/example/samba/MultiRemoteDownloadService.java new file mode 100644 index 0000000..ca152eb --- /dev/null +++ b/app/src/main/java/com/example/samba/MultiRemoteDownloadService.java @@ -0,0 +1,140 @@ +package com.example.samba; + +import android.app.Service; +import android.content.Intent; +import android.os.Environment; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.util.Log; + +import com.example.bean.TaskInfo; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.LinkedHashMap; +import java.util.Map; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class MultiRemoteDownloadService extends Service { + public static final String DOWNLOAD_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/com.example.wgjrouter/"; + public static final String ACTION_START = "ACTION_START_REMOTE"; + public static final String ACTION_STOP = "ACTION_STOP_REMOTE"; + public static final String ACTION_START_ALL = "ACTION_START_REMOTE_ALL"; + public static final String ACTION_STOP_ALL = "ACTION_STOP_REMOTE_ALL"; + public static final String ACTION_UPDATE = "ACTION_UPDATE_REMOTE"; + public static final String ACTION_FINISHED = "ACTION_FINISHED_REMOTE"; + public static final int MSG_INIT = 0; + private InitThread mInitThread = null; + private Map mTasks = new LinkedHashMap<>(); + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + //获得Activity传递的参数 + if(intent != null && intent.getAction().equals(ACTION_START)){ + TaskInfo taskInfo = (TaskInfo) intent.getSerializableExtra("fileInfo"); + + //启动初始化线程 + mInitThread = new InitThread(taskInfo); + MultiDownloadTask.mExecutorService.execute(mInitThread); + }else if(intent != null && intent.getAction().equals(ACTION_STOP)){ + TaskInfo taskInfo = (TaskInfo) intent.getSerializableExtra("fileInfo"); + //从下载集合中取出下载任务 + MultiRemoteDownloadTask task = mTasks.get(taskInfo.getIndexs()); + if(task != null){ + //停止下载任务 + task.isPause = true; + } + }else if(intent != null && intent.getAction().equals(ACTION_STOP_ALL)){ + Log.d("zouguo","全部暂停远程:" + mTasks.toString()); + for(int i = 0;i < mTasks.size();i++){ + MultiRemoteDownloadTask task = mTasks.get(i); + if(task != null){ + //停止任务 + task.isPause = true; + } + } + } + return super.onStartCommand(intent, flags, startId); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case MSG_INIT: + TaskInfo taskInfo = (TaskInfo) msg.obj; + + //启动下载任务 + MultiRemoteDownloadTask mTask = new MultiRemoteDownloadTask(MultiRemoteDownloadService.this, taskInfo,1); + mTask.download(); + //把下载任务加载到集合 + mTasks.put(taskInfo.getIndexs(),mTask); + break; + } + } + }; + + class InitThread extends Thread{ + private TaskInfo taskInfo; + + public InitThread(TaskInfo taskInfo) { + this.taskInfo = taskInfo; + } + + @Override + public void run() { + //连接网络文件 + OkHttpClient okHttpClient = new OkHttpClient(); + Request request = new Request.Builder() + .url(taskInfo.getFileUrl()) + .method("GET", null) + .build(); + Call call = okHttpClient.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + //获得文件长度 + long length = response.body().contentLength(); + //在本地创建文件 + File fileDir = new File(DOWNLOAD_PATH); + if(!fileDir.exists()){ + fileDir.mkdir(); + } + File file = new File(fileDir, taskInfo.getFileName()); + RandomAccessFile raf = new RandomAccessFile(file,"rwd"); + //设置本地文件长度 + raf.setLength(length); + taskInfo.setFileLength(length); + handler.obtainMessage(MSG_INIT, taskInfo).sendToTarget(); + + try { + raf.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/samba/MultiRemoteDownloadTask.java b/app/src/main/java/com/example/samba/MultiRemoteDownloadTask.java new file mode 100644 index 0000000..29edcff --- /dev/null +++ b/app/src/main/java/com/example/samba/MultiRemoteDownloadTask.java @@ -0,0 +1,230 @@ +package com.example.samba; + +import android.content.Context; +import android.content.Intent; + +import com.example.bean.TaskInfo; +import com.example.bean.ThreadInfo; +import com.example.samba.thread.ThreadDAO; +import com.example.samba.thread.ThreadDAOImpl; +import com.example.utils.MyFileUtils; + +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.List; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class MultiRemoteDownloadTask { + private Context mContext; + private TaskInfo taskInfo; + private ThreadDAO threadDAO; + private long mFinished = 0; + public boolean isPause = false; + private int mThreadCount;//分块下载线程数 + private List mThreadList = null; + private long speedNotiSize = 10 * 1024 * 1024;//超过10M的更新时间慢 + private int slowNotiInternal = 1000;//慢时间间隔(大于speedNotiSize) + private int fastNotiInternal = 100;//快更新时间 + + public MultiRemoteDownloadTask(Context mContext, TaskInfo taskInfo, int mThreadCount) { + this.mContext = mContext; + this.taskInfo = taskInfo; + this.mThreadCount = mThreadCount; + threadDAO = new ThreadDAOImpl(); + } + + public void download(){ + //读取数据库的线程信息 + List threadList = threadDAO.getThreadInfos(taskInfo.getFileUrl()); + + if(threadList.size() == 0){ + //获取每个线程下载长度 + long length = taskInfo.getFileLength() / mThreadCount; + for(int i = 0;i < mThreadCount;i++){ + //创建线程信息 + ThreadInfo threadInfo = new ThreadInfo(); + threadInfo.setId(i); + threadInfo.setUrl(taskInfo.getFileUrl()); + threadInfo.setStart(i * length); + threadInfo.setEnd((i + 1) * length - 1); + threadInfo.setFinished(0); + + if(i == mThreadCount - 1){ + threadInfo.setEnd(taskInfo.getFileLength()); + } + + //添加到线程集合 + threadList.add(threadInfo); + //向数据库插入线程信息 + threadDAO.insertThread(threadInfo); + } + } + + mThreadList = new ArrayList<>(); + //启动多线程分块下载 + for(ThreadInfo threadInfo : threadList){ + DownloadThread downloadThread = new DownloadThread(threadInfo); + MultiDownloadTask.mExecutorService.execute(downloadThread);//加入线程池 + mThreadList.add(downloadThread); + } + } + + /** + * 判断是否所有线程执行完毕 + */ + private synchronized void checkAllThreadsFinished(){ + boolean allFinished = true; + + for(DownloadThread thread : mThreadList){ + if(!thread.isFinished){ + allFinished = false; + break; + } + } + + if(allFinished){ + //删除线程信息 + threadDAO.deleteThread(taskInfo.getFileUrl()); + + //发送任务完成广播 + Intent intent = new Intent(MultiRemoteDownloadService.ACTION_FINISHED); + intent.putExtra("downloadRemoteFinishFileinfo", taskInfo); + mContext.sendBroadcast(intent); + } + } + + class DownloadThread extends Thread{ + private ThreadInfo mThreadInfo; + public boolean isFinished = false;//标记线程是否结束 + + public DownloadThread(ThreadInfo mThreadInfo) { + this.mThreadInfo = mThreadInfo; + } + + @Override + public void run() { + final long start = mThreadInfo.getStart() + mThreadInfo.getFinished(); + + OkHttpClient ohClient = new OkHttpClient(); + Request req = new Request.Builder() + .addHeader("Range","bytes=" + start + "-" + mThreadInfo.getEnd()) + .method("GET",null) + .url(mThreadInfo.getUrl()) + .build(); + Call call = ohClient.newCall(req); + call.enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + InputStream is; + RandomAccessFile raf; + BufferedOutputStream bos; + try { + is = response.body().byteStream(); + + //设置文件写入位置 + File file = new File(MultiDownloadService.DOWNLOAD_PATH, taskInfo.getFileName()); + raf = new RandomAccessFile(file,"rwd"); + raf.seek(start); + bos = new BufferedOutputStream(new FileOutputStream(file)); + + mFinished += mThreadInfo.getFinished(); + + byte[] buffer = new byte[8 * 1024]; + int bufferzLen = -1; + long beginTime = System.currentTimeMillis(); + long notiTime = System.currentTimeMillis(); + + Intent intent = new Intent(MultiRemoteDownloadService.ACTION_UPDATE); + + int i = 0; + while ((bufferzLen = is.read(buffer)) != -1){ + bos.write(buffer,0,bufferzLen); + bos.flush(); + + //累加整个文件的完成进度 + mFinished += bufferzLen; + //累加每个线程完成的进度 + mThreadInfo.setFinished(mThreadInfo.getFinished() + bufferzLen); + + i++; + + long notifiedTime = System.currentTimeMillis() - notiTime; + long consumeTime = System.currentTimeMillis() - beginTime; + if(taskInfo.getFileLength() > speedNotiSize){ + //文件大的刷新慢 + if(notifiedTime > slowNotiInternal){ + notiTime = System.currentTimeMillis(); + + long speed = i * bufferzLen; + + intent.putExtra("index", taskInfo.getIndexs()); + intent.putExtra("downloadProgress",(int)(mFinished * 1.0f / taskInfo.getFileLength() * 100)); + intent.putExtra("downloadSpeed", MyFileUtils.getInstance().formatTranSpeed(speed,2)); + intent.putExtra("downloadFinished",mFinished); + intent.putExtra("downloadFileLength",taskInfo.getFileLength()); + intent.putExtra("downloadUseTime",consumeTime); + mContext.sendBroadcast(intent); + + taskInfo.setTranTime(consumeTime); + + i = 0; + } + }else{ + //文件比较小,刷新要快 + if(notifiedTime > fastNotiInternal){ + notiTime = System.currentTimeMillis(); + + long speed = i * bufferzLen; + + intent.putExtra("index", taskInfo.getIndexs()); + intent.putExtra("downloadProgress",(int)(mFinished * 1.0f / taskInfo.getFileLength() * 100)); + intent.putExtra("downloadSpeed", MyFileUtils.getInstance().formatTranSpeed(speed,2)); + intent.putExtra("downloadFinished",mFinished); + intent.putExtra("downloadFileLength",taskInfo.getFileLength()); + intent.putExtra("downloadUseTime",consumeTime); + mContext.sendBroadcast(intent); + + taskInfo.setTranTime(consumeTime); + + i = 0; + } + } + + //下载暂停,保存进度 + if(isPause){ + threadDAO.updateThread(mThreadInfo.getId(),mThreadInfo.getUrl(),mThreadInfo.getFinished()); + return; + } + } + + //标识线程执行完毕 + isFinished = true; + //检查下载任务是否完成 + checkAllThreadsFinished(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + + } + } + }); + } + } +} diff --git a/app/src/main/java/com/example/samba/MultiUploadService.java b/app/src/main/java/com/example/samba/MultiUploadService.java new file mode 100644 index 0000000..71a44f7 --- /dev/null +++ b/app/src/main/java/com/example/samba/MultiUploadService.java @@ -0,0 +1,4 @@ +package com.example.samba; + +public class MultiUploadService { +} diff --git a/app/src/main/java/com/example/samba/MultiUploadTask.java b/app/src/main/java/com/example/samba/MultiUploadTask.java new file mode 100644 index 0000000..9fd4236 --- /dev/null +++ b/app/src/main/java/com/example/samba/MultiUploadTask.java @@ -0,0 +1,4 @@ +package com.example.samba; + +public class MultiUploadTask { +} diff --git a/app/src/main/java/com/example/samba/SambaUtils.java b/app/src/main/java/com/example/samba/SambaUtils.java new file mode 100644 index 0000000..be06b2a --- /dev/null +++ b/app/src/main/java/com/example/samba/SambaUtils.java @@ -0,0 +1,238 @@ +package com.example.samba; + +import android.app.NotificationManager; +import android.os.Environment; +import android.util.Log; + +import com.example.bean.SmbFileInfos; +import com.google.gson.Gson; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import jcifs.smb.NtlmAuthenticator; +import jcifs.smb.NtlmPasswordAuthentication; +import jcifs.smb.SmbAuthException; +import jcifs.smb.SmbException; +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileFilter; +import jcifs.smb.SmbFileInputStream; +import jcifs.smb.SmbFileOutputStream; +import jcifs.smb.SmbFilenameFilter; + +public class SambaUtils { + private static SambaUtils sambaUtils = null; + private String pathJson = ""; + + Gson gson = new Gson(); + + public static synchronized SambaUtils getInstance(boolean newClass){ + if(newClass){ + //切换路由器时,此处生成新类 + return new SambaUtils(); + } + + if(sambaUtils == null) { + return new SambaUtils(); + } + return sambaUtils; + } + + public String getPathDirFile(final String path){ + try { +// NtlmPasswordAuthentication apa = new NtlmPasswordAuthentication(null,"root","w132836zY."); + SmbFile smbFile = new SmbFile(path); + + if(!smbFile.exists()){ + Log.d("zouguo","地址不存在"); + }else{ + SmbFile[] files = smbFile.listFiles(); + List listSmbFileInfos = new ArrayList<>(); + + for(SmbFile f:files){ + if(!f.isHidden()){ + /** + * 隐藏目录不支持显示 + * 缘由:隐藏目录无法正常返回父目录 + */ + SmbFileInfos smbFileInfos = new SmbFileInfos(); + smbFileInfos.setName(f.getName()); + smbFileInfos.setDate(f.getDate()); + smbFileInfos.setTime(f.createTime()); + smbFileInfos.setCsize(f.getContentLength()); + smbFileInfos.setCanRead(f.canRead()); + smbFileInfos.setCanWrite(f.canWrite()); + smbFileInfos.setIsFile(f.isFile()); + smbFileInfos.setIsDir(f.isDirectory()); + smbFileInfos.setType(f.getType()); + smbFileInfos.setCtype(f.getContentType()); + smbFileInfos.setParentUrl(f.getParent()); + smbFileInfos.setCanoniUrl(f.getCanonicalPath()); + + if(f.isDirectory()){ + /** + * 文件夹,统计出下层子项数目 + * 注:此操作非常耗时 + */ + //smbFileInfos.setCounts(f.list().length); + }else{ + /** + * 将long型的文件大小转为可读性 + */ + if(f.length() <= 1024){ + //Byte + smbFileInfos.setSize(f.length()); + smbFileInfos.setSizeUnit("B"); + }else if(f.length() <= 1024*1024){ + //KByte + smbFileInfos.setSize(f.length()/1024); + smbFileInfos.setSizeUnit("KB"); + }else if(f.length() <= 1024*1024*1024){ + //MByte + smbFileInfos.setSize(f.length()/1024/1024); + smbFileInfos.setSizeUnit("MB"); + }else if(f.length() <= 1024*1024*1024*1024){ + //GByte + smbFileInfos.setSize(f.length()/1024/1024/1024); + smbFileInfos.setSizeUnit("GB"); + }else{ + smbFileInfos.setSize(0); + smbFileInfos.setSizeUnit("error"); + } + } + + listSmbFileInfos.add(smbFileInfos); + } + } + + pathJson = gson.toJson(listSmbFileInfos); + } + }catch (SmbAuthException e){ + e.printStackTrace(); + pathJson = "Error:" + e.getMessage(); + }catch (SmbException e){ + e.printStackTrace(); + pathJson = "Error:" + e.getMessage(); + }catch (MalformedURLException e){ + e.printStackTrace(); + pathJson = "Error:" + e.getMessage(); + }catch (Exception e){ + e.printStackTrace(); + pathJson = "Error:" + e.getMessage(); + } + return pathJson; + } + + public boolean newFolder(String currentDir,String folderName){ + boolean newFolderIsOK = false; + + try { + SmbFile smbFileNewFolder = new SmbFile(currentDir + folderName); + smbFileNewFolder.mkdirs(); + + newFolderIsOK = true; + }catch (SmbException e){ + e.printStackTrace(); + } catch (MalformedURLException e){ + e.printStackTrace(); + } + + return newFolderIsOK; + } + + public boolean deleteItem(String currentDir,String folderName){ + boolean isDelOk = false; + + try { + SmbFile smbFileDelFolder = new SmbFile(currentDir + folderName); + smbFileDelFolder.delete(); + + isDelOk = true; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (SmbException e) { + e.printStackTrace(); + } + + return isDelOk; + } + + public boolean checkFileOrDirExist(String path){ + try { + SmbFile smbFile = new SmbFile(path); + + if(smbFile.exists()){ + return true; + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (SmbException e) { + e.printStackTrace(); + } + return false; + } + + /** + * 分析文件夹下的子项数目 + * @param dirPath + * @return + */ + public List countDirSon(String dirPath){ + List listSize = new ArrayList<>(); + int dirCount = 0; + int fileCount = 0; + + try { + SmbFile smbFile = new SmbFile(dirPath); + SmbFile[] smblist = smbFile.listFiles(); + + for(SmbFile f : smblist){ + if(f.isFile()){ + fileCount++; + }else{ + dirCount++; + } + } + + listSize.add(smblist.length); + listSize.add(fileCount); + listSize.add(dirCount); + return listSize; + } catch (MalformedURLException e) { + e.printStackTrace(); + return null; + } catch (SmbException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 重命名 + * @param pathFrom + * @param pathTo + * @return + */ + public boolean renameFile(String pathFrom,String pathTo){ + try { + SmbFile smbFrom = new SmbFile(pathFrom); + SmbFile smbTo = new SmbFile(pathTo); + smbFrom.renameTo(smbTo); + + return true; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (SmbException e) { + e.printStackTrace(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/samba/intentservice/MyIntentServiceDownload.java b/app/src/main/java/com/example/samba/intentservice/MyIntentServiceDownload.java new file mode 100644 index 0000000..28630a3 --- /dev/null +++ b/app/src/main/java/com/example/samba/intentservice/MyIntentServiceDownload.java @@ -0,0 +1,76 @@ +package com.example.samba.intentservice; + +import android.app.IntentService; +import android.content.Intent; +import android.os.IBinder; +import android.os.Message; +import android.util.Log; + +public class MyIntentServiceDownload extends IntentService { + public static final String DOWNLOAD_URL = "download_url"; + public static final String INDEX_FLAG = "index_flag"; + public static UpdateUI updateUI; + + public static void setUpdateUI(UpdateUI updateUIInterface){ + updateUI = updateUIInterface; + } + + public MyIntentServiceDownload() { + super("MyIntentServiceDownload"); + } + + @Override + protected void onHandleIntent(Intent intent) { + Log.d("zouguo","Thread id is " + Thread.currentThread().getId()); + + boolean isDownOk = downloadFile(intent.getStringExtra(DOWNLOAD_URL)); + Message msg = new Message(); + msg.what = intent.getIntExtra(INDEX_FLAG,0); + msg.obj = isDownOk; + if(updateUI != null){ + updateUI.updateUI(msg); + } + } + + @Override + public void onCreate() { + super.onCreate(); + Log.d("zouguo","onCreate"); + } + + @Override + public void onStart(Intent intent, int startId) { + super.onStart(intent, startId); + Log.d("zouguo","onStart " + startId); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d("zouguo","onStartCommand " + startId); + return super.onStartCommand(intent, flags, startId); + } + + @Override + public IBinder onBind(Intent intent) { + Log.d("zouguo","onBind"); + return super.onBind(intent); + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d("zouguo","onDestroy IntentService"); + } + + public interface UpdateUI{ + void updateUI(Message message); + } + + //下载具体实现 + private boolean downloadFile(String downloadUrl){ + boolean isOk = false; + + + return isOk; + } +} diff --git a/app/src/main/java/com/example/samba/single/INetDownloadCallBack.java b/app/src/main/java/com/example/samba/single/INetDownloadCallBack.java new file mode 100644 index 0000000..e8c6592 --- /dev/null +++ b/app/src/main/java/com/example/samba/single/INetDownloadCallBack.java @@ -0,0 +1,12 @@ +package com.example.samba.single; + +import java.io.File; + +public interface INetDownloadCallBack { + //成功回调 + void success(File localFile,long useTime); + //进度回调 + void progress(int progress); + //失败回调 + void failed(Throwable throwable); +} diff --git a/app/src/main/java/com/example/samba/single/INetUploadCallBack.java b/app/src/main/java/com/example/samba/single/INetUploadCallBack.java new file mode 100644 index 0000000..4a932eb --- /dev/null +++ b/app/src/main/java/com/example/samba/single/INetUploadCallBack.java @@ -0,0 +1,10 @@ +package com.example.samba.single; + +public interface INetUploadCallBack { + //成功回调 + void success(String remoteUrl,int useTime); + //进度回调 + void progress(int progress); + //失败回调 + void failed(Throwable throwable); +} diff --git a/app/src/main/java/com/example/samba/single/ISambaTransManager.java b/app/src/main/java/com/example/samba/single/ISambaTransManager.java new file mode 100644 index 0000000..c1c9687 --- /dev/null +++ b/app/src/main/java/com/example/samba/single/ISambaTransManager.java @@ -0,0 +1,10 @@ +package com.example.samba.single; + +import java.io.File; + +public interface ISambaTransManager { + //文件下载 + void download(String url, File localFile,INetDownloadCallBack callBack); + //文件上传 + void upload(File file,String remoteUrl,INetUploadCallBack callBack); +} diff --git a/app/src/main/java/com/example/samba/single/JcifsSambaTransManager.java b/app/src/main/java/com/example/samba/single/JcifsSambaTransManager.java new file mode 100644 index 0000000..836e074 --- /dev/null +++ b/app/src/main/java/com/example/samba/single/JcifsSambaTransManager.java @@ -0,0 +1,106 @@ +package com.example.samba.single; + +import android.os.Handler; +import android.os.Looper; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.UnknownHostException; + +import jcifs.smb.SmbException; +import jcifs.smb.SmbFile; +import jcifs.smb.SmbFileInputStream; + +public class JcifsSambaTransManager implements ISambaTransManager { + private static Handler handler = new Handler(Looper.getMainLooper()); + + @Override + public void download(String url, File targetDir, final INetDownloadCallBack callBack) { + long beginTime = System.currentTimeMillis(); + + SmbFileInputStream sfis = null; + BufferedOutputStream bos = null; + + try { + try { + SmbFile smbDown = new SmbFile(url); + final File localFile = new File(targetDir + "/" + smbDown.getName()); + sfis = new SmbFileInputStream(smbDown); + bos = new BufferedOutputStream(new FileOutputStream(localFile)); + + byte[] bt = new byte[8 * 1024]; + final long totalLen = smbDown.length(); + long curLen = 0; + + int bufferzLen = 0; + + while((bufferzLen = sfis.read(bt)) != -1){ + bos.write(bt,0,bufferzLen); + bos.flush(); + curLen += bufferzLen; + + final long finalCurlen = curLen; + + handler.post(new Runnable() { + @Override + public void run() { + callBack.progress((int)(finalCurlen * 1.0f / totalLen * 100)); + } + }); + } + + final long useTime = System.currentTimeMillis() - beginTime; + + handler.post(new Runnable() { + @Override + public void run() { + callBack.success(localFile,useTime); + } + }); + } catch (final MalformedURLException e) { + e.printStackTrace(); + } catch (final SmbException e) { + e.printStackTrace(); + } catch (final UnknownHostException e) { + e.printStackTrace(); + } catch (final FileNotFoundException e) { + e.printStackTrace(); + } catch (final IOException e){ + e.printStackTrace(); + } + } catch (final Throwable e) { + e.printStackTrace(); + + handler.post(new Runnable() { + @Override + public void run() { + callBack.failed(e); + } + }); + } finally { + try { + if(sfis != null) + sfis.close(); + if(bos != null) + bos.close(); + } catch (final IOException e) { + e.printStackTrace(); + handler.post(new Runnable() { + @Override + public void run() { + callBack.failed(e); + } + }); + } + } + } + + @Override + public void upload(File file, String targetUrl, INetUploadCallBack callBack) { + + } +} diff --git a/app/src/main/java/com/example/samba/single/SambaTrans.java b/app/src/main/java/com/example/samba/single/SambaTrans.java new file mode 100644 index 0000000..c12eea0 --- /dev/null +++ b/app/src/main/java/com/example/samba/single/SambaTrans.java @@ -0,0 +1,17 @@ +package com.example.samba.single; + +public class SambaTrans { + private static SambaTrans sInstance = new SambaTrans(); + + private ISambaTransManager iSambaTransManager = new JcifsSambaTransManager(); + + public ISambaTransManager getiSambaTransManager(){ + return iSambaTransManager; + } + + public static SambaTrans getInstance(){ + return sInstance; + } + + +} diff --git a/app/src/main/java/com/example/samba/single/Single.java b/app/src/main/java/com/example/samba/single/Single.java new file mode 100644 index 0000000..91bbe77 --- /dev/null +++ b/app/src/main/java/com/example/samba/single/Single.java @@ -0,0 +1,64 @@ +package com.example.samba.single; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; + +import com.example.wgjrouter.R; + +import java.io.File; +import java.util.ArrayList; + + +public class Single extends AppCompatActivity { + private Toolbar download_text_toolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.single); + + initView(); + + Intent getIntent = getIntent(); + ArrayList queue_url = getIntent.getStringArrayListExtra("queue_url"); + + Log.d("zouguo","Single:" + queue_url.toString()); + + String url = "smb://root:holl0311@192.168.80.1/holl/sdb1/安全工作规程(电力监控部分)习题集.doc"; + + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File targetDir = new File(file.getPath() + "/com.example.wgjrouter"); + SambaTrans.getInstance().getiSambaTransManager().download(url, targetDir, new INetDownloadCallBack() { + @Override + public void success(File localFile,long useTime) { + Log.d("zouguo","localFile:" + localFile.getPath() + "--耗时:" + useTime); + } + + @Override + public void progress(int progress) { + Log.d("zouguo","progress:" + progress); + } + + @Override + public void failed(Throwable throwable) { + Log.d("zouguo","throwable:" + throwable.toString()); + } + }); + } + + private void initView(){ + download_text_toolbar = findViewById(R.id.download_text_toolbar); + download_text_toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} diff --git a/app/src/main/java/com/example/samba/thread/TaskDAO.java b/app/src/main/java/com/example/samba/thread/TaskDAO.java new file mode 100644 index 0000000..85181e3 --- /dev/null +++ b/app/src/main/java/com/example/samba/thread/TaskDAO.java @@ -0,0 +1,36 @@ +package com.example.samba.thread; + +import com.example.bean.TaskInfo; +import com.example.database.FileTrans; + +import java.util.List; + +public interface TaskDAO { + /** + * 添加任务 + * @param taskInfo + */ + void insertTask(TaskInfo taskInfo); + + /** + * 添加完成任务 + * @param fileTrans + */ + void insertOverTask(FileTrans fileTrans); + + /** + * 下载任务列表,本地、远程 + */ + List getDownloadTaskInfos(); + + /** + * 上传任务列表 + */ + List getUploadTaskInfos(); + + /** + * 删除任务 + * @param url + */ + void deleteTask(String url); +} diff --git a/app/src/main/java/com/example/samba/thread/TaskDAOImpl.java b/app/src/main/java/com/example/samba/thread/TaskDAOImpl.java new file mode 100644 index 0000000..8e69447 --- /dev/null +++ b/app/src/main/java/com/example/samba/thread/TaskDAOImpl.java @@ -0,0 +1,35 @@ +package com.example.samba.thread; + +import com.example.bean.TaskInfo; +import com.example.database.FileTrans; + +import org.litepal.LitePal; + +import java.util.List; + +public class TaskDAOImpl implements TaskDAO { + @Override + public synchronized void insertTask(TaskInfo taskInfo) { + taskInfo.save(); + } + + @Override + public synchronized void insertOverTask(FileTrans fileTrans) { + fileTrans.save(); + } + + @Override + public List getDownloadTaskInfos() { + return LitePal.where("upordownorremote = ? or upordownorremote = ? ","1","2").find(TaskInfo.class); + } + + @Override + public List getUploadTaskInfos() { + return LitePal.where("upordownorremote = ?","0").find(TaskInfo.class); + } + + @Override + public synchronized void deleteTask(String url) { + LitePal.deleteAll(TaskInfo.class,"fileurl = ?",url); + } +} diff --git a/app/src/main/java/com/example/samba/thread/ThreadDAO.java b/app/src/main/java/com/example/samba/thread/ThreadDAO.java new file mode 100644 index 0000000..e7b58c1 --- /dev/null +++ b/app/src/main/java/com/example/samba/thread/ThreadDAO.java @@ -0,0 +1,42 @@ +package com.example.samba.thread; + +import com.example.bean.ThreadInfo; + +import java.util.List; + +public interface ThreadDAO { + /** + * 插入线程信息 + * @param threadInfo + */ + void insertThread(ThreadInfo threadInfo); + + /** + * 删除线程信息 + * @param url + */ + void deleteThread(String url); + + /** + * 更新线程下载进度 + * @param thread_id + * @param url + * @param finished + */ + void updateThread(int thread_id,String url,int finished); + + /** + * 获取文件的线程信息 + * @param url + * @return + */ + List getThreadInfos(String url); + + /** + * 判断线程信息是否存在 + * @param thread_id + * @param url + * @return + */ + boolean isExists(int thread_id,String url); +} diff --git a/app/src/main/java/com/example/samba/thread/ThreadDAOImpl.java b/app/src/main/java/com/example/samba/thread/ThreadDAOImpl.java new file mode 100644 index 0000000..d278947 --- /dev/null +++ b/app/src/main/java/com/example/samba/thread/ThreadDAOImpl.java @@ -0,0 +1,38 @@ +package com.example.samba.thread; + +import android.util.Log; + +import com.example.bean.ThreadInfo; + +import org.litepal.LitePal; + +import java.util.List; + +public class ThreadDAOImpl implements ThreadDAO { + @Override + public synchronized void insertThread(ThreadInfo threadInfo) { + threadInfo.save(); + } + + @Override + public synchronized void deleteThread(String url) { + LitePal.deleteAll(ThreadInfo.class,"url = ?",url); + } + + @Override + public synchronized void updateThread(int thread_id,String url,int finished) { + ThreadInfo tI = LitePal.where("id = ? and url = ?",thread_id+"",url).findFirst(ThreadInfo.class); + tI.setFinished(finished); + tI.save(); + } + + @Override + public List getThreadInfos(String url) { + return LitePal.where("url = ?",url).find(ThreadInfo.class); + } + + @Override + public boolean isExists(int thread_id,String url) { + return LitePal.where("id = ? and url = ?",thread_id+"",url).find(ThreadInfo.class).isEmpty(); + } +} diff --git a/app/src/main/java/com/example/utils/MyDateUtils.java b/app/src/main/java/com/example/utils/MyDateUtils.java new file mode 100644 index 0000000..c6364c8 --- /dev/null +++ b/app/src/main/java/com/example/utils/MyDateUtils.java @@ -0,0 +1,40 @@ +package com.example.utils; + +import android.util.Log; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class MyDateUtils { + private static MyDateUtils myDateUtils; + private SimpleDateFormat sdf; + + public static MyDateUtils getInstance(){ + if(myDateUtils == null){ + myDateUtils = new MyDateUtils(); + } + return myDateUtils; + } + + public String getCurrentDate(long timestamp){ + sdf = new SimpleDateFormat("yy/MM/dd HH:mm"); + Date date = new Date(timestamp); + return sdf.format(date); + } + + public String getSimpleTimeFromMillis(long timemills){ + String simpleTime = null; + + if(timemills < 1000){ + simpleTime = timemills + "毫秒"; + }else if(timemills >= 1000 && timemills < 1000 * 60){ + simpleTime = timemills / 1000 + "秒"; + }else if(timemills >= 1000 * 60 && timemills < 1000 * 60 * 60){ + simpleTime = timemills / 1000 / 60 + "分"; + }else if(timemills >= 1000 * 60 * 60 && timemills < 1000 * 60 * 60 * 60){ + simpleTime = timemills / 1000 / 60 / 60 + "时"; + } + + return simpleTime; + } +} diff --git a/app/src/main/java/com/example/utils/MyFileUtils.java b/app/src/main/java/com/example/utils/MyFileUtils.java new file mode 100644 index 0000000..f7c9536 --- /dev/null +++ b/app/src/main/java/com/example/utils/MyFileUtils.java @@ -0,0 +1,118 @@ +package com.example.utils; + +import com.example.adapter.MyRecFilesAdapter; +import com.example.wgjrouter.R; +import com.squareup.picasso.Picasso; + +import java.math.BigDecimal; + +import io.vov.vitamio.utils.Log; + +public class MyFileUtils { + private static MyFileUtils myFileSizeFormat; + + public static MyFileUtils getInstance(){ + if(myFileSizeFormat == null){ + myFileSizeFormat = new MyFileUtils(); + } + return myFileSizeFormat; + } + + public String formatFileSize(long fileByteSize,int decimalPoint){ + String fFileSize = ""; + + if(fileByteSize < 1024){ + fFileSize = fileByteSize + "B"; + }else if(fileByteSize >= 1024 && fileByteSize < 1024 * 1024){ + BigDecimal bigDecimal = new BigDecimal(fileByteSize / 1024); + double bdss = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue(); + fFileSize = bdss + "KB"; + }else if(fileByteSize >= 1024 * 1024 && fileByteSize < 1024 * 1024 * 1024){ + BigDecimal bigDecimal = new BigDecimal(fileByteSize / 1024 / 1024); + double bdss = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue(); + fFileSize = bdss + "MB"; + }else if(fileByteSize >= 1024 * 1024 * 1024 && fileByteSize < 1024 * 1024 * 1024 * 1024){ + BigDecimal bigDecimal = new BigDecimal(fileByteSize / 1024 / 1024 / 1024); + double bdss = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue(); + fFileSize = bdss + "GB"; + }else if(fileByteSize >= 1024 * 1024 * 1024 * 1024 && fileByteSize < 1024 * 1024 * 1024 * 1024 * 024){ + BigDecimal bigDecimal = new BigDecimal(fileByteSize / 1024 / 1024 / 1024 / 1024); + double bdss = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue(); + fFileSize = bdss + "TB"; + } + + return fFileSize; + } + + public String formatTranSpeed(long speed,int decimalPoint){ + long bigSpeed = 0; + String fSpeed = null; + + if(speed < 1024){ + fSpeed = speed + "B/s"; + }else if(speed >= 1024 && speed < 1024 *1024){ + bigSpeed = speed / 1024; + BigDecimal bigDecimal = new BigDecimal(bigSpeed); + fSpeed = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue() + "KB/s"; + }else if(speed >= 1024 * 1024 && speed < 1024 *1024 * 1024){ + bigSpeed = speed / 1024 / 1024; + BigDecimal bigDecimal = new BigDecimal(bigSpeed); + fSpeed = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue() + "MB/s"; + }else if(speed >= 1024 * 1024 * 1024){ + bigSpeed = speed / 1024 / 1024 / 1024; + BigDecimal bigDecimal = new BigDecimal(bigSpeed); + fSpeed = bigDecimal.setScale(decimalPoint,BigDecimal.ROUND_HALF_UP).doubleValue() + "GB/s"; + } + + return fSpeed; + } + + /** + * 根据文件Url判断文件类型 + * @param fileUrl + * @return + */ + public int checkFileType(String fileUrl){ + int label = 1; + + if(fileUrl.endsWith("png") || fileUrl.endsWith("jpg") || fileUrl.endsWith("bmp") || fileUrl.endsWith("gif") || fileUrl.endsWith("jpeg") || fileUrl.endsWith("ico")){ + label = 14; + } else if(fileUrl.endsWith("apk")){ + label = 0; + } else if(fileUrl.endsWith("xls") || fileUrl.endsWith("xlsx")){ + label = 2; + } else if(fileUrl.endsWith("doc") || fileUrl.endsWith("docx")){ + label = 3; + } else if(fileUrl.endsWith("ppt") || fileUrl.endsWith("pptx")){ + label = 4; + } else if(fileUrl.endsWith("exe")){ + label = 5; + } else if(fileUrl.endsWith("ini")){ + label = 6; + } else if(fileUrl.endsWith("iso")){ + label = 7; + } else if(fileUrl.endsWith("link")){ + label = 8; + } else if(fileUrl.endsWith("pdf")){ + label = 9; + } else if(fileUrl.endsWith("psd")){ + label = 10; + } else if(fileUrl.endsWith("txt")){ + label = 11; + } else if(fileUrl.endsWith("jar")){ + label = 12; + } else if(fileUrl.endsWith("zip") || fileUrl.endsWith("rar") || fileUrl.endsWith("tar") || fileUrl.endsWith("7z")){ + label = 13; + } else if(fileUrl.endsWith("avi") || fileUrl.endsWith("mov") || fileUrl.endsWith("mp4") || fileUrl.endsWith("mkv") || fileUrl.endsWith("wmv") || fileUrl.endsWith("flv") || fileUrl.endsWith("rmvb")){ + label = 15; + } else if(fileUrl.endsWith("torrent")) { + label = 16; + }else if(fileUrl.endsWith("mp3") || fileUrl.endsWith("wma") || fileUrl.endsWith("wav")){ + label = 17; + }else{ + label = 18; + } + + return label; + } +} diff --git a/app/src/main/java/com/example/utils/MyPhoneUtils.java b/app/src/main/java/com/example/utils/MyPhoneUtils.java new file mode 100644 index 0000000..febe130 --- /dev/null +++ b/app/src/main/java/com/example/utils/MyPhoneUtils.java @@ -0,0 +1,323 @@ +package com.example.utils; + +import android.content.ComponentName; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Build; +import android.provider.Settings; +import android.support.v4.content.FileProvider; +import android.support.v7.app.AlertDialog; +import android.util.Log; +import android.view.View; +import android.view.inputmethod.InputMethodManager; + +import java.io.File; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Collections; + +public class MyPhoneUtils { + private static MyPhoneUtils myPhoneUtils; + private Context context; + + private MyPhoneUtils(Context context){ + this.context = context; + } + + public static MyPhoneUtils getInstance(Context context){ + if(myPhoneUtils == null){ + myPhoneUtils = new MyPhoneUtils(context); + } + return myPhoneUtils; + } + + /** + * 检查网络状态 + * @return + */ + public boolean checkNetworkState(){ + boolean networkState = false; + try { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if(cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isAvailable()){ + networkState = true; + } + } catch (Exception e) { + e.printStackTrace(); + } + return networkState; + } + + /** + * 检查网络类型 + * @return + */ + public int checkNetworkType(){ + /** + * 0--其它 + * 1--GPRS + * 2--WiFi + */ + int networkType = 0; + + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkInfo.State gprs = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); + NetworkInfo.State wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); + + if(gprs == NetworkInfo.State.CONNECTED || gprs == NetworkInfo.State.CONNECTING){ + networkType = 1; + }else if(wifi == NetworkInfo.State.CONNECTED || wifi == NetworkInfo.State.CONNECTING){ + networkType = 2; + } + + return networkType; + } + + public void getNetworkGateway(){ + + } + + public String getNetworkLocalIP(){ + String localIp = null; + + switch (checkNetworkType()){ + case 0: + //未知 + break; + case 1: + //GPRS + try { + ArrayList alni = Collections.list(NetworkInterface.getNetworkInterfaces()); + for(NetworkInterface ni : alni){ + ArrayList alia = Collections.list(ni.getInetAddresses()); + for(InetAddress ia : alia){ + if(!ia.isLoopbackAddress() && !ia.isLinkLocalAddress()){ + localIp = ia.getHostAddress(); + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + break; + case 2: + //WIFI + WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + + if(wm.isWifiEnabled()){ + //WIFI已启用 + WifiInfo wi = wm.getConnectionInfo(); + + localIp = intIpToString(wi.getIpAddress()); + } + break; + } + return localIp; + } + + public void getNetworkInternetIp(){ + + } + + private String intIpToString(int intIp){ + return (intIp & 0xFF) + "." + + ((intIp >> 8) & 0xFF) + "." + + ((intIp >> 16) & 0xFF) + "." + + (intIp >> 24 & 0xFF); + } + + public boolean isInputMethodShow(){ + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + return imm.isActive(); + } + + /** + * 隐藏输入法 + * @param view + */ + public void hideInputMethod(View view){ + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + if(imm == null){ + return; + } + imm.hideSoftInputFromWindow(view.getWindowToken(),0); + } + + /** + * 显示输入法 + * @param view + */ + public void showInputMethod(View view){ + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + if(imm == null){ + return; + } + view.setFocusable(true); + view.setFocusableInTouchMode(true); + view.requestFocus(); + imm.showSoftInput(view,InputMethodManager.SHOW_FORCED); + } + + /** + *调用其它视频播放器播放网络视频 + * 不需要7.0版本判断 + * @param vNetUrl + */ + public void usePlayerPlayNetVideo(String vNetUrl){ + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.parse(vNetUrl),"video/*"); + context.startActivity(intent); + } + + /** + * 调用其它工具解析文件 + * @param localUrl + * @param mimeType + * mimeType: + * 1、video/*,2、audio/*,3、application/msword,4、application/vnd.ms-excel,5、application/vnd.ms-powerpoint + * 6、application/vnd.ms-works,7、text/plain,8、application/x-compress,9、application/x-zip-compressed + * 10、application/x-compressed,11、application/x-tar,12、image/,13、application/pdf + */ + public boolean useLocalResolver(String localUrl,String mimeType){ + Log.d("zouguo","localUrl1:" + localUrl); + Log.d("zouguo","mimeType1:" + mimeType); + + boolean resolveOk = false; + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + File file = new File(localUrl); + + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N){ + //7.0以上版本 + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + Uri contentUri = FileProvider.getUriForFile(context,context.getPackageName() + ".FileProvider",file); + intent.setDataAndType(contentUri,mimeType); + }else{ + Uri uri = Uri.fromFile(file); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setDataAndType(uri,mimeType); + } + resolveOk = true; + context.startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + } + return resolveOk; + } + + /** + * 调用系统分享文件 + * @param localUrl + * @param mimeType + */ + public void useLocalSharer(String localUrl,String mimeType){ + Log.d("zouguo","localUrl2:" + localUrl); + Log.d("zouguo","mimeType2:" + mimeType); + + Intent intent = new Intent(Intent.ACTION_SEND); + File file = new File(localUrl); + + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N){ + //7.0以上版本 + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + Uri contentUri = FileProvider.getUriForFile(context,context.getPackageName() + ".FileProvider",file); + intent.putExtra(Intent.EXTRA_STREAM,contentUri); + intent.setType(mimeType); + }else{ + Uri uri = Uri.fromFile(file); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(Intent.EXTRA_STREAM,uri); + intent.setType(mimeType); + } + context.startActivity(Intent.createChooser(intent,"分享到:")); + } + + /** + * 检查某个应用是否已安装 + * @param packName + */ + public boolean checkIsInstalledApp(String packName){ + PackageInfo pi = null; + try { + pi = context.getPackageManager().getPackageInfo(packName,0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return pi != null; + } + + /** + * 通过包名唤醒APP + * 迅雷com.xunlei.downloadprovider + * @param packName + */ + public void wakeAppByPackName(String packName){ + if(!checkIsInstalledApp(packName)){ + return; + } + + Intent intent = context.getPackageManager().getLaunchIntentForPackage(packName); + + if(intent != null){ + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + } + + /** + * 通过包名、活动名唤醒APP + * @param packName + * @param actiName + */ + public void wakeAppByPackNameAndActivity(String packName,String actiName){ + Intent intent = new Intent(Intent.ACTION_MAIN); + ComponentName cn = new ComponentName(packName,actiName); + intent.setComponent(cn); + context.startActivity(intent); + } + + /** + * 通过特定类型的Url唤醒APP + * @param givenUrl + */ + public void wakeAppByUrl(String givenUrl){ + Intent intent = new Intent(); + intent.setData(Uri.parse(givenUrl)); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * 安装apk + * @param apkUrl + */ + public void installApk(String apkUrl){ + Intent intent = new Intent(Intent.ACTION_VIEW); + File file = new File(apkUrl); + + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N){ + //7.0以上 + Uri conUri = FileProvider.getUriForFile(context,context.getPackageName() + ".FileProvider",file); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.setDataAndType(conUri,"application/vnd.android.package-archive"); + }else{ + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri uri = Uri.fromFile(file); + intent.setDataAndType(uri,"application/vnd.android.package-archive"); + } + + context.startActivity(intent); + } +} diff --git a/app/src/main/java/com/example/utils/MyVideoUtils.java b/app/src/main/java/com/example/utils/MyVideoUtils.java new file mode 100644 index 0000000..3440ff0 --- /dev/null +++ b/app/src/main/java/com/example/utils/MyVideoUtils.java @@ -0,0 +1,31 @@ +package com.example.utils; + + +import android.util.Log; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +public class MyVideoUtils { + + private static MyVideoUtils myVideoUtils; + + public static MyVideoUtils getInstance(){ + if(myVideoUtils == null){ + myVideoUtils = new MyVideoUtils(); + } + return myVideoUtils; + } + + public String formatVideoDuration(long duration){ + String tlength = null; + + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); + + tlength = sdf.format(duration); + + return tlength; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/AboutApp.java b/app/src/main/java/com/example/wgjrouter/AboutApp.java new file mode 100644 index 0000000..cbee355 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/AboutApp.java @@ -0,0 +1,164 @@ +package com.example.wgjrouter; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.pgyersdk.feedback.PgyerFeedbackManager; + +public class AboutApp extends AppCompatActivity { + + private Toolbar about_toolbar; + private TextView about_tv_github; + private ImageView about_iv_joinqq; + private ImageView about_iv_feedback; + private TextView about_tv_copyqq; + private TextView about_tv_curversion; + private ImageView about_iv_shareapp; + private ImageView goto_wxpay; + private ImageView goto_alipay; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_aboutapp); + + initView(); + } + + private void initView(){ + about_toolbar = findViewById(R.id.about_toolbar); + about_tv_github = findViewById(R.id.about_tv_github); + about_iv_joinqq = findViewById(R.id.about_iv_joinqq); + about_iv_feedback = findViewById(R.id.about_iv_feedback); + about_tv_copyqq = findViewById(R.id.about_tv_copyqq); + about_tv_curversion = findViewById(R.id.about_tv_curversion); + about_iv_shareapp = findViewById(R.id.about_iv_shareapp); + goto_wxpay = findViewById(R.id.goto_wxpay); + goto_alipay = findViewById(R.id.goto_alipay); + + about_tv_github.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String githubHome = "https://github.com/zouguo-eng"; + + Intent gogithub = new Intent(Intent.ACTION_VIEW); + gogithub.setData(Uri.parse(githubHome)); + startActivity(gogithub); + } + }); + + goto_wxpay.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + + goto_alipay.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + + about_toolbar.setTitle("关于"); + about_toolbar.setNavigationIcon(R.mipmap.back); + about_toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + about_iv_joinqq.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(!joinQQGroup("1iFbREDDfeHB_8LHkG4fc2uusd641RRy")){ + Toast.makeText(AboutApp.this,"未安装手Q或安装的版本不支持",Toast.LENGTH_SHORT).show(); + } + } + }); + + about_iv_feedback.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new PgyerFeedbackManager.PgyerFeedbackBuilder() + .setShakeInvoke(false) //fasle 则不触发摇一摇,最后需要调用 invoke 方法 + .setDisplayType(PgyerFeedbackManager.TYPE.DIALOG_TYPE) //设置以Dialog 的方式打开 + .setColorDialogTitle("#FF0000") //设置Dialog 标题的字体颜色,默认为颜色为#ffffff + .setColorTitleBg("#FF0000") //设置Dialog 标题栏的背景色,默认为颜色为#2E2D2D + .setBarBackgroundColor("#FF0000") // 设置顶部按钮和底部背景色,默认颜色为 #2E2D2D + .setBarButtonPressedColor("#FF0000") //设置顶部按钮和底部按钮按下时的反馈色 默认颜色为 #383737 + .setColorPickerBackgroundColor("#FF0000") //设置颜色选择器的背景色,默认颜色为 #272828 + .builder() + .invoke(); //激活直接显示的方式 + } + }); + + about_tv_copyqq.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + //复制QQ群号到剪贴板 + ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData cd = ClipData.newPlainText("shareurl","728198774"); + cm.setPrimaryClip(cd); + + Toast.makeText(AboutApp.this,"群号已复制到剪贴板",Toast.LENGTH_SHORT).show(); + } + }); + + about_iv_shareapp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT,"微管家,微路由管理器。下载地址(密码:wgj): https://www.pgyer.com/wgjly"); + startActivity(Intent.createChooser(intent,"分享到")); + } + }); + + about_tv_curversion.setText("当前版本:" + BuildConfig.VERSION_NAME); + } + + /**************** + * + * 发起添加群流程。群号:微管家M1-App(728198774) 的 key 为: 1iFbREDDfeHB_8LHkG4fc2uusd641RRy + * @param key 由官网生成的key + * @return 返回true表示呼起手Q成功,返回fals表示呼起失败 + ******************/ + public boolean joinQQGroup(String key) { + Intent intent = new Intent(); + intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key)); + // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + try { + startActivity(intent); + return true; + } catch (Exception e) { + // 未安装手Q或安装的版本不支持 + return false; + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/BackupAppActivity.java b/app/src/main/java/com/example/wgjrouter/BackupAppActivity.java new file mode 100644 index 0000000..7fe3fc2 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupAppActivity.java @@ -0,0 +1,32 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupAppActivity extends AppCompatActivity { + private Toolbar activity_backup_app_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_app); + + initView(); + } + + private void initView(){ + activity_backup_app_tb = findViewById(R.id.activity_backup_app_tb); + activity_backup_app_tb.setTitle("应用备份"); + activity_backup_app_tb.setNavigationIcon(R.mipmap.back); + activity_backup_app_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} + diff --git a/app/src/main/java/com/example/wgjrouter/BackupAudioActivity.java b/app/src/main/java/com/example/wgjrouter/BackupAudioActivity.java new file mode 100644 index 0000000..8e98e0f --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupAudioActivity.java @@ -0,0 +1,31 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupAudioActivity extends AppCompatActivity { + private Toolbar activity_backup_audio_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_audio); + + initView(); + } + + private void initView(){ + activity_backup_audio_tb = findViewById(R.id.activity_backup_audio_tb); + activity_backup_audio_tb.setTitle("音频备份"); + activity_backup_audio_tb.setNavigationIcon(R.mipmap.back); + activity_backup_audio_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/BackupContactActivity.java b/app/src/main/java/com/example/wgjrouter/BackupContactActivity.java new file mode 100644 index 0000000..b3247fa --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupContactActivity.java @@ -0,0 +1,32 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupContactActivity extends AppCompatActivity { + private Toolbar activity_backup_contact_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_contact); + + initView(); + } + + private void initView(){ + activity_backup_contact_tb = findViewById(R.id.activity_backup_contact_tb); + activity_backup_contact_tb.setTitle("通讯录备份"); + activity_backup_contact_tb.setNavigationIcon(R.mipmap.back); + activity_backup_contact_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} + diff --git a/app/src/main/java/com/example/wgjrouter/BackupFilesActivity.java b/app/src/main/java/com/example/wgjrouter/BackupFilesActivity.java new file mode 100644 index 0000000..4ec289c --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupFilesActivity.java @@ -0,0 +1,31 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupFilesActivity extends AppCompatActivity { + private Toolbar activity_backup_file_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_file); + + initView(); + } + + private void initView(){ + activity_backup_file_tb = findViewById(R.id.activity_backup_file_tb); + activity_backup_file_tb.setTitle("文件备份"); + activity_backup_file_tb.setNavigationIcon(R.mipmap.back); + activity_backup_file_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/BackupGridViewActivity.java b/app/src/main/java/com/example/wgjrouter/BackupGridViewActivity.java new file mode 100644 index 0000000..0acaddc --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupGridViewActivity.java @@ -0,0 +1,193 @@ +package com.example.wgjrouter; + +import android.database.Cursor; +import android.os.Bundle; +import android.provider.MediaStore; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; +import android.widget.GridView; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.example.adapter.MyBaGvPhoneBackupAdapter; +import com.example.bean.MyPhoneBackups; + +import java.util.ArrayList; +import java.util.List; + +public class BackupGridViewActivity extends AppCompatActivity { + + List myPhoneBackupsList; + MyBaGvPhoneBackupAdapter myBaGvPhoneBackupAdapter; + + List imageTitleList = new ArrayList<>(); + List imageSizeList = new ArrayList<>(); + List imageUrlList = new ArrayList<>(); + List videoTitleList = new ArrayList<>(); + List videoSizeList = new ArrayList<>(); + List videoUrlList = new ArrayList<>(); + List audioTitleList = new ArrayList<>(); + List audioSizeList = new ArrayList<>(); + List audioUrlList = new ArrayList<>(); + List docsTitleList = new ArrayList<>(); + List docsSizeList = new ArrayList<>(); + List docsUrlList = new ArrayList<>(); + + private ProgressBar activity_phonebackup_pb; + private Toolbar activity_phonebackup_tb; + private GridView activity_phonebackup_gv; + private RecyclerView activity_phonebackup_rc; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_grid); + + initView(); + + activity_phonebackup_pb.setVisibility(View.VISIBLE); + getAllImageFromLocal(); + getAllVideoFromLocal(); + getAllAudioFromLocal(); +// getAllFileFromLocal(); + activity_phonebackup_pb.setVisibility(View.GONE); + + showDataView(); + } + + private void initView(){ + activity_phonebackup_pb = findViewById(R.id.activity_phonebackup_pb); + activity_phonebackup_tb = findViewById(R.id.activity_phonebackup_tb); + activity_phonebackup_gv = findViewById(R.id.activity_phonebackup_gv); + activity_phonebackup_rc = findViewById(R.id.activity_phonebackup_rc); + + activity_phonebackup_tb.setTitle("本地文件列表"); + activity_phonebackup_tb.setNavigationIcon(R.mipmap.back); + activity_phonebackup_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + myPhoneBackupsList = new ArrayList<>(); + myBaGvPhoneBackupAdapter = new MyBaGvPhoneBackupAdapter(BackupGridViewActivity.this, myPhoneBackupsList); + activity_phonebackup_gv.setAdapter(myBaGvPhoneBackupAdapter); + } + + private void getAllImageFromLocal(){ + Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null,null,null,null); + Log.d("zouguo","CountImage:" + cursor.getCount()); + + Toast.makeText(BackupGridViewActivity.this,"数量:" + cursor.getCount(),Toast.LENGTH_SHORT).show(); + + while (cursor.moveToNext()){ + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)); + int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE)); + String location = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); + + Log.d("zouguo","name1:" + name); + Log.d("zouguo","size1:" + size); + Log.d("zouguo","位置1:" + location); + + imageTitleList.add(name); + imageSizeList.add(size); + imageUrlList.add(location); + } + } + + private void getAllVideoFromLocal(){ + Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,null,null,null,null); + Log.d("zouguo","CountVideo:" + cursor.getCount()); + + while (cursor.moveToNext()){ + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); + int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); + String location = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); + + Log.d("zouguo","name2:" + name); + Log.d("zouguo","size2:" + size); + Log.d("zouguo","位置2:" + location); + + videoTitleList.add(name); + videoSizeList.add(size); + videoUrlList.add(location); + } + } + + private void getAllAudioFromLocal(){ + Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null); + Log.d("zouguo","CountAudio:" + cursor.getCount()); + + while(cursor.moveToNext()){ + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); + int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)); + String location = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); + + Log.d("zouguo","name3:" + name); + Log.d("zouguo","size3:" + size); + Log.d("zouguo","位置3:" + location); + + audioTitleList.add(name); + audioSizeList.add(size); + audioUrlList.add(location); + } + } + + private void getAllFileFromLocal(){ + Cursor cursor = getContentResolver().query(MediaStore.Files.getContentUri("external"),null,null,null,null); + Log.d("zouguo","CountFile:" + cursor.getCount()); + Log.d("zouguo","ColumnCount:" + cursor.getColumnCount()); + + for(int i = 0;i < cursor.getColumnCount(); i++){ + Log.d("zouguo","Column" + i + ":" + cursor.getColumnName(i)); + } + + while (cursor.moveToNext()){ + String name = cursor.getString(cursor.getColumnIndexOrThrow("_display_name")); + String title = cursor.getString(cursor.getColumnIndexOrThrow("title")); + String mimetype = cursor.getString(cursor.getColumnIndexOrThrow("mime_type")); + int size = cursor.getInt(cursor.getColumnIndexOrThrow("_size")); + String location = cursor.getString(cursor.getColumnIndexOrThrow("_data")); + + + Log.d("zouguo","------------------------------------"); + + Log.d("zouguo","name4:" + name); + Log.d("zouguo","title4:" + title); + Log.d("zouguo","mimetype4:" + mimetype); + Log.d("zouguo","size4:" + size); + Log.d("zouguo","位置4:" + location); + } + } + + private void showDataView(){ + int imageCounts = imageTitleList.size(); + int videoCounts = videoTitleList.size(); + int audioCounts = audioTitleList.size(); + + MyPhoneBackups images = new MyPhoneBackups(); + images.setFileType(0); + images.setFileTitle("图片"); + images.setFileCounts(imageCounts); + myPhoneBackupsList.add(images); + + MyPhoneBackups videos = new MyPhoneBackups(); + videos.setFileType(1); + videos.setFileTitle("视频"); + videos.setFileCounts(videoCounts); + myPhoneBackupsList.add(videos); + + MyPhoneBackups audios = new MyPhoneBackups(); + audios.setFileType(2); + audios.setFileTitle("音频"); + audios.setFileCounts(audioCounts); + myPhoneBackupsList.add(audios); + + myBaGvPhoneBackupAdapter.notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/BackupImageActivity.java b/app/src/main/java/com/example/wgjrouter/BackupImageActivity.java new file mode 100644 index 0000000..c3ff023 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupImageActivity.java @@ -0,0 +1,384 @@ +package com.example.wgjrouter; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.provider.MediaStore; +import android.support.annotation.Nullable; +import android.support.v4.util.ArraySet; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SwitchCompat; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.example.adapter.MyRecImageBackupAdapter; +import com.example.bean.MyPhoneBackups; +import com.example.event.MessageEvent; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class BackupImageActivity extends AppCompatActivity { + private Toolbar activity_backup_image_tb; + private SwitchCompat activity_backup_image_sc; + private SwitchCompat activity_backup_video_sc; + private TextView activity_backup_image_wz; + private TextView activity_backup_image_count_tips; + private TextView activity_backup_image_selectall; + private RecyclerView activity_backup_image_rv; + private RelativeLayout activity_backup_video_rl; + + List dirTitleList = new ArrayList<>(); + List dirItemCount = new ArrayList<>(); + List dirFirstItem = new ArrayList<>(); + Set dirUpList = new ArraySet<>(); + + List myPhoneBackupsList; + MyRecImageBackupAdapter myRecImageBackupAdapter; + + private EventBus eventBus; + + SharedPreferences sp; + SharedPreferences.Editor spe; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 12121: + //数据获取成功,展示 + showDataView(); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_image); + + eventBus = EventBus.getDefault(); + eventBus.register(this); + + initView(); + + initImageAutoBackupState(); + } + + private void initView(){ + sp = getSharedPreferences("app_setting",MODE_PRIVATE); + spe = sp.edit(); + + Set autoUpDirList = sp.getStringSet("up_image_dirs",new HashSet()); + + dirUpList = sp.getStringSet("up_image_dirs",null); + + activity_backup_image_tb = findViewById(R.id.activity_backup_image_tb); + activity_backup_image_sc = findViewById(R.id.activity_backup_image_sc); + activity_backup_video_sc = findViewById(R.id.activity_backup_video_sc); + activity_backup_image_count_tips = findViewById(R.id.activity_backup_image_count_tips); + activity_backup_image_selectall = findViewById(R.id.activity_backup_image_selectall); + activity_backup_image_wz = findViewById(R.id.activity_backup_image_wz); + activity_backup_image_rv = findViewById(R.id.activity_backup_image_rv); + activity_backup_video_rl = findViewById(R.id.activity_backup_video_rl); + + activity_backup_image_selectall.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(myRecImageBackupAdapter.isSelectAll()){ + //取消全选 + myRecImageBackupAdapter.selectNone(); + }else{ + //全选 + myRecImageBackupAdapter.selectAll(); + } + } + }); + + activity_backup_image_tb.setTitle("相册备份"); + activity_backup_image_tb.setNavigationIcon(R.mipmap.back); + activity_backup_image_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backIntentData(); + finish(); + } + }); + + activity_backup_image_wz.setText("照片及视频备份至:来自:" + Build.MODEL); + + activity_backup_image_sc.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(isChecked){ + spe.putBoolean("up_image",true); + spe.commit(); + activity_backup_image_rv.setVisibility(View.VISIBLE); + activity_backup_video_rl.setVisibility(View.VISIBLE); + getAllImageFromLocal(); + }else{ + spe.putBoolean("up_image",false); + spe.putBoolean("up_video",false); + spe.commit(); + activity_backup_video_sc.setChecked(false); + activity_backup_image_rv.setVisibility(View.GONE); + activity_backup_video_rl.setVisibility(View.GONE); + //移除全部列表 + myPhoneBackupsList.clear(); + myRecImageBackupAdapter.setCanInitData(true); + myRecImageBackupAdapter.notifyDataSetChanged(); + } + } + }); + + activity_backup_video_sc.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(isChecked){ + spe.putBoolean("up_video",true); + spe.commit(); + getAllVideoFromLocal(); + }else{ + spe.putBoolean("up_video",false); + spe.commit(); + //移除全部列表 + myPhoneBackupsList.clear(); + myRecImageBackupAdapter.setCanInitData(true); + myRecImageBackupAdapter.notifyDataSetChanged(); + //重新加载图片 + getAllImageFromLocal(); + } + } + }); + + LinearLayoutManager llm = new LinearLayoutManager(BackupImageActivity.this); + llm.setOrientation(LinearLayoutManager.VERTICAL); + activity_backup_image_rv.setLayoutManager(llm); + + myPhoneBackupsList = new ArrayList<>(); + myRecImageBackupAdapter = new MyRecImageBackupAdapter(BackupImageActivity.this, eventBus, myPhoneBackupsList, autoUpDirList); + activity_backup_image_rv.setAdapter(myRecImageBackupAdapter); + + myRecImageBackupAdapter.setOnItemListener(new MyRecImageBackupAdapter.OnItemListener() { + @Override + public void onItemClick(View view, int position) { + SwitchCompat sc = view.findViewById(R.id.item_rec_autobackup_sc); + + if(sc.isChecked()){ + myRecImageBackupAdapter.notifyItemChanged(position,false); + }else{ + myRecImageBackupAdapter.notifyItemChanged(position,true); + } + } + }); + + activity_backup_image_rv.addItemDecoration(new DividerItemDecoration(BackupImageActivity.this,DividerItemDecoration.VERTICAL)); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MessageEvent event) { + switch (event.getEventType()) { + case 33: + if(event.getFileType() == dirTitleList.size()){ + //当前全选 + activity_backup_image_selectall.setText("全不选"); + }else{ + //全不选 + activity_backup_image_selectall.setText("全选"); + } + + activity_backup_image_count_tips.setText("选择自动备份的相册 " + event.getFileType() + "/" + dirTitleList.size()); + break; + } + } + + private void initImageAutoBackupState(){ + boolean imageAutoState = sp.getBoolean("up_image",false); + boolean videoAutoState = sp.getBoolean("up_video",false); + + if(imageAutoState){ + activity_backup_image_sc.setChecked(true); + activity_backup_video_rl.setVisibility(View.VISIBLE); + }else{ + activity_backup_image_sc.setChecked(false); + activity_backup_video_rl.setVisibility(View.GONE); + } + + if(videoAutoState){ + activity_backup_video_sc.setChecked(true); + }else{ + activity_backup_video_sc.setChecked(false); + } + } + + private void getAllImageFromLocal(){ + dirTitleList.clear(); + dirItemCount.clear(); + dirFirstItem.clear(); + + new Thread(new Runnable() { + @Override + public void run() { + Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null,null,null,null); + Log.d("zouguo","CountImage:" + cursor.getCount()); + + while (cursor.moveToNext()){ + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)); + int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE)); + String location = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); + String dir = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)); + + if(location.contains("tencent")){ + dir = "tencent"; + } + + //判断文件夹是否已记录 + if(dirTitleList.contains(dir)){ + int index = dirTitleList.indexOf(dir); + int count = dirItemCount.get(index) + 1; + + dirItemCount.set(index,count); + }else{ + dirTitleList.add(dir); + dirItemCount.add(1); + dirFirstItem.add(location); + } + } + + Message msg = new Message(); + msg.what = 12121; + handler.sendMessage(msg); + } + }).start(); + } + + private void getAllVideoFromLocal(){ + new Thread(new Runnable() { + @Override + public void run() { + Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,null,null,null,null); + Log.d("zouguo","CountVideo:" + cursor.getCount()); + + while (cursor.moveToNext()){ + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); + int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); + String location = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); + String dir = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)); + + if(location.contains("tencent")){ + dir = "tencent"; + } + + //判断文件夹是否已记录 + if(dirTitleList.contains(dir)){ + int index = dirTitleList.indexOf(dir); + int count = dirItemCount.get(index) + 1; + + dirItemCount.set(index,count); + }else{ + dirTitleList.add(dir); + dirItemCount.add(1); + dirFirstItem.add(location); + } + } + + Message msg = new Message(); + msg.what = 12121; + handler.sendMessage(msg); + } + }).start(); + } + + private void showDataView(){ + myPhoneBackupsList.clear(); + + int autoCounts = 0; + + if(activity_backup_image_sc.isChecked()){ + for(int i = 0;i list = new ArraySet<>(); + + if(activity_backup_image_sc.isChecked()){ + //记录需要进行自动上传操作的图片、视频文件夹 + List selectListIndex = myRecImageBackupAdapter.getSelectItemIndex(); + + for(int i = 0;i < selectListIndex.size();i++){ + list.add(dirTitleList.get(selectListIndex.get(i))); + } + + spe.putStringSet("up_image_dirs",list); + }else{ + //清空设置的上传文件夹 + spe.putStringSet("up_image_dirs",list); + } + spe.commit(); + } + + //返回时携带开启状态数据 + private void backIntentData(){ + Intent backdata = new Intent(); + backdata.putExtra("open_type",0); + backdata.putExtra("open_state",activity_backup_image_sc.isChecked()); + setResult(RESULT_OK,backdata); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + eventBus.unregister(this); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/BackupListViewActivity.java b/app/src/main/java/com/example/wgjrouter/BackupListViewActivity.java new file mode 100644 index 0000000..507ff7a --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupListViewActivity.java @@ -0,0 +1,159 @@ +package com.example.wgjrouter; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.View; + +import com.example.adapter.MyRecBackupsAdapter; +import com.example.bean.MyPhoneBackups; + +import java.util.ArrayList; +import java.util.List; + +public class BackupListViewActivity extends AppCompatActivity { + + private Toolbar activity_phonebackup_list_tb; + private RecyclerView activity_phonebackup_list_rv; + + String[] itemTitles = {"相册备份","文件备份","音频备份","微信文件备份","应用备份","短信备份","通话记录备份","通讯录备份"}; + + List myPhoneBackupsList; + MyRecBackupsAdapter myRecBackupsAdapter; + + List autoUploadState = new ArrayList<>(); + + private int REQUEST_CODE = 1689; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_list); + + initView(); + + checkAutoUploadState(); + + showDataView(); + } + + private void initView(){ + activity_phonebackup_list_tb = findViewById(R.id.activity_phonebackup_list_tb); + activity_phonebackup_list_rv = findViewById(R.id.activity_phonebackup_list_rv); + + activity_phonebackup_list_tb.setTitle("手机备份"); + activity_phonebackup_list_tb.setNavigationIcon(R.mipmap.back); + activity_phonebackup_list_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + LinearLayoutManager llm = new LinearLayoutManager(BackupListViewActivity.this); + llm.setOrientation(LinearLayoutManager.VERTICAL); + activity_phonebackup_list_rv.setLayoutManager(llm); + + myPhoneBackupsList = new ArrayList<>(); + myRecBackupsAdapter = new MyRecBackupsAdapter(BackupListViewActivity.this,myPhoneBackupsList); + activity_phonebackup_list_rv.setAdapter(myRecBackupsAdapter); + + myRecBackupsAdapter.setOnItemListener(new MyRecBackupsAdapter.OnItemListener() { + @Override + public void onItemClick(View view, int position) { + Intent gointent; + switch (position){ + case 0: + gointent = new Intent(BackupListViewActivity.this,BackupImageActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 1: + gointent = new Intent(BackupListViewActivity.this,BackupFilesActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 2: + gointent = new Intent(BackupListViewActivity.this,BackupAudioActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 3: + gointent = new Intent(BackupListViewActivity.this,BackupWechatActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 4: + gointent = new Intent(BackupListViewActivity.this,BackupAppActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 5: + gointent = new Intent(BackupListViewActivity.this,BackupMsgActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 6: + gointent = new Intent(BackupListViewActivity.this,BackupPhoneActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + case 7: + gointent = new Intent(BackupListViewActivity.this, BackupContactActivity.class); + startActivityForResult(gointent,REQUEST_CODE); + break; + } + } + + @Override + public void onItemLongClick(View view, int position) { + + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(resultCode == RESULT_OK && requestCode == REQUEST_CODE){ + int open_type = data.getIntExtra("open_type",0); + boolean open_state = data.getBooleanExtra("open_state",false); + + myRecBackupsAdapter.notifyItemChanged(open_type,open_state); + } + } + + private void checkAutoUploadState(){ + autoUploadState.clear(); + + SharedPreferences spf = getSharedPreferences("app_setting",MODE_PRIVATE); + boolean upImageState = spf.getBoolean("up_image",false); + boolean upFilesState = spf.getBoolean("up_file",false); + boolean upAudioState = spf.getBoolean("up_audio",false); + boolean upWechatState = spf.getBoolean("up_wechat",false); + boolean upAppState = spf.getBoolean("up_app",false); + boolean upMsgState = spf.getBoolean("up_msg",false); + boolean upPhoneState = spf.getBoolean("up_phone",false); + boolean upContactState = spf.getBoolean("up_contact",false); + + autoUploadState.add(upImageState); + autoUploadState.add(upFilesState); + autoUploadState.add(upAudioState); + autoUploadState.add(upWechatState); + autoUploadState.add(upAppState); + autoUploadState.add(upMsgState); + autoUploadState.add(upPhoneState); + autoUploadState.add(upContactState); + } + + private void showDataView(){ + myPhoneBackupsList.clear(); + + for(int i = 0;i < itemTitles.length;i++){ + MyPhoneBackups myPhoneBackup = new MyPhoneBackups(); + myPhoneBackup.setFileType(i); + myPhoneBackup.setFileTitle(itemTitles[i]); + myPhoneBackup.setAutoUpload(autoUploadState.get(i)); + myPhoneBackupsList.add(myPhoneBackup); + } + myRecBackupsAdapter.notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/BackupMsgActivity.java b/app/src/main/java/com/example/wgjrouter/BackupMsgActivity.java new file mode 100644 index 0000000..8421a53 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupMsgActivity.java @@ -0,0 +1,32 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupMsgActivity extends AppCompatActivity { + private Toolbar activity_backup_msg_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_msg); + + initView(); + } + + private void initView(){ + activity_backup_msg_tb = findViewById(R.id.activity_backup_msg_tb); + activity_backup_msg_tb.setTitle("短信备份"); + activity_backup_msg_tb.setNavigationIcon(R.mipmap.back); + activity_backup_msg_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} + diff --git a/app/src/main/java/com/example/wgjrouter/BackupPhoneActivity.java b/app/src/main/java/com/example/wgjrouter/BackupPhoneActivity.java new file mode 100644 index 0000000..95c4a45 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupPhoneActivity.java @@ -0,0 +1,32 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupPhoneActivity extends AppCompatActivity { + private Toolbar activity_backup_phone_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_audio); + + initView(); + } + + private void initView(){ + activity_backup_phone_tb = findViewById(R.id.activity_backup_audio_tb); + activity_backup_phone_tb.setTitle("通话记录备份"); + activity_backup_phone_tb.setNavigationIcon(R.mipmap.back); + activity_backup_phone_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} + diff --git a/app/src/main/java/com/example/wgjrouter/BackupWechatActivity.java b/app/src/main/java/com/example/wgjrouter/BackupWechatActivity.java new file mode 100644 index 0000000..c48c53b --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/BackupWechatActivity.java @@ -0,0 +1,31 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +public class BackupWechatActivity extends AppCompatActivity { + private Toolbar activity_backup_wechat_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_phone_backup_wechat); + + initView(); + } + + private void initView(){ + activity_backup_wechat_tb = findViewById(R.id.activity_backup_wechat_tb); + activity_backup_wechat_tb.setTitle("微信文件备份"); + activity_backup_wechat_tb.setNavigationIcon(R.mipmap.back); + activity_backup_wechat_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/wgjrouter/FileTransFinish.java b/app/src/main/java/com/example/wgjrouter/FileTransFinish.java new file mode 100644 index 0000000..1ed3fbc --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FileTransFinish.java @@ -0,0 +1,532 @@ +package com.example.wgjrouter; + +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Gravity; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.adapter.MyRecTransAdapter; +import com.example.bean.TaskInfo; +import com.example.database.FileTrans; +import com.example.utils.MyPhoneUtils; + +import org.litepal.LitePal; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +public class FileTransFinish extends AppCompatActivity { + + private LinearLayout file_trans_finish_parentview; + private RecyclerView file_trans_finish_rv; + private Toolbar file_trans_finish_tb; + private List lvFileTransList = null; + private MyRecTransAdapter myRecTransAdapter = null; + + private List updownList = new ArrayList<>(); + + private String installApkUrl = ""; + private static int REQUEST_INSTALL_PERMISSION_CODE = 15926; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_file_trans_finish); + + file_trans_finish_parentview = findViewById(R.id.file_trans_finish_parentview); + file_trans_finish_tb = findViewById(R.id.file_trans_finish_tb); + + //Toolbar设置菜单布局 + file_trans_finish_tb.inflateMenu(R.menu.file_finish_option_menu); + + file_trans_finish_tb.setNavigationIcon(R.mipmap.back); + file_trans_finish_tb.setTitle("已完成"); + file_trans_finish_tb.setTitleTextColor(Color.WHITE); + file_trans_finish_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + file_trans_finish_tb.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + switch (menuItem.getItemId()){ + case R.id.trans_finish_onlydown: + //仅显示下载记录 + getTransDataFromDBOnlyDown(); + break; + case R.id.trans_finish_clear: + LitePal.deleteAll(FileTrans.class); + //刷新 + getTransDataFromDB(); + break; + case R.id.trans_finish_deleteall: + //风险操作,提醒 + AlertDialog adf = null; + AlertDialog.Builder adbf = new AlertDialog.Builder(FileTransFinish.this); + adbf.setTitle("删空提醒"); + adbf.setMessage("是否删除已下载的全部文件"); + adbf.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + //本地下载路径 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File sumFile = new File(file.getPath() + "/com.example.wgjrouter"); + + if(sumFile.exists()){ + //目录存在 + Log.d("zouguo","文件数:" + sumFile.list().length); + String[] lists = sumFile.list(); + + for(int i = 0;i < lists.length;i++){ + Log.d("zouguo","文件:" + lists[i]); + + FileTrans ft = LitePal.where("filename = ? and upordown = ?",lists[i],"1").findLast(FileTrans.class); + + if(ft != null) { + File f = new File(ft.getFilePath()); + + if (f.exists()) { + f.delete(); + } + } + } + + //清空记录 + LitePal.deleteAll(FileTrans.class); + //刷新 + getTransDataFromDB(); + + Toast.makeText(FileTransFinish.this,"删空完成",Toast.LENGTH_SHORT).show(); + } + } + } + }); + adbf.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + adf = adbf.create(); + adf.show(); + adf.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + break; + } + return false; + } + }); + + file_trans_finish_rv = findViewById(R.id.file_trans_finish_rv); + + LinearLayoutManager llm = new LinearLayoutManager(FileTransFinish.this); + llm.setOrientation(LinearLayoutManager.VERTICAL); + file_trans_finish_rv.setLayoutManager(llm); + + lvFileTransList = new ArrayList<>(); + myRecTransAdapter = new MyRecTransAdapter(FileTransFinish.this,lvFileTransList); + file_trans_finish_rv.setAdapter(myRecTransAdapter); + + myRecTransAdapter.setOnItemListener(new MyRecTransAdapter.OnItemListener() { + @Override + public void onItemClick(View view, int position) { + if(updownList.get(position) == 0){ + //上传类型 + Toast.makeText(FileTransFinish.this,"抱歉,暂不支持上传文件的查看",Toast.LENGTH_SHORT).show(); + return; + } + + TextView tv = view.findViewById(R.id.fg_transfer_filename_tv); + + if(tv.getText().toString().equals("")){ + Toast.makeText(FileTransFinish.this,"抱歉,解析失败",Toast.LENGTH_SHORT).show(); + return; + } + + openFile(tv.getText().toString()); + } + + @Override + public void onItemLongClick(final View parentView,final int parentPosition) { + if(updownList.get(parentPosition) == 0){ + //上传类型 + return; + } + + View popView = View.inflate(FileTransFinish.this,R.layout.dialog_file_longclick_menu,null); + + ListView lv = popView.findViewById(R.id.dialog_file_longclick_menu_lv); + + String[] menuData = {"打开","分享","删除记录","删除文件","取消"}; + ArrayAdapter arrayAdapter = new ArrayAdapter<>(FileTransFinish.this,android.R.layout.simple_list_item_1,menuData); + lv.setAdapter(arrayAdapter); + + final PopupWindow pw = new PopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT); + + lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + pw.dismiss(); + + TextView tv = parentView.findViewById(R.id.fg_transfer_filename_tv); + + if(tv.getText().toString().equals("")){ + Toast.makeText(FileTransFinish.this,"抱歉,解析失败",Toast.LENGTH_SHORT).show(); + return; + } + + Log.d("zouguo","position:" + position); + + switch (position){ + case 0: + openFile(tv.getText().toString()); + break; + case 1: + shareFile(tv.getText().toString()); + break; + case 2: + //删除记录 + LitePal.deleteAll(FileTrans.class,"filename = ? and upordown = ?",tv.getText().toString(),String.valueOf(updownList.get(parentPosition))); + //刷新 + getTransDataFromDB(); + break; + case 3: + //删除文件 + FileTrans ft = LitePal.where("filename = ? and upordown = ?",tv.getText().toString(),String.valueOf(updownList.get(parentPosition))).findLast(FileTrans.class); + + if(ft != null){ + File file = new File(ft.getFilePath()); + + if(file.exists()){ + //存在 + if(file.delete()){ + Toast.makeText(FileTransFinish.this,"删除成功",Toast.LENGTH_SHORT).show(); + + //删除记录 + LitePal.deleteAll(FileTrans.class,"filename = ? and upordown = ?",tv.getText().toString(),String.valueOf(updownList.get(parentPosition))); + //刷新 + getTransDataFromDB(); + }else{ + Toast.makeText(FileTransFinish.this,"抱歉,删除本地文件失败",Toast.LENGTH_SHORT).show(); + } + }else{ + //文件不存在,删除该条记录 + LitePal.deleteAll(FileTrans.class,"filename = ? and upordown = ?",tv.getText().toString(),String.valueOf(updownList.get(parentPosition))); + //刷新 + getTransDataFromDB(); + } + }else{ + Toast.makeText(FileTransFinish.this,"抱歉,解析失败",Toast.LENGTH_SHORT).show(); + } + break; + case 4: + pw.dismiss(); + break; + } + } + }); + + ColorDrawable cd = new ColorDrawable(0xb0000000); + pw.setBackgroundDrawable(cd); + pw.setOutsideTouchable(true); + pw.setFocusable(true); + pw.showAtLocation(file_trans_finish_parentview, Gravity.CENTER,0,0); + } + }); + + getTransDataFromDB(); + } + + //查询全部记录 + private void getTransDataFromDB(){ + lvFileTransList.clear(); + updownList.clear(); + + List fileTransDBS = LitePal.findAll(FileTrans.class); + for(FileTrans fileTrans : fileTransDBS){ + TaskInfo taskInfo = new TaskInfo(); + taskInfo.setFileName(fileTrans.getFileName()); + taskInfo.setFileLength(fileTrans.getFileLength()); + taskInfo.setFileUrl(fileTrans.getFilePath()); + taskInfo.setTranTime(fileTrans.getFileTranTime()); + taskInfo.setUpOrDownOrRemote(fileTrans.getUpOrDown()); + taskInfo.setTranGap(""); + taskInfo.setTranState("完成"); + + updownList.add(fileTrans.getUpOrDown()); + lvFileTransList.add(taskInfo); + } + myRecTransAdapter.notifyDataSetChanged(); + } + + /** + * 仅下载记录 + */ + private void getTransDataFromDBOnlyDown(){ + lvFileTransList.clear(); + updownList.clear(); + + List fileTransDBS = LitePal.where("upordown = ?","1").find(FileTrans.class); + for(FileTrans fileTrans : fileTransDBS){ + TaskInfo taskInfo = new TaskInfo(); + taskInfo.setFileName(fileTrans.getFileName()); + taskInfo.setFileLength(fileTrans.getFileLength()); + taskInfo.setFileUrl(fileTrans.getFilePath()); + taskInfo.setTranTime(fileTrans.getFileTranTime()); + taskInfo.setUpOrDownOrRemote(fileTrans.getUpOrDown()); + taskInfo.setTranGap(""); + taskInfo.setTranState("完成"); + + updownList.add(fileTrans.getUpOrDown()); + lvFileTransList.add(taskInfo); + } + myRecTransAdapter.notifyDataSetChanged(); + } + + /** + * 打开下载的文件 + * @param fileName + */ + private void openFile(String fileName){ + FileTrans ft = LitePal.where("filename = ? and upordown = ?",fileName,"1").findLast(FileTrans.class); + + if(ft != null){ + Log.d("zouguo","OpenName:" + fileName); + Log.d("zouguo","UpOrDown:" + ft.getUpOrDown()); + Log.d("zouguo","OpenType:" + ft.getFileType()); + + File file = new File(ft.getFilePath()); + + if(file.exists()){ + switch(ft.getFileType()) { + case 0: + installApkUrl = fileName; + + //apk安装 + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ + //8.0以上 + boolean haveInstallPermission = getPackageManager().canRequestPackageInstalls(); + if(haveInstallPermission){ + MyPhoneUtils.getInstance(FileTransFinish.this).installApk(ft.getFilePath()); + }else{ + new AlertDialog.Builder(FileTransFinish.this) + .setTitle("操作提醒") + .setMessage("安装应用需要打开未知来源权限,请去设置中开启权限") + .setPositiveButton("授权", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Uri packageUri = Uri.parse("package:"+ getPackageName()); + Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageUri); + startActivityForResult(intent,REQUEST_INSTALL_PERMISSION_CODE); + } + }) + .create().show(); + } + }else{ + MyPhoneUtils.getInstance(FileTransFinish.this).installApk(ft.getFilePath()); + } + break; + case 2: + //xls + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/vnd.ms-excel"); + break; + case 3: + //word + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/msword"); + break; + case 4: + //ppt + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/vnd.ms-powerpoint"); + break; + case 6: + //ini + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"text/plain"); + break; + case 7: + //iso + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(),"application/*"); + break; + case 9: + //pdf + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/pdf"); + break; + case 11: + //txt + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"text/plain"); + break; + case 12: + //jar包 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/java-archive"); + break; + case 13: + //压缩包 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/*"); + break; + case 14: + //图片 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"image/*"); + break; + case 15: + //视频 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"video/*"); + break; + case 16: + //种子 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"application/x-bittorrent"); + break; + case 17: + //音频 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalResolver(ft.getFilePath(),"audio/*"); + break; + default: + Toast.makeText(FileTransFinish.this,"抱歉,文件类型未能正确识别",Toast.LENGTH_SHORT).show(); + break; + } + }else{ + //文件不存在,删除该条记录 + LitePal.deleteAll(FileTrans.class,"filename = ? and upordown = ?",fileName,"1"); + //刷新 + getTransDataFromDB(); + } + }else{ + Toast.makeText(FileTransFinish.this,"抱歉,解析失败",Toast.LENGTH_SHORT).show(); + } + } + + /** + * 分享下载的文件 + * @param fileName + */ + private void shareFile(String fileName){ + FileTrans ft = LitePal.where("filename = ? and upordown = ?",fileName,"1").findLast(FileTrans.class); + + if(ft != null){ + Log.d("zouguo","OpenName:" + fileName); + Log.d("zouguo","UpOrDown:" + ft.getUpOrDown()); + Log.d("zouguo","OpenType:" + ft.getFileType()); + + File file = new File(ft.getFilePath()); + + if(file.exists()){ + switch(ft.getFileType()) { + case 0: + //apk + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 2: + //xls + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 3: + //word + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 4: + //ppt + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 5: + //exe + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 6: + //ini + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "text/*"); + break; + case 7: + //iso + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 9: + //pdf + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 10: + //psd + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 11: + //txt + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "text/*"); + break; + case 12: + //jar包 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 13: + //压缩包 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 14: + //图片 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "image/*"); + break; + case 15: + //视频 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "video/*"); + break; + case 16: + //种子 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "application/*"); + break; + case 17: + //音频 + MyPhoneUtils.getInstance(FileTransFinish.this).useLocalSharer(ft.getFilePath(), "audio/*"); + break; + default: + Toast.makeText(FileTransFinish.this, "抱歉,文件类型未能正确识别", Toast.LENGTH_SHORT).show(); + break; + } + }else{ + //文件不存在,删除该条记录 + LitePal.deleteAll(FileTrans.class,"filename = ? and upordown = ?",fileName,"1"); + //刷新 + getTransDataFromDB(); + } + }else{ + Toast.makeText(FileTransFinish.this,"抱歉,解析失败",Toast.LENGTH_SHORT).show(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode == REQUEST_INSTALL_PERMISSION_CODE && resultCode == RESULT_OK){ + Log.d("zouguo","OK"); + + openFile(installApkUrl); + }else{ + Log.d("zouguo","NO"); + } + } +} diff --git a/app/src/main/java/com/example/wgjrouter/FragmentFile.java b/app/src/main/java/com/example/wgjrouter/FragmentFile.java new file mode 100644 index 0000000..b06b637 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FragmentFile.java @@ -0,0 +1,2008 @@ +package com.example.wgjrouter; + +import android.Manifest; +import android.app.Activity; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.ContentUris; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.preference.PreferenceManager; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v4.app.NotificationCompat; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.adapter.MyRecFilesAdapter; +import com.example.bean.MyRecFileInfos; +import com.example.bean.SmbFileInfos; +import com.example.consts.Consts; +import com.example.event.MessageEvent; +import com.example.samba.SambaUtils; +import com.example.utils.MyDateUtils; +import com.example.utils.MyFileUtils; +import com.example.utils.MyPhoneUtils; +import com.github.chrisbanes.photoview.PhotoView; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.squareup.picasso.MemoryPolicy; +import com.squareup.picasso.Picasso; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class FragmentFile extends Fragment{ + + Gson gson = new Gson(); + + private SwipeRefreshLayout fg_file_sr; + private RecyclerView recyclerView; + private Toolbar toolbar; + private PopupWindow popupWindowPic; + private View fg_file_opendir_cl; + + private List myFgLvInfosList; + private MyRecFilesAdapter myFgLvArrayAdapter; + private LinearLayout linearLayoutSearch; + private EditText editTextSearch; + private Button buttonSearch; + private ProgressBar fg_file_pb; + private ImageView fg_file_error_iv; + private View fg_file_showpic_label;//图片弹窗显示/隐藏标记位 + + /** + * 0--Holl + * 1--OpenWrt 默认 + */ + private int routerType = 0; + private String routerHost = ""; + private String canoniUrl = "";//随着目录的进入和回退而变化 + private String rootUrl = "";//固定 + private String routerName = ""; + private boolean waitChangeTitle = false; + + SharedPreferences sharedPreferences = null; + private boolean isSearch = false; + private boolean transCoverFile = true;//默认传输时覆盖目标文件夹已有的文件 + + //读取配置的WiFi名称关键字、网关、软链接名、挂载类型 + private boolean wifi_default_config = true; + private String gateway_config; + private String samba_config; + private String link_diskdir_config; + + private String jsonFileDir = ""; + private String toolbarTile = ""; + + //文件属性 + private List fileInfosList = new ArrayList<>(); + //上层目录 + private List parentTitBack = new ArrayList<>(); + private List parentUrlList = new ArrayList<>(); + private List parentUrlBack = new ArrayList<>(); + private List fileOrDirList = new ArrayList<>();//标记当前Item是文件、文件夹 + private List fileTitleList = new ArrayList<>(); + private List fileTypeList = new ArrayList<>();//标记文件的类型,下载用 + private int fileType = 0;//标记本地文件类型,上传用 + private List canoniUlrList = new ArrayList<>(); + private List picItemUrlList = new ArrayList<>(); + private ArrayList videoTitleList = new ArrayList<>(); + private ArrayList videoItemUrlList = new ArrayList<>(); + + private int dirCounts = 0; + private int fileCounts = 0; + + private View parentView = null; + private boolean isFresh = false; + private boolean isShowPic = false; + private int clickPicIndex = 0; + private int longClickItemIndex = 0; + private String newFolderName = null; + private int newFolderIndex = 0; + + private int FILE_REQUEST_CODE = 121; + private int REQUEST_PERMISSION_CODE = 9737; + + private AlertDialog alertDialog = null; + private static String CHANNEL_ID = "channel_wgj"; + private static String CHANNEL_NAME = "channel_wgjrouter"; + private Notification.Builder nb; + private NotificationCompat.Builder ncb; + private Notification notification; + private NotificationManager notificationManager = null; + + String urlPath = null; + String newfname = null; + + private boolean isEdit = false; + private EventBus eventBus; + //网络变化接收广播 + private NetworkChangeReceive networkChangeReceive = null; + + private Handler handler = new Handler(); + + private Handler hanlderFile = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 122: + case 123: + case 125: + case 127: + case 129: + Toast.makeText(getActivity(),msg.obj.toString(),Toast.LENGTH_SHORT).show(); + break; + case 126: + //文件已存在 + final String fileName = msg.obj.toString(); + final int fileType = msg.arg1; + android.app.AlertDialog ad = null; + android.app.AlertDialog.Builder adb = new android.app.AlertDialog.Builder(getActivity()); + adb.setTitle("上传提醒"); + adb.setMessage("当前文件已存在,上传将覆盖,是否继续"); + adb.setNegativeButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + adb.setPositiveButton("继续", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + eventBus.postSticky(new MessageEvent(2,fileType,fileName,0,canoniUrl,urlPath)); + } + }); + ad = adb.create(); + ad.show(); + ad.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + ad.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.RED); + break; + case 128: + List listSize = new ArrayList<>(); + listSize = (List) msg.obj; + + if(listSize.size() > 0){ + //获取成功 + AlertDialog adf = null; + AlertDialog.Builder adbf = new AlertDialog.Builder(getActivity()); + adbf.setTitle(fileTitleList.get(msg.arg1)); + adbf.setMessage("子项数:" + listSize.get(0) + "\n文件数:" + String.valueOf(listSize.get(1) + "\n文件夹数:" + String.valueOf(listSize.get(2)))); + adbf.setPositiveButton("好的", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + adf = adbf.create(); + adf.show(); + }else{ + Toast.makeText(getActivity(),"当前文件夹为空",Toast.LENGTH_SHORT).show(); + } + break; + case 130: + Toast.makeText(getActivity(),"重命名成功,刷新中...",Toast.LENGTH_SHORT).show(); + + fresh(canoniUrl); + break; + case 131: + Toast.makeText(getActivity(),"删除成功,刷新中...",Toast.LENGTH_SHORT).show(); + + fresh(canoniUrl); + break; + case 132: + //删除进度对话框更新 + TextView progress_tv = alertDialog.findViewById(R.id.dialog_waitting_schedule_tv); + + if(msg.arg1 == 0){ + progress_tv.setText(msg.obj.toString()); + }else{ + alertDialog.dismiss(); + hanlderFile.removeMessages(132); + + Toast.makeText(getActivity(),"删除成功,刷新中...",Toast.LENGTH_SHORT).show(); + + fresh(canoniUrl); + } + + if(!alertDialog.isShowing()){ + hanlderFile.removeMessages(132); + } + break; + } + } + }; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + eventBus = EventBus.getDefault(); + eventBus.register(this); + //注册网络变化广播接收器 + networkChangeReceive = new NetworkChangeReceive(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); + getActivity().registerReceiver(networkChangeReceive,intentFilter); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + parentView = inflater.inflate(R.layout.layout_fg_file,container,false); + + //初始化一些参数 + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + transCoverFile = sharedPreferences.getBoolean("override_destfile",true);//个性化配置菜单:是否覆盖下载 + + initView(parentView); + + //刷新数据 + fresh(canoniUrl); + return parentView; + } + + class NetworkChangeReceive extends BroadcastReceiver{ + + @Override + public void onReceive(Context context, Intent intent) { + if(MyPhoneUtils.getInstance(getActivity()).checkNetworkState() && MyPhoneUtils.getInstance(getActivity()).checkNetworkType() == 2){ + /** + * 网络状态有变化,并且网络为连接,切换WIFI + * 刷新数据 + */ + fresh(canoniUrl); + } + } + } + + //初始化视图 + private void initView(final View parentView){ + fg_file_showpic_label = parentView.findViewById(R.id.fg_file_showpic_label); + fg_file_sr = parentView.findViewById(R.id.fg_file_sr); + fg_file_pb = parentView.findViewById(R.id.fg_file_pb); + fg_file_error_iv = parentView.findViewById(R.id.fg_file_error_iv); + recyclerView = parentView.findViewById(R.id.fg_file_recyclerview); + toolbar = parentView.findViewById(R.id.fg_file_toolbar); + linearLayoutSearch = parentView.findViewById(R.id.fg_file_ll_search); + editTextSearch = parentView.findViewById(R.id.fg_file_et_search); + buttonSearch = parentView.findViewById(R.id.fg_file_btn_search); + fg_file_opendir_cl = parentView.findViewById(R.id.fg_file_opendir_cl); + + setHasOptionsMenu(true); + AppCompatActivity appCompatActivity = (AppCompatActivity) getActivity(); + appCompatActivity.setSupportActionBar(toolbar); + + if(canoniUrl.equals("")){ + //读取配置数据 + wifi_default_config = sharedPreferences.getBoolean("wifi_default_config",true); + gateway_config = sharedPreferences.getString("gateway_config",""); + samba_config = sharedPreferences.getString("samba_config",""); + link_diskdir_config = sharedPreferences.getString("link_diskdir_config",""); + + if(wifi_default_config){ + routerName = "Holl微路由"; + //默认路由为Holl + routerType = 0; + routerHost = Consts.NET_HOST_HOLL; + rootUrl = Consts.ROOT_URL_HOLL; + canoniUrl = Consts.CANONI_URL_HOLL; + }else{ + routerName = "智能路由器"; + if(gateway_config != "" && samba_config != "" && link_diskdir_config != "" ){ + routerType = 1; + routerHost = "http://" + gateway_config + "/" + link_diskdir_config + "/"; + rootUrl = "smb://" + samba_config + "@" + gateway_config + "/"; + canoniUrl = "smb://" + samba_config + "@" + gateway_config + "/"; + }else{ + Toast.makeText(getActivity(),"智能路由器未初始化配置",Toast.LENGTH_SHORT).show(); + } + } + } + + fg_file_error_iv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + fresh(canoniUrl); + } + }); + + LinearLayoutManager llm = new LinearLayoutManager(getActivity()); + llm.setOrientation(LinearLayoutManager.VERTICAL); + recyclerView.setLayoutManager(llm); + + myFgLvInfosList = new ArrayList<>(); + myFgLvArrayAdapter = new MyRecFilesAdapter(getActivity(),eventBus,routerType,routerHost,myFgLvInfosList); + recyclerView.setAdapter(myFgLvArrayAdapter); + + myFgLvArrayAdapter.setOnItemListener(new MyRecFilesAdapter.OnItemListener() { + @Override + public void onItemClick(View view, int position) { + if(myFgLvArrayAdapter.getMultiChoiceMode() == 1){ + //此时在多选状态,项目选择状态翻转 + CheckBox cb = view.findViewById(R.id.item_cb_fileselect); + + if(cb.isChecked()){ + myFgLvArrayAdapter.notifyItemChanged(position,false); + }else{ + myFgLvArrayAdapter.notifyItemChanged(position,true); + } + return; + } + + //加载完成前不允许再点击 + /** + * 判断项目类型 + * 1.文件夹--进入文件夹 + * 2.图片、办公文件--调用自带查看器 + * 3.其它--调用系统查看器 + */ + if(!fileOrDirList.get(position)){ + //文件夹 + toolbarTile = fileTitleList.get(position); + toolbar.setTitle(toolbarTile); + toolbar.setNavigationIcon(R.mipmap.back); + + parentTitBack.add(fileTitleList.get(position)); + parentUrlBack.add(parentUrlList.get(position)); + canoniUrl = canoniUrl + fileTitleList.get(position); + + fresh(canoniUrl); + }else{ + //分析文件类型 + boolean isFile = fileOrDirList.get(position); + + //Samba链接转真实链接 + String httpSrcUrl = ""; + switch (routerType){ + case 0: + httpSrcUrl = canoniUlrList.get(position).substring((canoniUlrList.get(position).indexOf("/holl/") + 5),canoniUlrList.get(position).length()); + break; + case 1: + httpSrcUrl = canoniUlrList.get(position).substring((canoniUlrList.get(position).indexOf("@192.168.80.1/") + 14),canoniUlrList.get(position).length()); + break; + } + + httpSrcUrl = routerHost + httpSrcUrl; + + String fileUrl = canoniUlrList.get(position).toLowerCase(); + + int label = MyFileUtils.getInstance().checkFileType(fileUrl); + + showFile(label,httpSrcUrl); + } + } + + @Override + public void onItemLongClick(View view, final int parentPosition) { + if(myFgLvArrayAdapter.getMultiChoiceMode() == 1){ + //此时在多选状态 + return; + } + + longClickItemIndex = parentPosition; + + View viewPoP = View.inflate(getActivity(),R.layout.dialog_file_longclick_menu,null); + + ListView listView = viewPoP.findViewById(R.id.dialog_file_longclick_menu_lv); + + String[] menuData = {"删除","下载","分析","重命名","取消"}; + ArrayAdapter arrayAdapter = new ArrayAdapter<>(getActivity(),android.R.layout.simple_list_item_1,menuData); + listView.setAdapter(arrayAdapter); + + final PopupWindow popupWindow = new PopupWindow(viewPoP,ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view,int position, long id) { + popupWindow.dismiss(); + + switch (position){ + case 0: + //删除 + if(canoniUrl.equals(rootUrl)){ + Toast.makeText(getActivity(),"抱歉,根目录不允许此操作",Toast.LENGTH_SHORT).show(); + return; + } + + AlertDialog ad = null; + final AlertDialog.Builder adb = new AlertDialog.Builder(getActivity()); + adb.setTitle("请确认是否删除:"); + adb.setMessage(fileTitleList.get(parentPosition)); + adb.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + dialog.dismiss(); + new Thread(new Runnable() { + @Override + public void run() { + //删除当前文件夹 + if(SambaUtils.getInstance(waitChangeTitle).deleteItem(canoniUrl,fileTitleList.get(parentPosition))){ + //刷新 + Message msg = new Message(); + msg.what = 131; + hanlderFile.sendMessage(msg); + }else{ + Message msg = new Message(); + msg.what = 125; + msg.obj = "抱歉,删除文件夹失败"; + hanlderFile.sendMessage(msg); + } + } + }).start(); + } + }); + adb.setNegativeButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + ad = adb.create(); + ad.show(); + ad.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + ad.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.RED); + break; + case 1: + //下载 + if(fileOrDirList.get(parentPosition)){ + //文件 + //判断读写权限是否正常 + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M){ + String[] needPermissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + List losePermissions = new ArrayList<>(); + for(int i = 0;i < needPermissions.length;i++){ + if(getActivity().checkSelfPermission(needPermissions[i]) != PackageManager.PERMISSION_GRANTED){ + losePermissions.add(needPermissions[i]); + } + } + if(!losePermissions.isEmpty()){ + //权限不正常 + String[] deneyPermissions = losePermissions.toArray(new String[losePermissions.size()]); + requestPermissions(deneyPermissions,REQUEST_PERMISSION_CODE); + }else{ + //权限都正常 + //检测本地Download目录是否已存在该文件 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File checkExists = new File(file.getPath() + "/com.example.wgjrouter/" + fileTitleList.get(parentPosition)); + + if(!checkExists.exists()){ + eventBus.postSticky(new MessageEvent(1,fileTypeList.get(parentPosition),fileTitleList.get(parentPosition),1,canoniUrl,canoniUlrList.get(parentPosition))); + Toast.makeText(getActivity(),"已添加到下载队列",Toast.LENGTH_SHORT).show(); + }else{ + if(transCoverFile){ + //覆盖下载 + eventBus.postSticky(new MessageEvent(1,fileTypeList.get(parentPosition),fileTitleList.get(parentPosition),1,canoniUrl,canoniUlrList.get(parentPosition))); + Toast.makeText(getActivity(),"已添加到下载队列(覆盖)",Toast.LENGTH_SHORT).show(); + }else{ + Toast.makeText(getActivity(),"本地已存在该文件",Toast.LENGTH_SHORT).show(); + } + } + } + } + }else{ + //低版本,不需要敏感权限确认 + //检测本地Download目录是否已存在该文件 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File checkExists = new File(file.getPath() + "/com.example.wgjrouter/" + fileTitleList.get(parentPosition)); + + if(!checkExists.exists()){ + eventBus.postSticky(new MessageEvent(1,fileTypeList.get(parentPosition),fileTitleList.get(parentPosition),1,canoniUrl,canoniUlrList.get(parentPosition))); + Toast.makeText(getActivity(),"已添加到下载队列",Toast.LENGTH_SHORT).show(); + }else{ + Toast.makeText(getActivity(),"本地已存在该文件",Toast.LENGTH_SHORT).show(); + } + } + } + }else{ + Toast.makeText(getActivity(),"抱歉,暂不支持下载文件夹",Toast.LENGTH_SHORT).show(); + } + break; + case 2: + //分析 + if(fileOrDirList.get(parentPosition)){ + //文件 + AlertDialog adf = null; + AlertDialog.Builder adbf = new AlertDialog.Builder(getActivity()); + adbf.setTitle(fileTitleList.get(parentPosition)); + adbf.setMessage(fileInfosList.get(parentPosition)); + adbf.setPositiveButton("好的", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + adf = adbf.create(); + adf.show(); + }else{ + //分析文件夹内含子项,耗时操作 + new Thread(new Runnable() { + @Override + public void run() { + List listSize = new ArrayList<>(); + listSize = SambaUtils.getInstance(waitChangeTitle).countDirSon(canoniUrl + fileTitleList.get(parentPosition)); + if(listSize != null){ + Message msg = new Message(); + msg.what = 128; + msg.obj = listSize; + msg.arg1 = parentPosition; + hanlderFile.sendMessage(msg); + }else{ + //分析子项数出现异常 + Message msg = new Message(); + msg.what = 127; + msg.obj = "抱歉,分析当前文件夹失败"; + hanlderFile.sendMessage(msg); + } + } + }).start(); + } + break; + case 3: + //重命名 + final AlertDialog adr = new AlertDialog.Builder(getActivity()).create(); + View viewR = View.inflate(getActivity(),R.layout.dialog_with_edittext,null); + TextView title = viewR.findViewById(R.id.dialog_with_et_title_tv); + final EditText newname = viewR.findViewById(R.id.dialog_with_et_input_et); + Button btnok = viewR.findViewById(R.id.dialog_with_et_ok_btn); + Button btnno = viewR.findViewById(R.id.dialog_with_et_no_btn); + + title.setText("请输入新文件名"); + newname.setHint("文件记得加后缀"); + //显示时去掉文件夹的后缀符 + newname.setText(fileTitleList.get(parentPosition).replace("/","")); + + adr.setView(viewR); + adr.show(); + + btnok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + adr.dismiss(); + + newfname = newname.getText().toString(); + + if(newfname.contains("\\") || newfname.contains("/") | newfname.contains(":") || newfname.contains("*") || newfname.contains("?") || newfname.contains("<") || newfname.contains(">") || newfname.contains("|")){ + Toast.makeText(getActivity(),"名称不可包含:\\/:*?<>|",Toast.LENGTH_SHORT).show(); + return; + } + + //新名称格式判断 + if(!fileOrDirList.get(parentPosition)){ + //文件夹 + newfname = newfname + "/"; + } + + if(newname.equals("")){ + Toast.makeText(getActivity(),"新的名称不可为空",Toast.LENGTH_SHORT).show(); + return; + } + + if(newfname.equals(fileTitleList.get(parentPosition))){ + Toast.makeText(getActivity(),"名称未做改变",Toast.LENGTH_SHORT).show(); + return; + } + + new Thread(new Runnable() { + @Override + public void run() { + + if(SambaUtils.getInstance(waitChangeTitle).renameFile(canoniUrl + fileTitleList.get(parentPosition),canoniUrl + newfname)){ + Message msg = new Message(); + msg.what = 130; + hanlderFile.sendMessage(msg); + }else{ + Message msg = new Message(); + msg.what = 129; + msg.obj = "抱歉,重命名失败,权限不足"; + hanlderFile.sendMessage(msg); + } + } + }).start(); + } + }); + btnno.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + adr.dismiss(); + } + }); + break; + } + } + }); + + ColorDrawable cd = new ColorDrawable(0xb0000000); + //new PaintDrawable(Color.parseColor("#66000000")) + popupWindow.setBackgroundDrawable(cd); + popupWindow.setOutsideTouchable(true); + popupWindow.setFocusable(true); + + int mRealSizeWidth; + int mRealSizeHeight; + + WindowManager windowManager = (WindowManager) getActivity().getApplication().getSystemService(Context.WINDOW_SERVICE); + Display display = windowManager.getDefaultDisplay(); + Point outPoint = new Point(); + if(Build.VERSION.SDK_INT >= 19){ + //考虑到虚拟按键 + display.getRealSize(outPoint); + }else{ + display.getSize(outPoint); + } + + mRealSizeWidth = outPoint.x; + mRealSizeHeight = outPoint.y; + + popupWindow.showAtLocation(parentView,Gravity.CENTER,0,0); + } + }); + + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + } + + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + + if(myFgLvArrayAdapter.canFresh()){ + if(recyclerView.canScrollVertically(1)){ + fg_file_sr.setEnabled(true); + } + }else{ + fg_file_sr.setEnabled(false); + } + } + }); + + toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + switch (menuItem.getItemId()){ + case R.id.file_option_download: + //批量下载 + List selectIndex = myFgLvArrayAdapter.getSelectItemIndex(); + final ArrayList selectItemTit = new ArrayList<>(); + final ArrayList selectItemUrl = new ArrayList<>(); + + for(int i = 0;i < selectIndex.size();i++){ + int position = selectIndex.get(i); + if(fileOrDirList.get(position)){ + //仅文件添加到下载队列中 + selectItemTit.add(fileTitleList.get(position)); + selectItemUrl.add(canoniUlrList.get(position)); + } + } + + if(selectIndex.size() > 0){ + new Thread(new Runnable() { + @Override + public void run() { + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + + for(int i = 0;i < selectItemTit.size();i++){ + boolean isDownloaded = new File(file.getPath() + "/com.example.wgjrouter/" + selectItemTit.get(i)).exists();//本地是否存在已完成的下载文件 + + if(!isDownloaded){ + //本地不存在下载文件 + EventBus.getDefault().postSticky(new MessageEvent(1,MyFileUtils.getInstance().checkFileType(selectItemUrl.get(i)),selectItemTit.get(i),1,"",selectItemUrl.get(i))); + }else if(transCoverFile){ + //本地已存在完整下载文件,覆盖下载 + EventBus.getDefault().postSticky(new MessageEvent(1,MyFileUtils.getInstance().checkFileType(selectItemUrl.get(i)),selectItemTit.get(i),1,"",selectItemUrl.get(i))); + } + } + } + }).start(); + + //取消掉勾选项 + myFgLvArrayAdapter.selectNone(); + Toast.makeText(getActivity(),"添加到下载队列(仅文件)",Toast.LENGTH_SHORT).show(); + }else{ + Toast.makeText(getActivity(),"无选择项",Toast.LENGTH_SHORT).show(); + } + break; + case R.id.file_option_delete: + List deleteIndex = myFgLvArrayAdapter.getSelectItemIndex(); + final List deleteItemUrl = new ArrayList<>(); + List listTit = new ArrayList<>(); + + for(int i = 0;i < deleteIndex.size();i++){ + int position = deleteIndex.get(i); + deleteItemUrl.add(canoniUlrList.get(position)); + + listTit.add(fileTitleList.get(position)); + } + + final int deleteCounts = listTit.size(); + if(deleteCounts > 0){ + String[] arrayTit = listTit.toArray(new String[listTit.size()]); + + AlertDialog ad; + AlertDialog.Builder adb = new AlertDialog.Builder(getActivity()); + adb.setTitle("删除 " + deleteCounts + " 项," + "请确认"); + adb.setItems(arrayTit,null); + adb.setPositiveButton("删除(不可恢复)", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + View view = View.inflate(getActivity(),R.layout.dialog_waitting_doing,null); + + alertDialog = new AlertDialog.Builder(getActivity()) + .setView(view) + .create(); + alertDialog.show(); + + //退出多选模式 + isEdit = false; + setStateEdit(isEdit); + + new Thread(new Runnable() { + @Override + public void run() { + int delCount = 0; + + for(int i = 0;i < deleteCounts;i++){ + //每一项挨个删除 + SambaUtils.getInstance(waitChangeTitle).deleteItem(deleteItemUrl.get(i),""); + + delCount++; + + Message msg = new Message(); + msg.obj = "删除进度:" + delCount + "/" + deleteCounts; + msg.what = 132; + msg.arg1 = 0; + hanlderFile.sendMessage(msg); + } + + Message msg = new Message(); + msg.what = 132; + msg.arg1 = 1; + hanlderFile.sendMessage(msg); + } + }).start(); + } + }); + adb.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + ad = adb.create(); + ad.show(); + ad.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + ad.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.RED); + }else{ + Toast.makeText(getActivity(),"无选择项",Toast.LENGTH_SHORT).show(); + } + break; + case R.id.file_option_selectall: + if(myFgLvArrayAdapter.isSelectAll()){ + myFgLvArrayAdapter.selectNone(); + }else{ + myFgLvArrayAdapter.selectAll(); + } + break; + case R.id.file_option_operate: + if(canoniUrl.equals(rootUrl)){ + Toast.makeText(getActivity(),"抱歉,根目录不允许此操作",Toast.LENGTH_SHORT).show(); + return true; + } + + //多选操作 + if(myFgLvArrayAdapter.getMultiChoiceMode() == 0){ + isEdit = true; + setStateEdit(isEdit); + } + break; + case R.id.file_option_upload: + //上传文件 + if(canoniUrl.equals(rootUrl)){ + Toast.makeText(getActivity(),"抱歉,根目录不允许此操作",Toast.LENGTH_SHORT).show(); + return true; + } + + //判断读写权限是否正常 + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M){ + String[] needPermissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + List losePermissions = new ArrayList<>(); + for(int i = 0;i < needPermissions.length;i++){ + if(getActivity().checkSelfPermission(needPermissions[i]) != PackageManager.PERMISSION_GRANTED){ + losePermissions.add(needPermissions[i]); + } + } + if(!losePermissions.isEmpty()){ + //权限不正常 + String[] deneyPermissions = losePermissions.toArray(new String[losePermissions.size()]); + requestPermissions(deneyPermissions,REQUEST_PERMISSION_CODE); + }else{ + //权限都正常 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + //当前目录上传文件 + Intent selFile = new Intent(Intent.ACTION_GET_CONTENT); + selFile.setType("*/*"); + selFile.addCategory(Intent.CATEGORY_OPENABLE); + try { + startActivityForResult(Intent.createChooser(selFile,"Select a File to Upload"),FILE_REQUEST_CODE); + } catch (ActivityNotFoundException e) { + Toast.makeText(getActivity(),"抱歉,未找到文件管理器",Toast.LENGTH_SHORT).show(); + } + } + } + }else{ + //低版本,不需要敏感权限确认 + //检测本地Download目录是否已存在该文件 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + //当前目录上传文件 + Intent selFile = new Intent(Intent.ACTION_GET_CONTENT); + selFile.setType("*/*"); + selFile.addCategory(Intent.CATEGORY_OPENABLE); + try { + startActivityForResult(Intent.createChooser(selFile,"Select a File to Upload"),FILE_REQUEST_CODE); + } catch (ActivityNotFoundException e) { + Toast.makeText(getActivity(),"抱歉,未找到文件管理器",Toast.LENGTH_SHORT).show(); + } + } + } + break; + case R.id.file_option_newfolder: + /** + * 当前目录新建文件夹 + * 1.根目录不能用于新建、上传、删除等操作 + */ + if(canoniUrl.equals(rootUrl)){ + Toast.makeText(getActivity(),"抱歉,根目录不允许此操作",Toast.LENGTH_SHORT).show(); + return true; + } + + final AlertDialog dialog = new AlertDialog.Builder(getActivity()).create(); + + View viewDialog = View.inflate(getActivity(),R.layout.dialog_with_edittext,null); + + TextView title = viewDialog.findViewById(R.id.dialog_with_et_title_tv); + final EditText folder = viewDialog.findViewById(R.id.dialog_with_et_input_et); + Button btnok = viewDialog.findViewById(R.id.dialog_with_et_ok_btn); + Button btnno = viewDialog.findViewById(R.id.dialog_with_et_no_btn); + + title.setText("请输入新文件夹名"); + + dialog.setView(viewDialog); + dialog.setCancelable(true); + dialog.setCanceledOnTouchOutside(false); + dialog.show(); + + btnok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + newFolderName = folder.getText().toString(); + + if(!newFolderName.equals("")){ + dialog.dismiss(); + + new Thread(new Runnable() { + @Override + public void run() { + if(SambaUtils.getInstance(waitChangeTitle).newFolder(canoniUrl,newFolderName)){ + + jsonFileDir = SambaUtils.getInstance(waitChangeTitle).getPathDirFile(canoniUrl); + + if(!jsonFileDir.startsWith("Error:")){ + handler.post(okrun); + }else{ + newFolderName = null; + handler.post(errun); + } + + isFresh = false; + }else{ + newFolderName = null; + Toast.makeText(getActivity(),"抱歉,新建文件夹失败",Toast.LENGTH_SHORT).show(); + } + } + }).start(); + }else{ + Toast.makeText(getActivity(),"请输入正确的文件夹名称",Toast.LENGTH_SHORT).show(); + } + } + }); + + btnno.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + } + }); + break; + case R.id.file_option_count: + AlertDialog.Builder adbc = new AlertDialog.Builder(getActivity()); + adbc.setTitle("当前目录统计:" ); + adbc.setMessage("文件夹:" + String.valueOf(dirCounts) + + "\n文件:" + String.valueOf(fileCounts)); + adbc.setPositiveButton("好的", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + dialogInterface.dismiss(); + } + }).show(); + break; + case R.id.file_option_backroot: + parentTitBack.clear(); + parentUrlBack.clear(); + + toolbarTile = ""; + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + canoniUrl = rootUrl; + + fresh(canoniUrl); + break; + case R.id.file_option_change_router: + if(wifi_default_config){ + //切到智能路由器 + gateway_config = sharedPreferences.getString("gateway_config",""); + samba_config = sharedPreferences.getString("samba_config",""); + link_diskdir_config = sharedPreferences.getString("link_diskdir_config",""); + + if(gateway_config != "" && samba_config != "" && link_diskdir_config != ""){ + routerType = 1; + routerHost = "http://" + gateway_config + "/" + link_diskdir_config + "/"; + rootUrl = "smb://" + samba_config + "@" + gateway_config + "/"; + canoniUrl = "smb://" + samba_config + "@" + gateway_config + "/"; + + wifi_default_config = false; + toolbarTile = ""; + routerName = "智能路由器"; + waitChangeTitle = true; + + myFgLvArrayAdapter.initRouterParams(routerType,routerHost); + fresh(canoniUrl); + }else{ + Toast.makeText(getActivity(),"智能路由器未初始化配置",Toast.LENGTH_SHORT).show(); + } + }else{ + //切到默认路由器Holl + routerType = 0; + routerHost = Consts.NET_HOST_HOLL; + rootUrl = Consts.ROOT_URL_HOLL; + canoniUrl = Consts.CANONI_URL_HOLL; + + wifi_default_config = true; + toolbarTile = ""; + routerName = "Holl微路由"; + waitChangeTitle = true; + + myFgLvArrayAdapter.initRouterParams(routerType,routerHost); + fresh(canoniUrl); + } + break; + } + return true; + } + }); + + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(myFgLvArrayAdapter.getMultiChoiceMode() == 0){ + backFatherDir(); + }else{ + isEdit = false; + setStateEdit(isEdit); + } + } + }); + + //当前目录搜索 + buttonSearch.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + linearLayoutSearch.setVisibility(View.GONE); + + if(!editTextSearch.getText().toString().equals("")){ + searchFile(editTextSearch.getText().toString()); + } + } + }); + + editTextSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { + if(actionId == EditorInfo.IME_ACTION_SEARCH){ + linearLayoutSearch.setVisibility(View.GONE); + + //搜索 + if(!editTextSearch.getText().toString().equals("")){ + searchFile(editTextSearch.getText().toString()); + } + } + return true; + } + }); + + fg_file_sr.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + fresh(canoniUrl); + + fg_file_sr.setRefreshing(false); + } + }); + + if(toolbarTile.equals("")){ + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + }else{ + toolbar.setTitle(toolbarTile); + toolbar.setNavigationIcon(R.mipmap.back); + + if(isEdit){ + isEdit = false; + setStateEdit(false); + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MessageEvent event) { + switch (event.getEventType()){ + case 3: + //上传成功,刷新(切换到其它目录时不受影响,仅是刷新当前路径) + fresh(canoniUrl); + break; + case 4: + Snackbar.make(fg_file_opendir_cl,"已成功下载到本地",Snackbar.LENGTH_LONG) + .setAction("查看", new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent look = new Intent(getActivity(),FileTransFinish.class); + startActivity(look); + } + }) + .setActionTextColor(Color.LTGRAY) + .show(); + break; + case 5: + //返回上册目录 + backFatherDir(); + case 7: + //隐藏大图查看器 + if(popupWindowPic != null && popupWindowPic.isShowing()){ + popupWindowPic.dismiss(); + } + break; + case 8: + if(isEdit){ + //关闭多选模式 + isEdit = false; + setStateEdit(isEdit); + } + break; + case 22: + if(event.getFileType() == fileTitleList.size()){ + //当前全选 + toolbar.getMenu().findItem(R.id.file_option_selectall).setTitle("全不选"); + }else{ + toolbar.getMenu().findItem(R.id.file_option_selectall).setTitle("全选"); + } + + toolbar.setTitle("项:" + event.getFileType() + "/" + fileTitleList.size()); + break; + } + }; + + private void backFatherDir(){ + if(parentUrlBack.size() == 0){ + //没有可返回的父路径 + toolbarTile = ""; + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + return; + } + + if(isFresh){ + return; + } + + canoniUrl = parentUrlBack.get(parentUrlBack.size() - 1); + + parentUrlBack.remove(parentUrlBack.size() - 1); + parentTitBack.remove(parentTitBack.size() - 1); + + if(parentTitBack.size() != 0){ + toolbarTile = parentTitBack.get(parentTitBack.size() - 1); + toolbar.setTitle(toolbarTile); + toolbar.setNavigationIcon(R.mipmap.back); + }else{ + toolbarTile = ""; + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + } + + fresh(canoniUrl); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull final String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + List deneyPermissionsList = new ArrayList<>(); + if(requestCode == REQUEST_PERMISSION_CODE){ + if(grantResults.length > 0){ + for(int i = 0;i < grantResults.length;i++){ + if(grantResults[i] != PackageManager.PERMISSION_GRANTED){ + //权限未放行 + deneyPermissionsList.add(permissions[i]); + } + } + + if(!deneyPermissionsList.isEmpty()){ + String[] deneyPermissions = deneyPermissionsList.toArray(new String[deneyPermissionsList.size()]); + //判断是否点击了不再提示(是否可再重新申请) + boolean ii = shouldShowRequestPermissionRationale(deneyPermissions[0]); + + //未点击>不再询问,拒绝时返回 true,表名还可再请求权限 + if(ii){ + //还可再申请权限 + new AlertDialog.Builder(getActivity()) + .setTitle("允许\"微管家\"获取读写存储器权限吗?") + .setMessage("微管家在上传、下载文件时需要读写存储器权限") + .setPositiveButton("允许", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + requestPermissions(permissions,REQUEST_PERMISSION_CODE); + } + }) + .setNegativeButton("不允许", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Toast.makeText(getActivity(),"用上传、下载功能将受限",Toast.LENGTH_SHORT).show(); + } + }) + .create().show(); + }else{ + Toast.makeText(getActivity(),"未能获得读写存储器权限",Toast.LENGTH_SHORT).show(); + } + } + } + } + } + + Runnable okrun = new Runnable() { + @Override + public void run() { + if(waitChangeTitle){ + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + } + waitChangeTitle = false; + + recyclerView.setVisibility(View.VISIBLE); + fg_file_error_iv.setVisibility(View.GONE); + + try { + JsonParser jsonParser = new JsonParser(); + JsonArray jsonArray = jsonParser.parse(jsonFileDir).getAsJsonArray(); + + //刷新前清空 + fileInfosList.clear(); + myFgLvInfosList.clear(); + fileOrDirList.clear(); + fileTitleList.clear(); + fileTypeList.clear(); + parentUrlList.clear(); + canoniUlrList.clear(); + picItemUrlList.clear(); + videoItemUrlList.clear(); + videoTitleList.clear(); + dirCounts = 0; + fileCounts = 0; + + int index = 0; + //文件属性 + String fileInfo = "文件大小:**\n" + "修改日期:##\n"; + for(JsonElement je : jsonArray){ + SmbFileInfos smbFileInfos = gson.fromJson(je,SmbFileInfos.class); + + MyRecFileInfos myFgLvInfos = new MyRecFileInfos(); + myFgLvInfos.setFilePath(smbFileInfos.getCanoniUrl()); + myFgLvInfos.setFileTitle(smbFileInfos.getName()); + myFgLvInfos.setFileSize(smbFileInfos.getSize()); + myFgLvInfos.setSizeUnit(smbFileInfos.getSizeUnit()); + myFgLvInfos.setFileDate(smbFileInfos.getDate()); + myFgLvInfos.setIsFile(smbFileInfos.getIsFile()); + + fileInfo = fileInfo.replace("**",String.valueOf(smbFileInfos.getSize()) + smbFileInfos.getSizeUnit()); + fileInfo = fileInfo.replace("##", MyDateUtils.getInstance().getCurrentDate(smbFileInfos.getDate())); + + if(smbFileInfos.getIsDir()){ + myFgLvInfos.setItemCount(smbFileInfos.getCounts()); + } + + if(smbFileInfos.getIsFile()){ + ////Samba链接转真实链接 + String httpSrcUrl = ""; + switch (routerType){ + case 0: + httpSrcUrl = smbFileInfos.getCanoniUrl().substring((smbFileInfos.getCanoniUrl().indexOf("/holl/") + 5),smbFileInfos.getCanoniUrl().length()); + break; + case 1: + httpSrcUrl = smbFileInfos.getCanoniUrl().substring((smbFileInfos.getCanoniUrl().indexOf("@192.168.80.1/") + 14),smbFileInfos.getCanoniUrl().length()); + break; + } + + httpSrcUrl = routerHost + httpSrcUrl; + + String fileUrl = smbFileInfos.getCanoniUrl().toLowerCase(); + if(fileUrl.endsWith("png") || fileUrl.endsWith("jpg") || fileUrl.endsWith("bmp") || fileUrl.endsWith("gif") || fileUrl.endsWith("jpeg") || fileUrl.endsWith("ico")){ + //将当前文件夹所有的图片地址存入List + picItemUrlList.add(httpSrcUrl); + } + if(fileUrl.endsWith("avi") || fileUrl.endsWith("mov") || fileUrl.endsWith("mp4") || fileUrl.endsWith("mkv") || fileUrl.endsWith("wmv") || fileUrl.endsWith("flv") || fileUrl.endsWith("rmvb")){ + //将当前文件夹所有的视频地址存入list + videoItemUrlList.add(httpSrcUrl); + videoTitleList.add(fileUrl.substring(fileUrl.lastIndexOf("/") + 1,fileUrl.lastIndexOf("."))); + } + } + + if(smbFileInfos.getName().equals(newFolderName + "/")){ + //该项为刚新建的文件夹 + newFolderIndex = index; + } + + fileInfosList.add(fileInfo); + fileOrDirList.add(smbFileInfos.getIsFile()); + fileTitleList.add(smbFileInfos.getName()); + fileTypeList.add(CheckFileType(smbFileInfos.getCanoniUrl())); + parentUrlList.add(smbFileInfos.getParentUrl()); + canoniUlrList.add(smbFileInfos.getCanoniUrl()); + + //初始化文件夹、文件的数量,用于文件、文件夹数量统计 + if(smbFileInfos.getIsDir()){ + dirCounts++; + }else{ + fileCounts++; + } + + myFgLvInfosList.add(myFgLvInfos); + + index = index + 1; + } + + myFgLvArrayAdapter.setCanInitData(true); + myFgLvArrayAdapter.notifyDataSetChanged(); + + //新建文件夹时跳到该新文件夹的索引 + if(newFolderName != null){ + if(newFolderIndex != 0){ + //匹配到新建的文件夹名 + recyclerView.scrollToPosition(newFolderIndex); + newFolderName = ""; + newFolderIndex = 0; + } + }else if(longClickItemIndex == 0){ + recyclerView.scrollToPosition(0); + longClickItemIndex = 0; + } + + fg_file_pb.setVisibility(View.GONE); + } catch (JsonSyntaxException e) { + e.printStackTrace(); + fg_file_pb.setVisibility(View.GONE); + } + } + }; + + Runnable errun = new Runnable() { + @Override + public void run() { + recyclerView.setVisibility(View.GONE); + fg_file_error_iv.setVisibility(View.VISIBLE); + + if(waitChangeTitle == true){ + if(wifi_default_config == false){ + //从Holl切智能失败 + routerType = 0; + routerHost = Consts.NET_HOST_HOLL; + rootUrl = Consts.ROOT_URL_HOLL; + canoniUrl = Consts.CANONI_URL_HOLL; + routerName = "Holl微路由"; + + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + + wifi_default_config = true; + }else{ + routerType = 1; + routerHost = "http://" + gateway_config + "/" + link_diskdir_config + "/"; + rootUrl = "smb://" + samba_config + "@" + gateway_config + "/"; + canoniUrl = "smb://" + samba_config + "@" + gateway_config + "/"; + routerName = "智能路由器"; + + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + + wifi_default_config = false; + } + + Toast.makeText(getActivity(),"切换失败,回滚中...",Toast.LENGTH_SHORT).show(); + myFgLvArrayAdapter.initRouterParams(routerType,routerHost); + fresh(canoniUrl); + } + + waitChangeTitle = false; + fg_file_pb.setVisibility(View.GONE); + } + }; + + @Override + public void onPrepareOptionsMenu(Menu menu) { + menu.clear(); + + if(isEdit){ + getActivity().getMenuInflater().inflate(R.menu.file_edit_menu,menu); + toolbar.setTitle("项:" + myFgLvArrayAdapter.getSelectItemIndex().size() + "/" + fileTitleList.size()); + toolbar.setNavigationIcon(R.mipmap.rollback); + }else{ + getActivity().getMenuInflater().inflate(R.menu.file_option_menu,menu); + + if(toolbarTile.equals("")){ + toolbar.setTitle(routerName); + toolbar.setNavigationIcon(null); + }else{ + toolbar.setTitle(toolbarTile); + toolbar.setNavigationIcon(R.mipmap.back); + } + } + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.file_option_menu,menu); + } + + //模糊搜索当前界面 + private void searchFile(String fileName){ + if(fileTitleList.size() == 0){ + return; + } + + for(int i = 0;i < fileTitleList.size();i++){ + if(fileTitleList.get(i).indexOf(fileName) != -1){ + //匹配 + } + } + + toolbar.setTitle("搜索:" + fileName); + toolbar.setNavigationIcon(R.mipmap.rollback); + } + + //全局搜索 + private void searchAllFile(){ + + } + + //查看文件 + private void showFile(int fileType,String srcNetUrl){ + switch(fileType){ + case 0: + //apk + break; + case 2: + //xls + break; + case 3: + //doc + break; + case 4: + //ppt + break; + case 6: + //ini + break; + case 7: + //iso + break; + case 9: + //pdf + break; + case 11: + //txt + break; + case 12: + //jar包 + break; + case 13: + //压缩包 + break; + case 14: + //大图 + fg_file_showpic_label.setTag("show"); + //根据ListView的点击项获取图片List中的对应索引 + clickPicIndex = picItemUrlList.indexOf(srcNetUrl); + + if(parentView != null){ + View viewPoP = LayoutInflater.from(getActivity()).inflate(R.layout.layout_fg_file_pop_bigpic,null); + + popupWindowPic = new PopupWindow(viewPoP,ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT); + + final ImageView leftPic = viewPoP.findViewById(R.id.iv_file_pop_bigpic_left); + final ImageView rightPic = viewPoP.findViewById(R.id.iv_file_pop_bigpic_right); + final PhotoView bigPicIV = viewPoP.findViewById(R.id.iv_file_pop_bigpic); + ImageView bigPicIVClose = viewPoP.findViewById(R.id.iv_file_pop_bigpic_close); + + bigPicIVClose.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + popupWindowPic.dismiss(); + } + }); + + leftPic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickPicIndex = clickPicIndex - 1; + + if(clickPicIndex >= 0){ + rightPic.setVisibility(View.VISIBLE); + Picasso.get().load(picItemUrlList.get(clickPicIndex)) + .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .into(bigPicIV); + }else{ + clickPicIndex = 0; + leftPic.setVisibility(View.GONE); + Toast.makeText(getActivity(),"这是第一张呀",Toast.LENGTH_SHORT).show(); + } + } + }); + + rightPic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickPicIndex = clickPicIndex + 1; + + if(clickPicIndex < picItemUrlList.size()){ + leftPic.setVisibility(View.VISIBLE); + Picasso.get().load(picItemUrlList.get(clickPicIndex)) + .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .into(bigPicIV); + }else{ + clickPicIndex = clickPicIndex - 1; + rightPic.setVisibility(View.GONE); + Toast.makeText(getActivity(),"最后一张了",Toast.LENGTH_SHORT).show(); + } + } + }); + + bigPicIV.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + popupWindowPic.dismiss(); + return true; + } + }); + + popupWindowPic.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + fg_file_showpic_label.setTag("hiddle"); + } + }); + +// bigPicIV.setOnTouchListener(new View.OnTouchListener() { +// @Override +// public boolean onTouch(View view, MotionEvent motionEvent) { +// switch (motionEvent.getAction()){ +// case MotionEvent.ACTION_DOWN: +// mPosX = motionEvent.getX(); +// mPosY = motionEvent.getY(); +// break; +// case MotionEvent.ACTION_MOVE: +// break; +// case MotionEvent.ACTION_UP: +// mCurPosX = motionEvent.getX(); +// mCurPosY = motionEvent.getY(); +// +// if(mCurPosX - mPosX > 50 && Math.abs(mCurPosY - mPosY) < 30){ +// //右滑动,上一章图片 +// if(!isShowPic){ +// isShowPic = true; +// +// clickPicIndex = clickPicIndex - 1; +// +// if(clickPicIndex >= 0){ +// Picasso.get().load(picItemUrlList.get(clickPicIndex)) +// .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) +// .placeholder(R.mipmap.loading_zhanwei) +// .error(R.mipmap.loading_faild) +// .into(bigPicIV); +// }else{ +// clickPicIndex = 0; +// Toast.makeText(getActivity(),"这是第一张呀",Toast.LENGTH_SHORT).show(); +// } +// isShowPic = false; +// } +// }else if(mCurPosX - mPosX < -50 && Math.abs(mCurPosY - mPosY) < 30){ +// //左滑动,下一站图片 +// if(!isShowPic){ +// isShowPic = true; +// +// clickPicIndex = clickPicIndex + 1; +// +// if(clickPicIndex < picItemUrlList.size()){ +// Picasso.get().load(picItemUrlList.get(clickPicIndex)) +// .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) +// .placeholder(R.mipmap.loading_zhanwei) +// .error(R.mipmap.loading_faild) +// .into(bigPicIV); +// }else{ +// clickPicIndex = clickPicIndex - 1; +// Toast.makeText(getActivity(),"最后一张了",Toast.LENGTH_SHORT).show(); +// } +// isShowPic = false; +// } +// }else if(mCurPosY - mPosY < -50 && Math.abs(mCurPosX - mPosX) < 30){ +// //上滑动 +// +// }else if(mCurPosY - mPosY > 50 && Math.abs(mCurPosX - mPosX) < 30){ +// //下滑动,关闭图片 +// popupWindow.dismiss(); +// } +// break; +// default: +// break; +// } +// return true; +// } +// }); + + Picasso.get().load(srcNetUrl) + .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .into(bigPicIV); + + popupWindowPic.showAtLocation(parentView, Gravity.CENTER,0,0); + } + break; + case 15: + //视频 + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); + boolean default_resolver_inner = sp.getBoolean("default_resolver_inner",true); + + if(default_resolver_inner){ + //内部解析 + Intent intent = new Intent(getActivity(),VideoPlayVTM.class); + intent.putExtra("videoType",0); + intent.putExtra("videoUrl",srcNetUrl); + intent.putExtra("videoTitle",srcNetUrl.substring((srcNetUrl.lastIndexOf("/") + 1),srcNetUrl.length())); + intent.putStringArrayListExtra("videoUrlList",videoItemUrlList); + intent.putStringArrayListExtra("videoTitleList",videoTitleList); + startActivity(intent); + }else{ + MyPhoneUtils.getInstance(getActivity()).usePlayerPlayNetVideo(srcNetUrl); + } + break; + case 16: + //磁链种子 + break; + case 17: + //音频 + break; + default: + //无自带解析器,调用其它解析器 + break; + } + + isFresh = false; + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if(resultCode == Activity.RESULT_OK && requestCode == FILE_REQUEST_CODE){ + + if(data == null){ + return; + } + + Uri uri = data.getData(); + + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT){ + //4.4以上系统 + urlPath = getPathFromUri(getContext(),uri); + }else{ + urlPath = getRealPathFromUri(getContext(),uri); + } + + if(urlPath == null){ + //文件真实路径解析失败 + Toast.makeText(getActivity(),"抱歉,文件路径解析失败",Toast.LENGTH_SHORT).show(); + return; + } + + final File file = new File(urlPath); + fileType = CheckFileType(urlPath); + + //检测文件是否存在 + new Thread(new Runnable() { + @Override + public void run() { + if(SambaUtils.getInstance(waitChangeTitle).checkFileOrDirExist(canoniUrl + file.getName())){ + Message msg = new Message(); + msg.what = 126; + msg.obj = file.getName(); + msg.arg1 = fileType; + hanlderFile.sendMessage(msg); + }else{ + eventBus.postSticky(new MessageEvent(2,fileType,file.getName(),0,canoniUrl,urlPath)); + } + } + }).start(); + } + } + + /** + * 4.4以上系统 + * @param uri + * @return + */ + private String getPathFromUri(Context context,Uri uri){ + Log.d("zouguo","1:" + uri.getScheme()); + Log.d("zouguo","2:" + uri.getAuthority()); + Log.d("zouguo","2.1:" + uri.getSchemeSpecificPart()); + Log.d("zouguo","2.2:" + uri.getEncodedAuthority()); + Log.d("zouguo","2.3:" + uri.getEncodedSchemeSpecificPart()); + + if(DocumentsContract.isDocumentUri(context,uri)){ + String docId = DocumentsContract.getDocumentId(uri); + Log.d("zouguo","3:" + docId); + + if("com.android.externalstorage.documents".equals(uri.getAuthority())){ + String[] split = docId.split(":"); + String type = split[0]; + + if("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + }else{ + return "/storage/".concat(type).concat("/").concat(split[1]); + } + }else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){ + if(docId.startsWith("raw")){ + Log.d("zouguo","3.1:" + docId); + + String[] split = docId.split(":"); + String type = split[0]; + return split[1]; + } + + Log.d("zouguo","3.2:" + docId); + //7.0 + if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N){ + Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId)); + return getFilePath(context,contentUri,null,null); + }else{ + //访问all_downloads需要具备android.permission.ACCESS_ALL_DOWNLOADS权限,系统级别的应用才可以访问 +// DownloadManager dm = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE); +// +// DownloadManager.Query dmq = new DownloadManager.Query();//.setFilterById(Long.parseLong(docId)) +// Cursor c = dm.query(dmq); +// +// if(c != null && c.moveToFirst()){ +// int idx = c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); +// String name = c.getString(idx); +// +// File file = new File(name); +// +// Log.d("zouguo","2--8.0往上系统文件路径获取" + name); +// Log.d("zouguo","2--8.0往上系统文件路径获取" + file.getPath()); +// Log.d("zouguo","2--8.0往上系统文件路径获取" + file.getAbsolutePath()); +// +// c.close(); +// }else{ +// Log.d("zouguo","2--8.0失败"); +// } + + Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/all_downloads"),Long.valueOf(docId)); + Log.d("zouguo","8.0往上系统文件路径获取"); + Log.d("zouguo","8.0:" + contentUri.getPath()); + return getFilePath(context,contentUri,null,null); + } + }else if("com.android.providers.media.documents".equals(uri.getAuthority())){ + String[] split = docId.split(":"); + String type = split[0]; + + Uri contentUri = null; + if("image".equals(type)){ + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + }else if("video".equals(type)){ + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + }else if("audio".equals(type)){ + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + String selection = "_id=?"; + String [] selectionArgs = new String[]{split[1]}; + + return getFilePath(context,contentUri,selection,selectionArgs); + } + }else if("content".equalsIgnoreCase(uri.getScheme())){ + return getFilePath(context,uri,null,null); + }else if("file".equalsIgnoreCase(uri.getScheme())){ + return uri.getPath(); + } + return null; + } + + /** + * 4.4以下系统 + * @param uri + * @return + */ + private String getRealPathFromUri(Context context,Uri uri){ + String path = null; + + String[] proj = {MediaStore.Images.Media.DATA}; + Cursor cursor = context.getContentResolver().query(uri,proj,null,null,null); + if(null != cursor && cursor.moveToFirst()){ + int cindex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + path = cursor.getString(cindex); + cursor.close(); + } + return path; + } + + private String getFilePath(Context context,Uri uri,String selection,String[] selectionArgs){ + Cursor cursor = null; + String column = "_data"; + String[] proj = {column}; + + try { + cursor = context.getContentResolver().query(uri,proj,selection,selectionArgs,null); + if(cursor != null && cursor.moveToFirst()){ + int cIndex = cursor.getColumnIndexOrThrow(column); + return cursor.getString(cIndex); + } + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e){ + e.printStackTrace(); + } finally { + if(cursor != null) + cursor.close(); + } + return null; + } + + /** + * 解析文件类型 + * @param fileUrl + * @return + */ + private int CheckFileType(String fileUrl){ + int label = 1; + if(fileUrl.endsWith("png") || fileUrl.endsWith("jpg") || fileUrl.endsWith("bmp") || fileUrl.endsWith("gif") || fileUrl.endsWith("jpeg") || fileUrl.endsWith("ico")){ + label = 14; + } else if(fileUrl.endsWith("apk")){ + label = 0; + } else if(fileUrl.endsWith("xls") || fileUrl.endsWith("xlsx")){ + label = 2; + } else if(fileUrl.endsWith("doc") || fileUrl.endsWith("docx")){ + label = 3; + } else if(fileUrl.endsWith("ppt") || fileUrl.endsWith("pptx")){ + label = 4; + } else if(fileUrl.endsWith("exe")){ + label = 5; + } else if(fileUrl.endsWith("ini")){ + label = 6; + } else if(fileUrl.endsWith("iso")){ + label = 7; + } else if(fileUrl.endsWith("link")){ + label = 8; + } else if(fileUrl.endsWith("pdf")){ + label = 9; + } else if(fileUrl.endsWith("psd")){ + label = 10; + } else if(fileUrl.endsWith("txt")){ + label = 11; + } else if(fileUrl.endsWith("jar")){ + label = 12; + } else if(fileUrl.endsWith("zip") || fileUrl.endsWith("rar") || fileUrl.endsWith("tar") || fileUrl.endsWith("7z")){ + label = 13; + } else if(fileUrl.endsWith("avi") || fileUrl.endsWith("mov") || fileUrl.endsWith("mp4") || fileUrl.endsWith("mkv") || fileUrl.endsWith("wmv") || fileUrl.endsWith("flv") || fileUrl.endsWith("rmvb")){ + label = 15; + } else if(fileUrl.endsWith("torrent")) { + label = 16; + }else if(fileUrl.endsWith("mp3") || fileUrl.endsWith("wma") || fileUrl.endsWith("wav")){ + label = 17; + }else{ + label = 18; + } + return label; + } + + private void initNotification(String title,String content){ + NotificationChannel notificationChannel = null; + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ + notificationChannel = new NotificationChannel(CHANNEL_ID,CHANNEL_NAME,NotificationManager.IMPORTANCE_DEFAULT); + notificationChannel.enableLights(true); + notificationChannel.setLightColor(Color.GREEN); + notificationChannel.setShowBadge(false); + notificationChannel.enableVibration(false); + notificationChannel.setVibrationPattern(new long[]{0}); + } + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ + nb = new Notification.Builder(getActivity(),CHANNEL_ID); + nb.setContentTitle(title) + .setSmallIcon(R.mipmap.smallicon) + .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)) + .setWhen(System.currentTimeMillis()) + .setContentText(content) + .setProgress(100,0,false) + .build(); + notification = nb.build(); + }else{ + ncb = new NotificationCompat.Builder(getActivity()); + ncb.setContentTitle(title) + .setSmallIcon(R.mipmap.smallicon) + .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)) + .setWhen(System.currentTimeMillis()) + .setContentText(content) + .setProgress(100,0,false) + .setVibrate(new long[]{0}) + .build(); + notification = ncb.build(); + } + + notificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE); + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ + notificationManager.createNotificationChannel(notificationChannel); + } + notificationManager.notify(1,notification); + } + + private void fresh(final String urlPath){ + if(isFresh){ + return; + } + + isFresh = true; + + recyclerView.setVisibility(View.GONE); + fg_file_pb.setVisibility(View.VISIBLE); + + new Thread(new Runnable() { + @Override + public void run() { + jsonFileDir = SambaUtils.getInstance(waitChangeTitle).getPathDirFile(urlPath); + +// Log.d("zouguo","刷新:" + urlPath); +// Log.d("zouguo","结果:" + jsonFileDir); + + if(!jsonFileDir.startsWith("Error:")){ + handler.post(okrun); + }else{ + handler.post(errun); + } + + isFresh = false; + } + }).start(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + + eventBus.unregister(this); + getActivity().unregisterReceiver(networkChangeReceive); + } + + //进入、退出编辑状态 + private void setStateEdit(boolean isEdit){ + if(isEdit){ + getActivity().invalidateOptionsMenu(); + myFgLvArrayAdapter.setMultiChoiceMode(1); + fg_file_sr.setEnabled(false); + }else{ + getActivity().invalidateOptionsMenu(); + myFgLvArrayAdapter.setMultiChoiceMode(0); + fg_file_sr.setEnabled(true); + + MenuItem menuItem = toolbar.getMenu().findItem(R.id.file_option_selectall); + if(menuItem != null){ + if(myFgLvArrayAdapter.isSelectAll()){ + menuItem.setTitle("全不选"); + }else{ + menuItem.setTitle("全选"); + } + } + } + } + + private void setOutsideAlpha(float alpha){ + WindowManager.LayoutParams params = getActivity().getWindow().getAttributes(); + params.alpha = alpha; + getActivity().getWindow().setAttributes(params); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/wgjrouter/FragmentHome.java b/app/src/main/java/com/example/wgjrouter/FragmentHome.java new file mode 100644 index 0000000..4f1bbeb --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FragmentHome.java @@ -0,0 +1,151 @@ +package com.example.wgjrouter; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +public class FragmentHome extends Fragment implements View.OnClickListener { + + private LinearLayout fg_home_ll_hollrouter; + private LinearLayout fg_home_ll_superrouter; + private LinearLayout fg_home_ll_help; + private LinearLayout fg_home_ll_appsetting; + private LinearLayout fg_home_ll_funny; + private LinearLayout fg_home_ll_backup; + private LinearLayout fg_home_ll_appabout; + + private TextView fg_home_tv_phone; + private TextView fg_home_tv_ip; + + private Socket socket; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 2: + Toast.makeText(getActivity(),"抱歉,微路由通信超时",Toast.LENGTH_SHORT).show(); + break; + default: + break; + } + } + }; + + @Override + public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.layout_fg_home,container,false); + + fg_home_ll_hollrouter = view.findViewById(R.id.fg_home_ll_hollrouter); + fg_home_ll_superrouter = view.findViewById(R.id.fg_home_ll_superrouter); + fg_home_ll_help = view.findViewById(R.id.fg_home_ll_help); + fg_home_ll_appsetting = view.findViewById(R.id.fg_home_ll_appsetting); + fg_home_ll_funny = view.findViewById(R.id.fg_home_ll_funny); + fg_home_ll_backup = view.findViewById(R.id.fg_home_ll_backup); + fg_home_ll_appabout = view.findViewById(R.id.fg_home_ll_appabout); + + fg_home_tv_phone = view.findViewById(R.id.fg_home_tv_phone); + fg_home_tv_ip = view.findViewById(R.id.fg_home_tv_ip); + + fg_home_ll_hollrouter.setOnClickListener(this); + fg_home_ll_superrouter.setOnClickListener(this); + fg_home_ll_help.setOnClickListener(this); + fg_home_ll_appsetting.setOnClickListener(this); + fg_home_ll_funny.setOnClickListener(this); + fg_home_ll_backup.setOnClickListener(this); + fg_home_ll_appabout.setOnClickListener(this); + + initShow(); + getUserPhoneIP(); + return view; + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.fg_home_ll_hollrouter: + //首先监测与微路由网关能否通信 + new Thread(new Runnable() { + @Override + public void run() { + try { + socket = new Socket(); + InetSocketAddress inetSocketAddress = new InetSocketAddress("192.168.80.1",7888); + socket.connect(inetSocketAddress,2000); + + Intent goHollRouter = new Intent(getActivity(), SettingHollRouterActivity.class); + startActivity(goHollRouter); + } catch (IOException e) { + Message msg = new Message(); + msg.what = 2; + handler.sendMessage(msg); + } finally { + try { + if(socket != null) + socket.close(); + } catch (IOException e) { + Message msg = new Message(); + msg.what = 2; + handler.sendMessage(msg); + } + } + } + }).start(); + break; + case R.id.fg_home_ll_superrouter: + Intent goSuperRouter = new Intent(getActivity(), SettingSuperRouterActivity.class); + startActivity(goSuperRouter); + break; + case R.id.fg_home_ll_funny: + Intent golive = new Intent(getActivity(),FunnyLiveActivity.class); + startActivity(golive); + break; + case R.id.fg_home_ll_backup: + Intent gobackup = new Intent(getActivity(), BackupListViewActivity.class); + startActivity(gobackup); + break; + case R.id.fg_home_ll_help: + Intent goHelp = new Intent(getActivity(), WebShow.class); + goHelp.putExtra("web_title","帮助"); + goHelp.putExtra("web_url","https://docs.qq.com/doc/DUExxellidWpqaERE"); + startActivity(goHelp); + break; + case R.id.fg_home_ll_appsetting: + Intent goSelfStyle = new Intent(getActivity(),SettingAppActivity.class); + startActivity(goSelfStyle); + break; + case R.id.fg_home_ll_appabout: + Intent goAbout = new Intent(getActivity(),AboutApp.class); + startActivity(goAbout); + break; + } + } + + /** + * 设置手机型号、IP + */ + private void initShow(){ + fg_home_tv_phone.setText(Build.MODEL); + } + + /** + * 获取当前设备名称、IP + */ + private void getUserPhoneIP(){ + + } +} diff --git a/app/src/main/java/com/example/wgjrouter/FragmentTransDownload.java b/app/src/main/java/com/example/wgjrouter/FragmentTransDownload.java new file mode 100644 index 0000000..4880853 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FragmentTransDownload.java @@ -0,0 +1,380 @@ +package com.example.wgjrouter; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Environment; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.example.adapter.MyRecTransAdapter; +import com.example.bean.TaskInfo; +import com.example.database.FileTrans; +import com.example.event.MessageEvent; +import com.example.samba.MultiDownloadService; +import com.example.samba.MultiRemoteDownloadService; +import com.example.samba.thread.TaskDAO; +import com.example.samba.thread.TaskDAOImpl; +import com.example.utils.MyFileUtils; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +public class FragmentTransDownload extends Fragment { + private RecyclerView layout_trans_download_rv; + List taskInfoList = null; + MyRecTransAdapter myRecTransAdapter = null; + + private String eventFileName = null; + private String eventFileUrl = null; + //本地路径--需要 + private String localDirPath = null; + private TaskDAO taskDAO = new TaskDAOImpl();//用于添加任务到数据库中(主要是用于退出应用重新回到界面时加载任务列表) + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + //注册接收下载任务广播 + EventBus.getDefault().register(this); + //注册下载进度更新广播接收器 + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(MultiDownloadService.ACTION_UPDATE); + intentFilter.addAction(MultiDownloadService.ACTION_FINISHED); + intentFilter.addAction(MultiRemoteDownloadService.ACTION_UPDATE); + intentFilter.addAction(MultiRemoteDownloadService.ACTION_FINISHED); + getActivity().registerReceiver(mReceive,intentFilter); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.layout_fg_trans_download,null); + + initView(view); + + //从任务数据库中读取未完成的任务(完成的任务会从TaskInfo数据库中删除) + getUnfinishedDownloadTaskFromDB(); + return view; + } + + private void initView(View view){ + layout_trans_download_rv = view.findViewById(R.id.layout_trans_download_rv); + + LinearLayoutManager llm = new LinearLayoutManager(getActivity()); + llm.setOrientation(LinearLayoutManager.VERTICAL); + layout_trans_download_rv.setLayoutManager(llm); + + taskInfoList = new ArrayList<>(); + myRecTransAdapter = new MyRecTransAdapter(getActivity(), taskInfoList); + layout_trans_download_rv.setAdapter(myRecTransAdapter); + + myRecTransAdapter.setOnItemListener(new MyRecTransAdapter.OnItemListener() { + @Override + public void onItemClick(View view, int position) { + Intent start = new Intent(getActivity(), MultiDownloadService.class); + start.setAction(MultiDownloadService.ACTION_START); + start.putExtra("fileInfo", taskInfoList.get(position)); + getActivity().startService(start); + } + + @Override + public void onItemLongClick(View view, int position) { + + } + }); + } + + private void getUnfinishedDownloadTaskFromDB(){ + List taskInfos = taskDAO.getDownloadTaskInfos(); + + Log.d("zouguo","任务数量:" + taskInfos.size()); + + //任务都已完成,但界面可能未刷新 + taskInfoList.clear(); + myRecTransAdapter.notifyDataSetChanged(); + + for(int i = 0;i < taskInfos.size();i++){ + //更新位置索引 + taskInfos.get(i).setIndexs(i); + + //未完成的下载任务重新加入任务列表 + taskInfoList.add(i,taskInfos.get(i)); + myRecTransAdapter.notifyItemInserted(i); + + //判断是远程下载还是本地下载 + switch (taskInfos.get(i).getUpOrDownOrRemote()){ + case 1: + Intent startLocal = new Intent(getActivity(), MultiDownloadService.class); + startLocal.setAction(MultiDownloadService.ACTION_START); + startLocal.putExtra("fileInfo", taskInfos.get(i)); + getActivity().startService(startLocal); + break; + case 2: + Intent startRemote = new Intent(getActivity(), MultiRemoteDownloadService.class); + startRemote.setAction(MultiRemoteDownloadService.ACTION_START); + startRemote.putExtra("fileInfo", taskInfos.get(i)); + getActivity().startService(startRemote); + break; + } + } + } + + BroadcastReceiver mReceive = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getAction().equals(MultiDownloadService.ACTION_UPDATE)){ + //条目更新进度条 + int id = intent.getIntExtra("index",0); + int progress = intent.getIntExtra("downloadProgress",0); + String speed = intent.getStringExtra("downloadSpeed"); + long finished = intent.getLongExtra("downloadFinished",0); + long fileLength = intent.getLongExtra("downloadFileLength",0); + long consumeTime = intent.getLongExtra("downloadUseTime",0); + + List payloadList = new ArrayList(); + payloadList.add("downloadProgress"); + payloadList.add(progress); + payloadList.add(speed); + payloadList.add(finished); + payloadList.add(fileLength); + payloadList.add(consumeTime); + myRecTransAdapter.notifyItemChanged(id,payloadList); + }else if(intent.getAction().equals(MultiDownloadService.ACTION_FINISHED)){ + //条目下载完成 + TaskInfo taskInfo = (TaskInfo) intent.getSerializableExtra("downloadFinishFileinfo"); + + List payloadList = new ArrayList(); + payloadList.add("downloadOK"); + payloadList.add(100); + payloadList.add(""); + payloadList.add(taskInfo.getTranFinished()); + payloadList.add(taskInfo.getFileLength()); + myRecTransAdapter.notifyItemChanged(taskInfo.getIndexs(),payloadList); + + //移除完成的条目 +// removeItem(taskInfo); + + //删除任务信息 + taskDAO.deleteTask(taskInfo.getFileUrl()); + //添加下载完成记录 + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm"); + FileTrans fileTran = new FileTrans(0, MyFileUtils.getInstance().checkFileType(taskInfo.getFileUrl()),taskInfo.getFileName(),taskInfo.getFileLength(),taskInfo.getTranTime(),taskInfo.getDirPath() + "/" + taskInfo.getFileName(),taskInfo.getDirPath(),taskInfo.getUpOrDownOrRemote(),sdf.format(calendar.getTime())); + taskDAO.insertOverTask(fileTran); + }else if(intent.getAction().equals(MultiRemoteDownloadService.ACTION_UPDATE)){ + int id = intent.getIntExtra("index",0); + int progress = intent.getIntExtra("downloadProgress",0); + String speed = intent.getStringExtra("downloadSpeed"); + long finished = intent.getLongExtra("downloadFinished",0); + long fileLength = intent.getLongExtra("downloadFileLength",0); + long consumeTime = intent.getLongExtra("downloadUseTime",0); + + List payloadList = new ArrayList(); + payloadList.add("downloadProgress"); + payloadList.add(progress); + payloadList.add(speed); + payloadList.add(finished); + payloadList.add(fileLength); + payloadList.add(consumeTime); + myRecTransAdapter.notifyItemChanged(id,payloadList); + }else if(intent.getAction().equals(MultiRemoteDownloadService.ACTION_FINISHED)){ + //条目下载完成 + TaskInfo taskInfo = (TaskInfo) intent.getSerializableExtra("downloadRemoteFinishFileinfo"); + + List payloadList = new ArrayList(); + payloadList.add("downloadOK"); + payloadList.add(100); + payloadList.add(""); + payloadList.add(taskInfo.getTranFinished()); + payloadList.add(taskInfo.getFileLength()); + myRecTransAdapter.notifyItemChanged(taskInfo.getIndexs(),payloadList); + + + //移除完成的条目 +// removeItem(taskInfo); + + //删除任务信息 + taskDAO.deleteTask(taskInfo.getFileUrl()); + //添加下载完成记录 + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm"); + FileTrans fileTran = new FileTrans(0, MyFileUtils.getInstance().checkFileType(taskInfo.getFileUrl()),taskInfo.getFileName(),taskInfo.getFileLength(),taskInfo.getTranTime(),taskInfo.getDirPath() + "/" + taskInfo.getFileName(),taskInfo.getDirPath(),taskInfo.getUpOrDownOrRemote(),sdf.format(calendar.getTime())); + taskDAO.insertOverTask(fileTran); + } + } + }; + + /** + * 删除某一条目 + * @param taskInfo + */ + private synchronized void removeItem(TaskInfo taskInfo){ + try { + taskInfoList.remove(taskInfo.getIndexs()); + myRecTransAdapter.notifyItemRemoved(taskInfo.getIndexs()); + } catch (Exception e) { + Log.d("zouguo","异常:" + taskInfoList.size()); + e.printStackTrace(); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MessageEvent event) { + eventFileName = event.getFileName(); + eventFileUrl = event.getEventFileUrl(); + + switch (event.getEventType()){ + case 1: + //SMB下载 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File checkDirExists = new File(file.getPath() + "/com.example.wgjrouter/"); + + if(!checkDirExists.exists()){ + //不存在该文件夹,新建 + if(!checkDirExists.mkdirs()){ + Toast.makeText(getActivity(),"抱歉,创建下载目录失败",Toast.LENGTH_SHORT).show(); + return; + } + } + + localDirPath = checkDirExists.getPath(); + + //判断下载队列中是否已存在该任务 + if(!myRecTransAdapter.isTaskExists(eventFileUrl)){ + int index = taskInfoList.size(); + TaskInfo taskInfo = new TaskInfo(0,index,eventFileName,eventFileUrl,localDirPath,"0.0B/s",0,"等待下载",0,0,"/",0,1,false); + taskInfoList.add(index,taskInfo); + myRecTransAdapter.notifyItemInserted(index); + + //添加任务到数据库(暂定如此) + taskDAO.insertTask(taskInfo); + + Intent start = new Intent(getActivity(), MultiDownloadService.class); + start.setAction(MultiDownloadService.ACTION_START); + start.putExtra("fileInfo", taskInfo); + getActivity().startService(start); + } + } + break; + case 21: + //重新开始下载任务,偷懒方法 + getUnfinishedDownloadTaskFromDB(); + break; + case 22: + //暂停本地下载 + Intent stopLocal = new Intent(getActivity(), MultiDownloadService.class); + stopLocal.setAction(MultiDownloadService.ACTION_STOP_ALL); + getActivity().startService(stopLocal); + //暂停远程下载 + Intent startRemote = new Intent(getActivity(), MultiRemoteDownloadService.class); + startRemote.setAction(MultiRemoteDownloadService.ACTION_STOP_ALL); + getActivity().startService(startRemote); + break; + case 6: + //远程下载 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File checkExists = new File(file.getPath() + "/com.example.wgjrouter/"); + + if(!checkExists.exists()){ + //不存在该文件夹,新建 + if(!checkExists.mkdirs()){ + Toast.makeText(getActivity(),"抱歉,创建下载目录失败",Toast.LENGTH_SHORT).show(); + return; + } + } + + localDirPath = checkExists.getPath(); + + //判断下载队列中是否已存在该任务 + if(!myRecTransAdapter.isTaskExists(eventFileUrl)){ + int index = taskInfoList.size(); + TaskInfo taskInfo = new TaskInfo(0,index,eventFileName,eventFileUrl,localDirPath,"0.0B/s",0,"等待下载",0,0,"/",0,2,false); + taskInfoList.add(index,taskInfo); + myRecTransAdapter.notifyItemInserted(index); + + //添加任务到数据库(暂定如此) + taskDAO.insertTask(taskInfo); + + Intent start = new Intent(getActivity(), MultiRemoteDownloadService.class); + start.setAction(MultiRemoteDownloadService.ACTION_START); + start.putExtra("fileInfo", taskInfo); + getActivity().startService(start); + } + } + break; + } + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + Log.d("zouguo","onActivityCreated"); + } + + @Override + public void onStart() { + super.onStart(); + Log.d("zouguo","onStart"); + } + + @Override + public void onResume() { + super.onResume(); + Log.d("zouguo","onResume"); + + //列表全部完成时清空 + List tasks = taskDAO.getDownloadTaskInfos(); + if(tasks.size() == 0){ + //数据库中已无下载任务,由于界面在后台时无法刷新,启动时从此处刷新界面 + taskInfoList.clear();//只为了确保为空 + myRecTransAdapter.notifyDataSetChanged(); + } + } + + @Override + public void onStop() { + super.onStop(); + Log.d("zouguo","onStop"); + } + + @Override + public void onPause() { + super.onPause(); + Log.d("zouguo","onPause"); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + Log.d("zouguo","onDestroyView"); + } + + @Override + public void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + getActivity().unregisterReceiver(mReceive); + + Log.d("zouguo","onDestroy"); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/FragmentTransUpload.java b/app/src/main/java/com/example/wgjrouter/FragmentTransUpload.java new file mode 100644 index 0000000..48c3fb2 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FragmentTransUpload.java @@ -0,0 +1,236 @@ +package com.example.wgjrouter; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.preference.PreferenceManager; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.NotificationCompat; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.example.adapter.MyRecTransAdapter; +import com.example.bean.TaskInfo; +import com.example.database.FileTrans; +import com.example.event.MessageEvent; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; + +import jcifs.smb.SmbException; +import jcifs.smb.SmbFileOutputStream; + +public class FragmentTransUpload extends Fragment { + + private RecyclerView fg_transfer_upload_rv; + private List taskInfoList; + private MyRecTransAdapter myRecTransAdapter; + + private BufferedInputStream bufferedInputStream = null; + private SmbFileOutputStream smbFileOutputStream = null; + + private String eventFileName = null; + private int eventFileType = 0; + //本地路径 + private String eventDirPath = null; + private String eventFileUrl = null; + + //路由路径--需要 + private String filePath = null; + private String dirPath = null; + private long useTime = 0; + + private boolean isUploadNow = false; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + //注册接收上传任务广播 + EventBus.getDefault().register(this); + //注册上传进度更新广播接收器 + + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.layout_fg_trans_upload,null); + + initView(view); + + //从任务数据库中读取未完成的任务(完成的任务会从TaskInfo数据库中删除) + getUnfinishedUploadTaskFromDB(); + return view; + } + + private void initView(View view){ + fg_transfer_upload_rv = view.findViewById(R.id.fg_transfer_upload_rv); + + LinearLayoutManager llm = new LinearLayoutManager(getActivity()); + llm.setOrientation(LinearLayoutManager.VERTICAL); + fg_transfer_upload_rv.setLayoutManager(llm); + + taskInfoList = new ArrayList<>(); + myRecTransAdapter = new MyRecTransAdapter(getActivity(), taskInfoList); + fg_transfer_upload_rv.setAdapter(myRecTransAdapter); + } + + private void getUnfinishedUploadTaskFromDB(){ + //检查手机备份开关 + SharedPreferences spf = getActivity().getSharedPreferences("app_setting",0); + //相片、视频备份开关 + boolean upImageState = spf.getBoolean("up_image",false); + //文件备份开关 + boolean upFilesState = spf.getBoolean("up_file",false); + //音频备份开关 + boolean upAudioState = spf.getBoolean("up_audio",false); + //微信文件备份开关 + boolean upWechatState = spf.getBoolean("up_wechat",false); + //应用备份开关 + boolean upAppState = spf.getBoolean("up_app",false); + //短信备份开关 + boolean upMsgState = spf.getBoolean("up_msg",false); + //通话记录备份开关 + boolean upPhoneState = spf.getBoolean("up_phone",false); + //通讯录备份开关 + boolean upContactState = spf.getBoolean("up_contact",false); + //获取数据库中未完成的上传任务 + + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MessageEvent event) { + eventFileName = event.getFileName(); + eventFileType = event.getFileType(); + eventDirPath = event.getEventDirPath(); + eventFileUrl = event.getEventFileUrl(); + + dirPath = eventDirPath; + filePath = eventFileUrl; + + switch (event.getEventType()){ + case 2: + if(eventFileUrl != null){ + //上传 + if(isUploadNow) + return; + isUploadNow = true; + + //获取文件File + File upfile = new File(eventFileUrl); + Log.d("zouguo","UP:" + upfile.getPath()); + + + + + }else{ + Toast.makeText(getActivity(),"抱歉,获取文件路径时发生异常",Toast.LENGTH_SHORT).show(); + } + break; + } + }; + + private List> putFile(String smbDirUrl, File upfile){ + List> list = new ArrayList<>(); + String putLog = ""; + + long beginTime = System.currentTimeMillis(); + + try { + bufferedInputStream = new BufferedInputStream(new FileInputStream(upfile)); + smbFileOutputStream = new SmbFileOutputStream(smbDirUrl + "/" + upfile.getName(),false); + + byte[] bt = new byte[8192]; + int n = 0; + double total = 0; + double fiSize = 0; + + fiSize = upfile.length(); + + while((n = bufferedInputStream.read(bt)) > 0){ + smbFileOutputStream.write(bt,0,n); + smbFileOutputStream.flush(); + + total += n; + } + + long endTime = System.currentTimeMillis() - beginTime; + + useTime = endTime; + putLog = "上传成功:" + upfile.getName() + ",耗时:" + String.valueOf(Math.max(1,endTime / 1000)) + "秒"; + } catch (FileNotFoundException e) { + e.printStackTrace(); + putLog = "上传失败:" + e.getMessage(); + } catch (SmbException e) { + e.printStackTrace(); + putLog = "上传失败:" + e.getMessage(); + } catch (MalformedURLException e) { + e.printStackTrace(); + putLog = "上传失败:" + e.getMessage(); + } catch (UnknownHostException e) { + e.printStackTrace(); + putLog = "上传失败:" + e.getMessage(); + } catch (IOException e) { + e.printStackTrace(); + putLog = "上传失败:" + e.getMessage(); + } finally { + try { + if(null != smbFileOutputStream) + smbFileOutputStream.close(); + if(null != bufferedInputStream) + bufferedInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + putLog = "上传失败:" + e.getMessage(); + } + } + + HashMap hashMap = new HashMap(); + hashMap.put("putok",true); + hashMap.put("putlog",putLog); + list.add(hashMap); + return list; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + EventBus.getDefault().unregister(this); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/FragmentTransfer.java b/app/src/main/java/com/example/wgjrouter/FragmentTransfer.java new file mode 100644 index 0000000..cc5a165 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FragmentTransfer.java @@ -0,0 +1,115 @@ +package com.example.wgjrouter; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.Toast; + +import com.ddz.floatingactionbutton.FloatingActionButton; +import com.ddz.floatingactionbutton.FloatingActionMenu; +import com.example.adapter.MyFgTransLvAdapter; +import com.example.event.MessageEvent; +import com.example.samba.MultiDownloadService; +import com.example.samba.MultiRemoteDownloadService; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; + + +public class FragmentTransfer extends Fragment { + + private ImageView fg_transfer_iv; + private TabLayout fg_transfer_tl; + private ViewPager fg_transfer_vp; + private FloatingActionMenu fl_menu; + private FloatingActionButton fl_menu_button_start; + private FloatingActionButton fl_menu_button_stop; + + private List fragmentList; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.layout_fg_transfer,container,false); + + fg_transfer_iv = view.findViewById(R.id.fg_transfer_iv); + fg_transfer_vp = view.findViewById(R.id.fg_transfer_vp); + fl_menu = view.findViewById(R.id.fl_menu); + fl_menu_button_start = view.findViewById(R.id.fl_menu_button_start); + fl_menu_button_stop = view.findViewById(R.id.fl_menu_button_stop); + + fg_transfer_iv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent gofile = new Intent(getActivity(),FileTransFinish.class); + startActivity(gofile); + } + }); + + fl_menu_button_start.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + fl_menu.collapse(); + + //判断当前是下载页、上传页 + switch (fg_transfer_vp.getCurrentItem()) { + case 0: + //下载界面 + EventBus.getDefault().postSticky(new MessageEvent(21,0,"",1,"","")); + break; + case 1: + //上传界面 + EventBus.getDefault().postSticky(new MessageEvent(31,0,"",0,"","")); + break; + } + } + }); + + fl_menu_button_stop.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + fl_menu.collapse(); + + //判断当前是下载页、上传页 + switch (fg_transfer_vp.getCurrentItem()){ + case 0: + //下载界面 + EventBus.getDefault().postSticky(new MessageEvent(22,0,"",1,"","")); + break; + case 1: + //上传界面 + EventBus.getDefault().postSticky(new MessageEvent(32,0,"",0,"","")); + break; + } + } + }); + + + fragmentList = new ArrayList<>(); + fragmentList.add(new FragmentTransDownload()); + fragmentList.add(new FragmentTransUpload()); + MyFgTransLvAdapter myFgTransLvAdapter = new MyFgTransLvAdapter(getActivity().getSupportFragmentManager(),fragmentList); + + fg_transfer_vp.setAdapter(myFgTransLvAdapter); + + fg_transfer_tl = view.findViewById(R.id.fg_transfer_tl); + fg_transfer_tl.setupWithViewPager(fg_transfer_vp); + return view; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/FunnyLiveActivity.java b/app/src/main/java/com/example/wgjrouter/FunnyLiveActivity.java new file mode 100644 index 0000000..fe6763e --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FunnyLiveActivity.java @@ -0,0 +1,432 @@ +package com.example.wgjrouter; + +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.PaintDrawable; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.ProgressBar; +import android.widget.SimpleAdapter; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.database.LiveVideoList; +import com.example.utils.MyPhoneUtils; + +import org.litepal.LitePal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FunnyLiveActivity extends AppCompatActivity{ + private Toolbar funny_tb; + private ListView funny_live_lv; + private LinearLayout funny_live_search; + private EditText funny_live_search_et; + private Button funny_live_search_btn; + private ProgressBar funny_live_loading; + + ArrayAdapter aa = null; + private List nameList = new ArrayList<>(); + private List urlsList = new ArrayList<>(); + + //记录播放视频的位置 + private int playItemPosition = 0; + private int PLAY_CODE = 380; + + private boolean isSearch = false; + + private Handler handler = new Handler() { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + runOnUiThread(new Runnable() { + @Override + public void run() { + funny_live_loading.setVisibility(View.GONE); + funny_live_lv.setVisibility(View.VISIBLE); + } + }); + + switch (msg.what) { + case 0: + Toast.makeText(FunnyLiveActivity.this, "抱歉,直播源初始化失败", Toast.LENGTH_SHORT).show(); + break; + case 288: + Toast.makeText(FunnyLiveActivity.this, "直播源初始化成功", Toast.LENGTH_SHORT).show(); + showVideoList(nameList); + break; + case 289: + showVideoList(nameList); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_funny_live); + + initView(); + + /** + * 初始播放列表 + * + * 有限数据库读取直播源 + * 数据库中无直播源代表首次运行,此时初始直播源 + */ + if (LitePal.findAll(LiveVideoList.class).size() == 0) { + Toast.makeText(FunnyLiveActivity.this, "正在初始化直播源列表...", Toast.LENGTH_SHORT).show(); + + nameList.clear(); + urlsList.clear(); + new Thread(new Runnable() { + @Override + public void run() { + readVideoListFromTxt(); + } + }).start(); + } else { + //从数据库读取数据 + nameList.clear(); + urlsList.clear(); + new Thread(new Runnable() { + @Override + public void run() { + readVideoListFromDB(); + } + }).start(); + } + } + + private void initView() { + funny_live_loading = findViewById(R.id.funny_live_loading); + funny_tb = findViewById(R.id.funny_tb); + funny_live_lv = findViewById(R.id.funny_live_lv); + funny_live_search = findViewById(R.id.funny_live_search); + funny_live_search_et = findViewById(R.id.funny_live_search_et); + funny_live_search_btn = findViewById(R.id.funny_live_search_btn); + + aa = new ArrayAdapter<>(FunnyLiveActivity.this, R.layout.item_lv_listvideo_black, nameList); + funny_live_lv.setAdapter(aa); + aa.notifyDataSetChanged(); + + funny_live_search_btn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + funny_live_search.setVisibility(View.GONE); + MyPhoneUtils.getInstance(FunnyLiveActivity.this).hideInputMethod(funny_live_search_et); + + if(!funny_live_search_et.getText().toString().equals("")){ + funny_tb.setNavigationIcon(R.mipmap.rollback); + funny_tb.setTitle("搜索结果"); + isSearch = true; + + nameList.clear(); + urlsList.clear(); + new Thread(new Runnable() { + @Override + public void run() { + searchLiveVideo("%" + funny_live_search_et.getText().toString() + "%"); + } + }).start(); + } + } + }); + + funny_live_search_et.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if(actionId == KeyEvent.KEYCODE_SEARCH){ + funny_live_search.setVisibility(View.GONE); + MyPhoneUtils.getInstance(FunnyLiveActivity.this).hideInputMethod(funny_live_search_et); + + if(!funny_live_search_et.getText().toString().equals("")){ + funny_tb.setNavigationIcon(R.mipmap.rollback); + funny_tb.setTitle("搜索结果"); + isSearch = true; + + nameList.clear(); + urlsList.clear(); + new Thread(new Runnable() { + @Override + public void run() { + searchLiveVideo("%" + funny_live_search_et.getText().toString() + "%"); + } + }).start(); + } + } + return true; + } + }); + + funny_tb.setNavigationIcon(R.mipmap.back); + funny_tb.setTitle("直播源列表"); + funny_tb.inflateMenu(R.menu.videolive_play_option_menu); + + funny_tb.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case R.id.live_menu_query: + if(funny_live_search.getVisibility() == View.GONE){ + funny_live_search.setVisibility(View.VISIBLE); + }else{ + funny_live_search.setVisibility(View.GONE); + } + break; + case R.id.live_menu_collect: + Intent gocollect = new Intent(FunnyLiveActivity.this,FunnyLiveCollectActivity.class); + startActivity(gocollect); + break; + case R.id.live_menu_reback: + AlertDialog ad = null; + AlertDialog.Builder adb = new AlertDialog.Builder(FunnyLiveActivity.this); + + adb.setTitle("是否初始直播源列表") + .setMessage("删除、新增的直播源都将被丢弃,仅恢复内置的直播源") + .setNegativeButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + funny_live_loading.setVisibility(View.VISIBLE); + funny_live_lv.setVisibility(View.INVISIBLE); + + //清空数据库中的直播源数据 + LitePal.deleteAll(LiveVideoList.class); + + Toast.makeText(FunnyLiveActivity.this, "正在初始化直播源列表...", Toast.LENGTH_SHORT).show(); + + nameList.clear(); + urlsList.clear(); + new Thread(new Runnable() { + @Override + public void run() { + readVideoListFromTxt(); + } + }).start(); + } + }); + ad = adb.create(); + ad.show(); + + ad.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + ad.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.RED); + break; + case R.id.live_menu_recorder: + Intent gorecorder = new Intent(FunnyLiveActivity.this, FunnyLiveRecorderActivity.class); + startActivity(gorecorder); + break; + } + return false; + } + }); + + funny_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(isSearch){ + funny_tb.setNavigationIcon(R.mipmap.back); + funny_tb.setTitle("直播源列表"); + isSearch = false; + + //回到直播源列表 + nameList.clear(); + urlsList.clear(); + readVideoListFromDB(); + }else{ + finish(); + } + } + }); + + funny_live_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + playItemPosition = position; + + //加入播放记录 + LiveVideoList lvl = LitePal.where("liveName = ? and liveUrls = ?", nameList.get(position), urlsList.get(position)).findFirst(LiveVideoList.class); + lvl.setIsPlay(1); + lvl.save(); + + //解析出直播源名称、链接 + Intent golive = new Intent(FunnyLiveActivity.this, VideoPlayVTM.class); + golive.putExtra("videoType", 1); + golive.putExtra("videoUrl", urlsList.get(position)); + golive.putExtra("videoTitle", nameList.get(position)); + golive.putExtra("videoPosition", playItemPosition); + startActivityForResult(golive,PLAY_CODE); + } + }); + + funny_live_lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, final int parentPosition, long id) { + View viewPoP = View.inflate(FunnyLiveActivity.this,R.layout.dialog_file_longclick_menu,null); + + ListView listView = viewPoP.findViewById(R.id.dialog_file_longclick_menu_lv); + + String[] menuData = {"删除","收藏","取消"}; + ArrayAdapter arrayAdapter = new ArrayAdapter(FunnyLiveActivity.this,android.R.layout.simple_list_item_1,menuData); + listView.setAdapter(arrayAdapter); + + final PopupWindow popupWindow = new PopupWindow(viewPoP, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + popupWindow.dismiss(); + + switch (position){ + case 0: + LiveVideoList lvld = LitePal.where("liveName = ? and liveUrls = ?",nameList.get(parentPosition),urlsList.get(parentPosition)).findFirst(LiveVideoList.class); + lvld.delete(); + + nameList.clear(); + urlsList.clear(); + readVideoListFromDB(); + break; + case 1: + LiveVideoList lvlc = LitePal.where("liveName = ? and liveUrls = ?",nameList.get(parentPosition),urlsList.get(parentPosition)).findFirst(LiveVideoList.class); + lvlc.setIsCollect(1); + lvlc.save(); + + Toast.makeText(FunnyLiveActivity.this,"收藏成功",Toast.LENGTH_SHORT).show(); + nameList.clear(); + urlsList.clear(); + readVideoListFromDB(); + break; + } + } + }); + + ColorDrawable cd = new ColorDrawable(0xb0000000); + popupWindow.setBackgroundDrawable(cd); + popupWindow.setOutsideTouchable(true); + popupWindow.setFocusable(true); + popupWindow.showAtLocation(funny_live_lv, Gravity.CENTER,0,0); + return true; + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode == PLAY_CODE && resultCode == RESULT_OK){ + playItemPosition = data.getIntExtra("videoPosition",0); + + //设置ListView到指定位置 + funny_live_lv.setSelection(playItemPosition); + } + } + + private void readVideoListFromTxt() { + try { + InputStreamReader isr = new InputStreamReader(getResources().getAssets().open("livevideolist.txt")); + BufferedReader br = new BufferedReader(isr); + + String line = ""; + + while ((line = br.readLine()) != null) { + String[] items = line.split(","); + + if (items.length == 2) { + nameList.add(items[0]); + urlsList.add(items[1]); + + //存入数据库 + LiveVideoList lvl = new LiveVideoList(); + lvl.setLiveName(items[0]); + lvl.setLiveUrls(items[1]); + lvl.save(); + } + } + + Message msg = new Message(); + msg.what = 288; + handler.sendMessage(msg); + } catch (IOException e) { + e.printStackTrace(); + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + } + + private void readVideoListFromDB() { + List allVideoList = LitePal.findAll(LiveVideoList.class); + + for (LiveVideoList lvl : allVideoList) { + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + + Message msg = new Message(); + msg.what = 289; + handler.sendMessage(msg); + } + + private void showVideoList(List nameList) { + runOnUiThread(new Runnable() { + @Override + public void run() { + aa.notifyDataSetChanged(); + } + }); + } + + private void searchLiveVideo(String liveName){ + List list = LitePal.where("livename like ?",liveName).find(LiveVideoList.class); + + for(LiveVideoList lvl : list){ + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + + Message msg = new Message(); + msg.what = 289; + handler.sendMessage(msg); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return super.onCreateOptionsMenu(menu); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/wgjrouter/FunnyLiveCollectActivity.java b/app/src/main/java/com/example/wgjrouter/FunnyLiveCollectActivity.java new file mode 100644 index 0000000..e0ef715 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FunnyLiveCollectActivity.java @@ -0,0 +1,123 @@ +package com.example.wgjrouter; + +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.Toast; + +import com.example.database.LiveVideoList; + +import org.litepal.LitePal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class FunnyLiveCollectActivity extends AppCompatActivity{ + private Toolbar funny_collect_tb; + private ListView funny_live_collect_lv; + + ArrayAdapter aa = null; + private List nameList = new ArrayList<>(); + private List urlsList = new ArrayList<>(); + + //记录播放视频的位置 + private int playItemPosition = 0; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + Toast.makeText(FunnyLiveCollectActivity.this,"抱歉,收藏夹读取失败",Toast.LENGTH_SHORT).show(); + break; + case 289: + showVideoList(nameList); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_funny_collect); + + initView(); + + readVideoCollectListFromDB(); + } + + private void initView(){ + funny_collect_tb = findViewById(R.id.funny_collect_tb); + funny_live_collect_lv = findViewById(R.id.funny_live_collect_lv); + + aa = new ArrayAdapter<>(FunnyLiveCollectActivity.this,R.layout.item_lv_listvideo_black,nameList); + funny_live_collect_lv.setAdapter(aa); + + funny_collect_tb.setNavigationIcon(R.mipmap.back); + funny_collect_tb.setTitle("收藏夹"); + funny_collect_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + funny_live_collect_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + playItemPosition = position; + //解析出直播源名称、链接 + Intent golive = new Intent(FunnyLiveCollectActivity.this, VideoPlayVTM.class); + golive.putExtra("videoType",3); + golive.putExtra("videoUrl",urlsList.get(position)); + golive.putExtra("videoTitle",nameList.get(position)); + golive.putExtra("videoPosition",playItemPosition); + startActivity(golive); + } + }); + } + + private void readVideoCollectListFromDB(){ + nameList.clear(); + urlsList.clear(); + + List allVideoList = LitePal.where("iscollect = ?","1").find(LiveVideoList.class); + + for (LiveVideoList lvl : allVideoList){ + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + + Message msg = new Message(); + msg.what = 289; + handler.sendMessage(msg); + } + + private void showVideoList(List nameList){ + aa.notifyDataSetChanged(); + } + + @Override + protected void onResume() { + super.onResume(); + readVideoCollectListFromDB(); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/FunnyLiveRecorderActivity.java b/app/src/main/java/com/example/wgjrouter/FunnyLiveRecorderActivity.java new file mode 100644 index 0000000..ebc7d27 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/FunnyLiveRecorderActivity.java @@ -0,0 +1,115 @@ +package com.example.wgjrouter; + +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.Toast; + +import com.example.database.LiveVideoList; + +import org.litepal.LitePal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +public class FunnyLiveRecorderActivity extends AppCompatActivity{ + private Toolbar funny_recorder_tb; + private ListView funny_live_recorder_lv; + + ArrayAdapter aa = null; + private List nameList = new ArrayList<>(); + private List urlsList = new ArrayList<>(); + + //记录播放视频的位置 + private int playItemPosition = 0; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + Toast.makeText(FunnyLiveRecorderActivity.this,"抱歉,播放记录读取失败",Toast.LENGTH_SHORT).show(); + break; + case 289: + showVideoList(nameList); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_funny_recorder); + + initView(); + + nameList.clear(); + urlsList.clear(); + + readVideoRecorderListFromDB(); + } + + private void initView(){ + funny_recorder_tb = findViewById(R.id.funny_recorder_tb); + funny_live_recorder_lv = findViewById(R.id.funny_live_recorder_lv); + + funny_recorder_tb.setNavigationIcon(R.mipmap.back); + funny_recorder_tb.setTitle("播放记录"); + funny_recorder_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + funny_live_recorder_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + playItemPosition = position; + //解析出直播源名称、链接 + Intent golive = new Intent(FunnyLiveRecorderActivity.this, VideoPlayVTM.class); + golive.putExtra("videoType",2); + golive.putExtra("videoUrl",urlsList.get(position)); + golive.putExtra("videoTitle",nameList.get(position)); + golive.putExtra("videoPosition",playItemPosition); + startActivity(golive); + } + }); + } + + private void readVideoRecorderListFromDB(){ + List allVideoList = LitePal.where("isplay = ?","1").find(LiveVideoList.class); + + for (LiveVideoList lvl : allVideoList){ + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + + Message msg = new Message(); + msg.what = 289; + handler.sendMessage(msg); + } + + private void showVideoList(List nameList){ + aa = new ArrayAdapter<>(FunnyLiveRecorderActivity.this,R.layout.item_lv_listvideo_black,nameList); + funny_live_recorder_lv.setAdapter(aa); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/MainActivity.java b/app/src/main/java/com/example/wgjrouter/MainActivity.java new file mode 100644 index 0000000..98fd49d --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/MainActivity.java @@ -0,0 +1,226 @@ +package com.example.wgjrouter; + +import android.Manifest; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.widget.BottomNavigationView; +import android.support.v4.app.Fragment; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MenuItem; +import android.view.View; +import android.widget.Toast; + +import com.example.adapter.MyFgVpFpaAdapter; +import com.example.event.MessageEvent; +import com.example.samba.MultiDownloadTask; +import com.pgyersdk.update.PgyUpdateManager; +import com.squareup.picasso.Picasso; + +import org.greenrobot.eventbus.EventBus; +import org.litepal.LitePal; + +import java.util.ArrayList; +import java.util.List; + +public class MainActivity extends AppCompatActivity { + + private String[] requestPermissionList = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}; + private int REQUEST_PERMISSION_CODE = 9736; + + ViewPager mainViewPager; + BottomNavigationView mainBNV; + MenuItem menuItem; + + List fragmentList; + + private long exitTime; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + mainViewPager = findViewById(R.id.main_viewpager); + mainBNV = findViewById(R.id.main_bnv); + + fragmentList = new ArrayList<>(); + fragmentList.add(new FragmentFile()); + fragmentList.add(new FragmentTransfer()); + fragmentList.add(new FragmentHome()); + MyFgVpFpaAdapter myFgVpFpaAdapter = new MyFgVpFpaAdapter(getSupportFragmentManager(),fragmentList); + mainViewPager.setAdapter(myFgVpFpaAdapter); + + mainBNV.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { + switch (menuItem.getItemId()){ + case R.id.navigation_file: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_transfer: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_home: + mainViewPager.setCurrentItem(2); + break; + default: + break; + } + return true; + } + }); + + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int i, float v, int i1) { + + } + + @Override + public void onPageSelected(int position) { + if(menuItem != null){ + menuItem.setChecked(false); + }else{ + menuItem = mainBNV.getMenu().getItem(0); + menuItem.setChecked(true); + } + menuItem = mainBNV.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int i) { + + } + }); + + //申请读写存储权限 6.0之后 + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M){ + List deneyPermissionList = new ArrayList<>(); + for(int i = 0;i < requestPermissionList.length;i++){ + if(checkSelfPermission(requestPermissionList[i]) != PackageManager.PERMISSION_GRANTED){ + deneyPermissionList.add(requestPermissionList[i]); + } + } + if(!deneyPermissionList.isEmpty()){ + String[] deneyPermissionArray = deneyPermissionList.toArray(new String[deneyPermissionList.size()]); + requestPermissions(deneyPermissionArray,REQUEST_PERMISSION_CODE); + } + } + + //蒲公英更新 + new PgyUpdateManager.Builder().register(); + + //创建数据库 + LitePal.getDatabase(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull final String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + List deneyPermissionsList = new ArrayList<>(); + if(requestCode == REQUEST_PERMISSION_CODE){ + if(grantResults.length > 0){ + for(int i = 0;i < grantResults.length;i++){ + if(grantResults[i] != PackageManager.PERMISSION_GRANTED){ + //权限未放行 + deneyPermissionsList.add(permissions[i]); + } + } + + if(!deneyPermissionsList.isEmpty()){ + String[] deneyPermissions = deneyPermissionsList.toArray(new String[deneyPermissionsList.size()]); + //6.0版本之上的需要动态权限,低于6.0不会执行到此处!! + //判断是否点击了不再提示(是否可再重新申请) + boolean ii = shouldShowRequestPermissionRationale(deneyPermissions[0]); + + //未点击>不再询问,拒绝时返回 true,表名还可再请求权限 + Log.d("zouguo","ii1:" + String.valueOf(ii)); + if(ii){ + //还可再申请权限 + new AlertDialog.Builder(MainActivity.this) + .setTitle("允许\"微管家\"获取读写存储器权限吗?") + .setMessage("微管家在上传、下载文件时需要读写存储器权限") + .setPositiveButton("允许", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + requestPermissions(permissions,REQUEST_PERMISSION_CODE); + } + }) + .setNegativeButton("不允许", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Toast.makeText(MainActivity.this,"无此权限将无法使用上传、下载功能",Toast.LENGTH_SHORT).show(); + } + }) + .create().show(); + }else{ + Toast.makeText(MainActivity.this,"读写存储器权限不足",Toast.LENGTH_SHORT).show(); + } + } + } + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + && event.getAction() == KeyEvent.ACTION_DOWN + && event.getRepeatCount() == 0){ + + if(mainViewPager.getCurrentItem() == 0){ + //获取FragmentFile中的返回按钮 + FragmentFile ff = (FragmentFile) fragmentList.get(0); + Toolbar fg_file_toolbar = ff.getView().findViewById(R.id.fg_file_toolbar); + View fg_file_showpic_label = ff.getView().findViewById(R.id.fg_file_showpic_label); + + if(fg_file_toolbar.getTitle() == "Holl微路由" || fg_file_toolbar.getTitle() == "智能路由器"){ + if((System.currentTimeMillis() - exitTime) > 2000 ){ + Toast.makeText(this,"再按一次退出程序",Toast.LENGTH_SHORT).show(); + exitTime = System.currentTimeMillis(); + }else{ + //需替换完全退出 + finish(); + System.exit(0); + } + }else{ + if(fg_file_showpic_label.getTag().equals("show")){ + //当前图片查看器在显示状态,隐藏掉 + EventBus.getDefault().postSticky(new MessageEvent(7,0,"",1,"","")); + }else if(fg_file_toolbar.getTitle().toString().startsWith("项:")){ + EventBus.getDefault().postSticky(new MessageEvent(8,0,"",1,"","")); + }else{ + //返回上层 + EventBus.getDefault().postSticky(new MessageEvent(5,0,"",1,"","")); + } + } + }else{ + if((System.currentTimeMillis() - exitTime) > 2000 ){ + Toast.makeText(this,"再按一次退出程序",Toast.LENGTH_SHORT).show(); + exitTime = System.currentTimeMillis(); + }else{ + //需替换完全退出 + finish(); + System.exit(0); + } + } + } + return false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Picasso.get().cancelTag("getPhotoTag"); + + Log.d("zouguo","MainOnDestroy"); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/RemoteFileActivity.java b/app/src/main/java/com/example/wgjrouter/RemoteFileActivity.java new file mode 100644 index 0000000..9835af2 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/RemoteFileActivity.java @@ -0,0 +1,556 @@ +package com.example.wgjrouter; + +import android.Manifest; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.example.adapter.MyRecRemoteFileAdapter; +import com.example.bean.MyRecRemoteFileInfos; +import com.example.event.MessageEvent; +import com.example.samba.SambaUtils; +import com.example.utils.MyFileUtils; +import com.example.utils.MyPhoneUtils; +import com.github.chrisbanes.photoview.PhotoView; +import com.squareup.picasso.MemoryPolicy; +import com.squareup.picasso.Picasso; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class RemoteFileActivity extends AppCompatActivity { + private boolean canBack = false; + private int clickPicIndex = 0; + + private String fatherUrl = null; + private String webHost = null; + private String webRootUrl = null; + private List fileOrDirList = new ArrayList<>(); + private List titList = new ArrayList<>(); + private List urlList = new ArrayList<>(); + private List picItemUrlList = new ArrayList<>(); + private ArrayList videoTitleList = new ArrayList<>(); + private ArrayList videoItemUrlList = new ArrayList<>(); + private List fileTypeList = new ArrayList<>();//标记文件的类型,下载用 + List myRecRemoteFileInfosList = null; + MyRecRemoteFileAdapter myRecRemoteFileAdapter; + + private ProgressBar remote_file_pb; + private FrameLayout remote_file_parent;//弹窗的父布局 + private PopupWindow popupWindowPic;//查看图片的弹窗 + private Toolbar remote_file_tb; + private RecyclerView remote_file_rv; + private View remote_file_opendir_cl; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + runOnUiThread(new Runnable() { + @Override + public void run() { + remote_file_pb.setVisibility(View.GONE); + } + }); + + switch (msg.what){ + case 1567: + Toast.makeText(RemoteFileActivity.this,"失败" + msg.obj.toString(),Toast.LENGTH_SHORT).show(); + break; + case 1568: + analyResponse(webHost,msg.obj.toString()); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_remote_file); + + Intent intent = getIntent(); + webHost = intent.getStringExtra("web_host"); + webRootUrl = intent.getStringExtra("web_url"); + + initView(); + getRemoteSource(webRootUrl); + + EventBus.getDefault().register(RemoteFileActivity.this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(MessageEvent event) { + switch (event.getEventType()) { + case 4: + //下载成功 + break; + } + } + + private void initView(){ + remote_file_pb = findViewById(R.id.remote_file_pb); + remote_file_parent = findViewById(R.id.remote_file_parent); + remote_file_tb = findViewById(R.id.remote_file_tb); + remote_file_rv = findViewById(R.id.remote_file_rv); + remote_file_opendir_cl = findViewById(R.id.remote_file_opendir_cl); + + remote_file_tb.setTitle("远程文件列表"); + remote_file_tb.setNavigationIcon(R.mipmap.back); + remote_file_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + LinearLayoutManager llManager = new LinearLayoutManager(RemoteFileActivity.this); + llManager.setOrientation(LinearLayoutManager.VERTICAL); + remote_file_rv.setLayoutManager(llManager); + + myRecRemoteFileInfosList = new ArrayList<>(); + myRecRemoteFileAdapter = new MyRecRemoteFileAdapter(RemoteFileActivity.this,myRecRemoteFileInfosList); + remote_file_rv.setAdapter(myRecRemoteFileAdapter); + + myRecRemoteFileAdapter.setOnItemListener(new MyRecRemoteFileAdapter.OnItemListener() { + @Override + public void onItemClick(View view, int position) { + if(fileOrDirList.get(position)){ + //文件 + String fileUrl = urlList.get(position); + + int label = MyFileUtils.getInstance().checkFileType(fileUrl); + + showFile(label,fileUrl); + }else{ + //文件夹,进入子目录 + canBack = true; + getRemoteSource(urlList.get(position)); + } + } + + @Override + public void onItemLongClick(View view, final int parentPosition) { + View viewPoP = View.inflate(RemoteFileActivity.this,R.layout.dialog_file_longclick_menu,null); + + ListView listView = viewPoP.findViewById(R.id.dialog_file_longclick_menu_lv); + + String[] menuData = {"下载","取消"}; + ArrayAdapter arrayAdapter = new ArrayAdapter<>(RemoteFileActivity.this,android.R.layout.simple_list_item_1,menuData); + listView.setAdapter(arrayAdapter); + + final PopupWindow popupWindow = new PopupWindow(viewPoP,ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view,int position, long id) { + popupWindow.dismiss(); + + switch (position){ + case 0: + //下载 + if(fileOrDirList.get(parentPosition)){ + //判断读写权限是否正常 + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M){ + String[] needPermissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + List losePermissions = new ArrayList<>(); + for(int i = 0;i < needPermissions.length;i++){ + if(checkSelfPermission(needPermissions[i]) != PackageManager.PERMISSION_GRANTED){ + losePermissions.add(needPermissions[i]); + } + } + if(!losePermissions.isEmpty()){ + //权限不正常 + Toast.makeText(RemoteFileActivity.this,"未能获取到存储器读写权限",Toast.LENGTH_SHORT).show(); + return; + }else{ + //权限都正常 + //检测本地Download目录是否已存在该文件 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File checkExists = new File(file.getPath() + "/com.example.wgjrouter/" + titList.get(parentPosition)); + + if(!checkExists.exists()){ + EventBus.getDefault().postSticky(new MessageEvent(6,fileTypeList.get(parentPosition),titList.get(parentPosition),2,"",urlList.get(parentPosition))); + Toast.makeText(RemoteFileActivity.this,"已添加到下载队列",Toast.LENGTH_SHORT).show(); + }else{ + Toast.makeText(RemoteFileActivity.this,"本地已存在该文件",Toast.LENGTH_SHORT).show(); + } + } + } + }else{ + //低版本,不需要敏感权限确认 + //检测本地Download目录是否已存在该文件 + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File checkExists = new File(file.getPath() + "/com.example.wgjrouter/" + titList.get(parentPosition)); + + if(!checkExists.exists()){ + EventBus.getDefault().postSticky(new MessageEvent(6,fileTypeList.get(parentPosition),titList.get(parentPosition),2,"",urlList.get(parentPosition))); + Toast.makeText(RemoteFileActivity.this,"已添加到下载队列",Toast.LENGTH_SHORT).show(); + }else{ + Toast.makeText(RemoteFileActivity.this,"本地已存在该文件",Toast.LENGTH_SHORT).show(); + } + } + } + }else{ + Toast.makeText(RemoteFileActivity.this,"抱歉,暂不支持下载文件夹",Toast.LENGTH_SHORT).show(); + } + break; + } + } + }); + + ColorDrawable cd = new ColorDrawable(0xb0000000); + popupWindow.setBackgroundDrawable(cd); + popupWindow.setOutsideTouchable(true); + popupWindow.setFocusable(true); + + popupWindow.showAtLocation(remote_file_parent,Gravity.CENTER,0,0); + } + }); + } + + private void getRemoteSource(String webUrl){ + if(webUrl.equals(webRootUrl + "../")){ + canBack = false; + return; + } + + remote_file_pb.setVisibility(View.VISIBLE); + + OkHttpClient ohClient = new OkHttpClient(); + Request req = new Request.Builder() + .url(webUrl) + .method("GET",null) + .build(); + Call call = ohClient.newCall(req); + call.enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + Message msg = new Message(); + msg.what = 1567; + msg.obj = e.getMessage(); + handler.sendMessage(msg); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + Message msg = new Message(); + msg.what = 1568; + msg.obj = response.body().string(); + handler.sendMessage(msg); + } + }); + handler.removeCallbacksAndMessages(null); + } + + private void analyResponse(String webHost,String resBody){ + if(webHost == null){ + return; + } + + myRecRemoteFileInfosList.clear(); + fileOrDirList.clear(); + titList.clear(); + urlList.clear(); + picItemUrlList.clear(); + videoItemUrlList.clear(); + videoTitleList.clear(); + fileTypeList.clear(); + + Document doc = Jsoup.parse(resBody); + Elements elements = doc.getElementsByTag("strong"); + + //设置标题 + remote_file_tb.setTitle(doc.title()); + //解析文件列表 + for(Element element : elements){ + String title = element.text(); + String url = webHost + element.select("a").attr("href"); + + if(title.equals("$RECYCLE.BIN/")){ + continue; + } + + if(title.equals("../")){ + fatherUrl = url; + continue; + } + + //分析文件夹还是文件 + if(title.endsWith("/")){ + //文件夹 + fileOrDirList.add(false); + }else{ + fileOrDirList.add(true); + + //图片列表 + if(title.endsWith("png") || title.endsWith("jpg") || title.endsWith("bmp") || title.endsWith("gif") || title.endsWith("jpeg") || title.endsWith("ico")){ + picItemUrlList.add(url); + } + //视频列表 + if(title.endsWith("avi") || title.endsWith("mov") || title.endsWith("mp4") || title.endsWith("mkv") || title.endsWith("wmv") || title.endsWith("flv") || title.endsWith("rmvb")){ + //将当前文件夹所有的视频地址存入list + videoItemUrlList.add(url); + videoTitleList.add(url.substring(url.lastIndexOf("/") + 1,url.lastIndexOf("."))); + } + //文件类型列表 + fileTypeList.add(CheckFileType(url)); + } + + titList.add(title); + urlList.add(url); + + MyRecRemoteFileInfos myRecRemoteFileInfos = new MyRecRemoteFileInfos(); + myRecRemoteFileInfos.setTitle(title); + myRecRemoteFileInfos.setUrl(url); + myRecRemoteFileInfosList.add(myRecRemoteFileInfos); + } + myRecRemoteFileAdapter.notifyDataSetChanged(); + } + + //查看文件 + private void showFile(int fileType,String fileUrl){ + switch(fileType) { + case 0: + //apk + break; + case 2: + //xls + break; + case 3: + //doc + break; + case 4: + //ppt + break; + case 6: + //ini + break; + case 7: + //iso + break; + case 9: + //pdf + break; + case 11: + //txt + break; + case 12: + //jar包 + break; + case 13: + //压缩包 + break; + case 14: + //大图 + clickPicIndex = picItemUrlList.indexOf(fileUrl); + + View viewPoP = LayoutInflater.from(RemoteFileActivity.this).inflate(R.layout.layout_fg_file_pop_bigpic,null); + + popupWindowPic = new PopupWindow(viewPoP, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT); + + final ImageView leftPic = viewPoP.findViewById(R.id.iv_file_pop_bigpic_left); + final ImageView rightPic = viewPoP.findViewById(R.id.iv_file_pop_bigpic_right); + final PhotoView bigPicIV = viewPoP.findViewById(R.id.iv_file_pop_bigpic); + ImageView bigPicIVClose = viewPoP.findViewById(R.id.iv_file_pop_bigpic_close); + + bigPicIVClose.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + popupWindowPic.dismiss(); + } + }); + + leftPic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickPicIndex = clickPicIndex - 1; + + if(clickPicIndex >= 0){ + rightPic.setVisibility(View.VISIBLE); + Picasso.get().load(picItemUrlList.get(clickPicIndex)) + .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .into(bigPicIV); + }else{ + clickPicIndex = 0; + leftPic.setVisibility(View.GONE); + Toast.makeText(RemoteFileActivity.this,"这是第一张呀",Toast.LENGTH_SHORT).show(); + } + } + }); + + rightPic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickPicIndex = clickPicIndex + 1; + + if(clickPicIndex < picItemUrlList.size()){ + leftPic.setVisibility(View.VISIBLE); + Picasso.get().load(picItemUrlList.get(clickPicIndex)) + .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .into(bigPicIV); + }else{ + clickPicIndex = clickPicIndex - 1; + rightPic.setVisibility(View.GONE); + Toast.makeText(RemoteFileActivity.this,"最后一张了",Toast.LENGTH_SHORT).show(); + } + } + }); + + bigPicIV.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + popupWindowPic.dismiss(); + return true; + } + }); + + Picasso.get().load(fileUrl) + .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) + .placeholder(R.mipmap.loading_zhanwei) + .error(R.mipmap.loading_faild) + .into(bigPicIV); + + popupWindowPic.showAtLocation(remote_file_parent, Gravity.CENTER,0,0); + break; + case 15: + //视频 + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(RemoteFileActivity.this); + boolean default_resolver_inner = sp.getBoolean("default_resolver_inner",true); + + if(default_resolver_inner){ + //内部解析 + Intent intent = new Intent(RemoteFileActivity.this,VideoPlayVTM.class); + intent.putExtra("videoType",0); + intent.putExtra("videoUrl",fileUrl); + intent.putExtra("videoTitle",fileUrl.substring((fileUrl.lastIndexOf("/") + 1),fileUrl.length())); + intent.putStringArrayListExtra("videoUrlList",videoItemUrlList); + intent.putStringArrayListExtra("videoTitleList",videoTitleList); + startActivity(intent); + }else{ + MyPhoneUtils.getInstance(RemoteFileActivity.this).usePlayerPlayNetVideo(fileUrl); + } + break; + case 16: + //磁链种子 + break; + case 17: + //音频 + break; + default: + //无自带解析器,调用其它解析器 + break; + } + } + + /** + * 解析文件类型 + * @param fileUrl + * @return + */ + private int CheckFileType(String fileUrl){ + int label = 1; + if(fileUrl.endsWith("png") || fileUrl.endsWith("jpg") || fileUrl.endsWith("bmp") || fileUrl.endsWith("gif") || fileUrl.endsWith("jpeg") || fileUrl.endsWith("ico")){ + label = 14; + } else if(fileUrl.endsWith("apk")){ + label = 0; + } else if(fileUrl.endsWith("xls") || fileUrl.endsWith("xlsx")){ + label = 2; + } else if(fileUrl.endsWith("doc") || fileUrl.endsWith("docx")){ + label = 3; + } else if(fileUrl.endsWith("ppt") || fileUrl.endsWith("pptx")){ + label = 4; + } else if(fileUrl.endsWith("exe")){ + label = 5; + } else if(fileUrl.endsWith("ini")){ + label = 6; + } else if(fileUrl.endsWith("iso")){ + label = 7; + } else if(fileUrl.endsWith("link")){ + label = 8; + } else if(fileUrl.endsWith("pdf")){ + label = 9; + } else if(fileUrl.endsWith("psd")){ + label = 10; + } else if(fileUrl.endsWith("txt")){ + label = 11; + } else if(fileUrl.endsWith("jar")){ + label = 12; + } else if(fileUrl.endsWith("zip") || fileUrl.endsWith("rar") || fileUrl.endsWith("tar") || fileUrl.endsWith("7z")){ + label = 13; + } else if(fileUrl.endsWith("avi") || fileUrl.endsWith("mov") || fileUrl.endsWith("mp4") || fileUrl.endsWith("mkv") || fileUrl.endsWith("wmv") || fileUrl.endsWith("flv") || fileUrl.endsWith("rmvb")){ + label = 15; + } else if(fileUrl.endsWith("torrent")) { + label = 16; + }else if(fileUrl.endsWith("mp3") || fileUrl.endsWith("wma") || fileUrl.endsWith("wav")){ + label = 17; + }else{ + label = 18; + } + return label; + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){ + if(popupWindowPic != null && popupWindowPic.isShowing()){ + popupWindowPic.dismiss(); + }else{ + if(canBack){ + getRemoteSource(fatherUrl); + }else{ + finish(); + } + } + } + return true; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/RouterDevices.java b/app/src/main/java/com/example/wgjrouter/RouterDevices.java new file mode 100644 index 0000000..0134150 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/RouterDevices.java @@ -0,0 +1,248 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.InputDevice; +import android.view.KeyEvent; +import android.view.View; +import android.widget.ListView; +import android.widget.Toast; + +import com.example.adapter.MyBaLvDevicesAdater; +import com.example.bean.MyBaLvDevices; +import com.example.consts.Consts; + +import org.apache.commons.net.telnet.TelnetClient; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + +public class RouterDevices extends AppCompatActivity { + + private Toolbar router_devices_tb; + private ListView router_devices_lv; + + private List devNameList = new ArrayList<>(); + private List devIPList = new ArrayList<>(); + private List devMACList = new ArrayList<>(); + private List devAccNetList = new ArrayList<>(); + private List devAccShaList = new ArrayList<>(); + private List devAccBindList = new ArrayList<>(); + + private List myBaLvDevicesList; + private MyBaLvDevicesAdater myBaLvDevicesAdater; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + Toast.makeText(RouterDevices.this,"抱歉,获取在线设备异常",Toast.LENGTH_SHORT).show(); + break; + case 1: + myBaLvDevicesList.clear(); + + if(devNameList.size() == 0){ + Toast.makeText(RouterDevices.this,"当前无在线设备",Toast.LENGTH_SHORT).show(); + return; + } + + for(int i = 0;i(); + myBaLvDevicesAdater = new MyBaLvDevicesAdater(this,myBaLvDevicesList); + router_devices_lv = findViewById(R.id.router_devices_lv); + router_devices_lv.setAdapter(myBaLvDevicesAdater); + + router_devices_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + private void getRouterDevices(final String code){ + new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(); + InetSocketAddress isa = new InetSocketAddress(Consts.SOCKETHOST,Consts.SOCKETPORT); + socket.connect(isa); + + OutputStream os = socket.getOutputStream(); + PrintWriter pw = new PrintWriter(os); + pw.write(code); + pw.flush(); + + socket.shutdownOutput(); + + InputStream is = socket.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + + String info = null; + String infos = ""; + + while((info = br.readLine()) != null){ + infos = infos + info; + } + + Log.d("zouguo",infos); + parseXMLWithPull(0,infos); + + socket.close(); + os.close(); + pw.close(); + is.close(); + isr.close(); + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }).start(); + } + + private void parseXMLWithPull(int flag,String xmlData){ + try { + XmlPullParserFactory xppf = XmlPullParserFactory.newInstance(); + XmlPullParser xpp = xppf.newPullParser(); + xpp.setInput(new StringReader(xmlData)); + + int eventType = xpp.getEventType(); + + String devName = null; + String devIP = null; + String devMac = null; + String devAccNet = null; + String devAccSha = null; + String devBindMac = null; + + devNameList.clear(); + devIPList.clear(); + devMACList.clear(); + devAccNetList.clear(); + devAccShaList.clear(); + devAccBindList.clear(); + + while(eventType != XmlPullParser.END_DOCUMENT){ + switch (eventType){ + case XmlPullParser.START_TAG: + String nodeName = xpp.getName(); + + switch (flag){ + case 0: + if("NAME".equals(nodeName)){ + devName = xpp.nextText(); + } + if("IP".equals(nodeName)){ + devIP = xpp.nextText(); + } + if("MAC".equals(nodeName)){ + devMac = xpp.nextText(); + } + if("ACCESS_INTERNET".equals(nodeName)){ + devAccNet = xpp.nextText(); + } + if("ACCESS_SHAREDISK".equals(nodeName)){ + devAccSha = xpp.nextText(); + } + if("BIND_MAC".equals(nodeName)){ + devBindMac = xpp.nextText(); + } + break; + } + break; + case XmlPullParser.END_TAG: + String node = xpp.getName(); + + if(flag == 0 && "DEVICE".equals(node)){ + //完成了一个设备的信息读取 + devNameList.add(devName); + devIPList.add(devIP); + devMACList.add(devMac); + devAccNetList.add(devAccNet); + devAccShaList.add(devAccSha); + devAccBindList.add(devBindMac); + } + break; + } + + eventType = xpp.next(); + } + + if(flag == 0){ + //设备信息读取完成 + Message msg = new Message(); + msg.what = 1; + handler.sendMessage(msg); + } + } catch (Exception e) { + e.printStackTrace(); + + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/RouterSetRepeater.java b/app/src/main/java/com/example/wgjrouter/RouterSetRepeater.java new file mode 100644 index 0000000..5155617 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/RouterSetRepeater.java @@ -0,0 +1,869 @@ +package com.example.wgjrouter; + +import android.content.DialogInterface; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.adapter.MyBaLvAPInfosAdapter; +import com.example.bean.MyBaLvApInfos; +import com.example.consts.Consts; + +import org.apache.commons.net.telnet.TelnetClient; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class RouterSetRepeater extends AppCompatActivity { + + private ProgressBar router_setrepeater_pb; + private Toolbar router_setrepeater_tb; + private Switch router_setrepeater_switch; + private ListView router_setrepeater_lv; + private ImageView router_setrepeater_iv; + + private List myBaLvAPInfosList; + private MyBaLvAPInfosAdapter myBaLvAPInfosAdapter; + + private TelnetClient telnetClient = null; + private InputStream is = null; + private PrintStream ps = null; + private char prompt = '$'; + private List apindexList = new ArrayList<>(); + private List apssidList = new ArrayList<>(); + private List apsignalList = new ArrayList<>(); + private List apencryptList = new ArrayList<>(); + + private List apBridgedList = new ArrayList<>(); + + private boolean isFresh = false; + //必须开启了中继后,才能进行关闭中继 + private boolean isRepeater = false; + private String apNamed = null; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + runOnUiThread(new Runnable() { + @Override + public void run() { + router_setrepeater_pb.setVisibility(View.GONE); + router_setrepeater_tb.setTitle("无线中继"); + } + }); + + switch (msg.what){ + case 0: + Toast.makeText(RouterSetRepeater.this,"抱歉,与微路由通信超时",Toast.LENGTH_SHORT).show(); + break; + case 6: + //AP获取完成 + Log.d("zouguo","扫描结束"); + apBridgedList.clear(); + myBaLvAPInfosList.clear(); + + if(apindexList.size() == 0){ + Toast.makeText(RouterSetRepeater.this,"未能搜到周围AP信息",Toast.LENGTH_SHORT).show(); + return; + } + + for(int i = 0;i < apssidList.size();i++){ + MyBaLvApInfos myBaLvAPInfos = new MyBaLvApInfos(); + myBaLvAPInfos.setAPindex(apindexList.get(i)); + myBaLvAPInfos.setAPssid(apssidList.get(i)); + myBaLvAPInfos.setAPsignal(apsignalList.get(i)); + myBaLvAPInfos.setAPencrypt(apencryptList.get(i)); + + if(apNamed != null && apssidList.get(i).equals(apNamed)){ + //当前桥接的WiFi + myBaLvAPInfos.setAPbridged(true); + apBridgedList.add(true); + }else{ + myBaLvAPInfos.setAPbridged(false); + apBridgedList.add(false); + } + + myBaLvAPInfosList.add(myBaLvAPInfos); + } + + myBaLvAPInfosAdapter.notifyDataSetChanged(); + break; + case 7: + //XML解析失败 + Toast.makeText(RouterSetRepeater.this,"抱歉,解析数据时发生异常",Toast.LENGTH_SHORT).show(); + break; + case 8: + //获取中继状态、扫描AP信息完成 + break; + case 9: + if(msg.arg1 == 2){ + return; + } + + Toast.makeText(RouterSetRepeater.this,"无线中继配置完成,请重连热点",Toast.LENGTH_SHORT).show(); + finish(); + break; + case 10: + if(msg.arg1 == 1){ + //关闭中继 + apNamed = null; + } + + //获取到中继状态 + router_setrepeater_switch.setEnabled(true); + if(msg.obj.toString().contains("sta")){ + //中继配置文件正常 + isRepeater = true; + router_setrepeater_switch.setChecked(true); + }else{ + isRepeater = false; + router_setrepeater_switch.setChecked(false); + } + break; + case 11: + String[] a = msg.obj.toString().split("\n"); + + if(a.length == 3){ + apNamed = a[1]; + + try { + apNamed = new String(apNamed.trim().getBytes("iso-8859-1"),"UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + if(apNamed.contains("?")){ + apNamed = apNamed.replace("?",""); + } + + Log.d("zouguo","apNamed:" + apNamed); + } + break; + } + } + }; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_router_setrepeater); + + initView(); + + //获取中继状态,存在异常的可能性 + checkRepeaterStatus("root","holl0311",Consts.REPEATER_CHECK_STATUS); + } + + private void initView(){ + router_setrepeater_pb = findViewById(R.id.router_setrepeater_pb); + router_setrepeater_tb = findViewById(R.id.router_setrepeater_tb); + router_setrepeater_tb.setNavigationIcon(R.mipmap.back); + router_setrepeater_tb.setTitle("中继初始化..."); + + myBaLvAPInfosList = new ArrayList<>(); + myBaLvAPInfosAdapter = new MyBaLvAPInfosAdapter(RouterSetRepeater.this,myBaLvAPInfosList); + router_setrepeater_lv = findViewById(R.id.router_setrepeater_lv); + router_setrepeater_lv.setAdapter(myBaLvAPInfosAdapter); + + router_setrepeater_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, final int position, long id) { + //判断加密方式 + if(!apencryptList.get(position).equals("")){ + if(apBridgedList.get(position)){ + //当前AP已被中继 + AlertDialog adf = null; + AlertDialog.Builder adbf = new AlertDialog.Builder(RouterSetRepeater.this); + adbf.setTitle("当前AP已被中继"); + adbf.setMessage("是否关闭该中继"); + adbf.setPositiveButton("关闭", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + router_setrepeater_pb.setVisibility(View.VISIBLE); + Toast.makeText(RouterSetRepeater.this,"无线中继配置中,请稍等",Toast.LENGTH_SHORT).show(); + //关闭中继 + connectRouter(1,"root","holl0311","","",""); + } + }); + adbf.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + adf = adbf.create(); + adf.show(); + adf.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + }else{ + if(apNamed != null){ + //已经中继了其它AP + AlertDialog adf = null; + AlertDialog.Builder adbf = new AlertDialog.Builder(RouterSetRepeater.this); + adbf.setTitle("已中继其它AP"); + adbf.setMessage("是否切换中继"); + adbf.setPositiveButton("切换", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + //关闭中继 + connectRouter(2,"root","holl0311","","",""); + + router_setrepeater_pb.setVisibility(View.VISIBLE); + Toast.makeText(RouterSetRepeater.this,"关闭当前中继,请稍等",Toast.LENGTH_SHORT).show(); + try { + //休眠2秒 + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(apencryptList.get(position).equals("Other")){ + router_setrepeater_pb.setVisibility(View.GONE); + Toast.makeText(RouterSetRepeater.this,"抱歉,无法识别的AP加密模式",Toast.LENGTH_SHORT).show(); + return; + } + + //当前热点有加密 + final AlertDialog dialogChange = new AlertDialog.Builder(RouterSetRepeater.this).create(); + + View viewDialog = View.inflate(RouterSetRepeater.this,R.layout.dialog_with_edittext,null); + + TextView title = viewDialog.findViewById(R.id.dialog_with_et_title_tv); + final EditText et_appwd = viewDialog.findViewById(R.id.dialog_with_et_input_et); + Button btnok = viewDialog.findViewById(R.id.dialog_with_et_ok_btn); + Button btnno = viewDialog.findViewById(R.id.dialog_with_et_no_btn); + + title.setText("请输入:"); + et_appwd.setHint( apssidList.get(position) + "的无线密码"); + + btnok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(et_appwd.getText().toString().length() < 8){ + Toast.makeText(RouterSetRepeater.this,"无线密码至少8位字母或数字",Toast.LENGTH_SHORT).show(); + return; + } + if(!et_appwd.getText().toString().equals("")){ + dialogChange.dismiss(); + router_setrepeater_pb.setVisibility(View.VISIBLE); + + Toast.makeText(RouterSetRepeater.this,"无线中继配置中,请稍等",Toast.LENGTH_SHORT).show(); + connectRouter(0,"root","holl0311",apssidList.get(position),et_appwd.getText().toString().replaceAll("\\s*",""),apencryptList.get(position)); + }else{ + Toast.makeText(RouterSetRepeater.this,"抱歉,当前AP需要输入无线密码",Toast.LENGTH_SHORT).show(); + } + } + }); + + btnno.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialogChange.dismiss(); + router_setrepeater_pb.setVisibility(View.GONE); + } + }); + + dialogChange.setView(viewDialog); + dialogChange.setCancelable(true); + dialogChange.setCanceledOnTouchOutside(false); + dialogChange.show(); + } + }); + adbf.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + adf = adbf.create(); + adf.show(); + adf.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + }else{ + if(apencryptList.get(position).equals("Other")){ + router_setrepeater_pb.setVisibility(View.GONE); + Toast.makeText(RouterSetRepeater.this,"抱歉,无法识别的AP加密模式",Toast.LENGTH_SHORT).show(); + return; + } + + //当前热点有加密 + final AlertDialog dialog = new AlertDialog.Builder(RouterSetRepeater.this).create(); + + View viewDialog = View.inflate(RouterSetRepeater.this,R.layout.dialog_with_edittext,null); + + TextView title = viewDialog.findViewById(R.id.dialog_with_et_title_tv); + final EditText et_appwd = viewDialog.findViewById(R.id.dialog_with_et_input_et); + Button btnok = viewDialog.findViewById(R.id.dialog_with_et_ok_btn); + Button btnno = viewDialog.findViewById(R.id.dialog_with_et_no_btn); + + title.setText("请输入:"); + et_appwd.setHint( apssidList.get(position) + "的无线密码"); + + btnok.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(et_appwd.getText().toString().length() < 8){ + Toast.makeText(RouterSetRepeater.this,"无线密码至少8位字母或数字",Toast.LENGTH_SHORT).show(); + return; + } + if(!et_appwd.getText().toString().equals("")){ + dialog.dismiss(); + router_setrepeater_pb.setVisibility(View.VISIBLE); + + Toast.makeText(RouterSetRepeater.this,"无线中继配置中,请稍等",Toast.LENGTH_SHORT).show(); + connectRouter(0,"root","holl0311",apssidList.get(position),et_appwd.getText().toString().replaceAll("\\s*",""),apencryptList.get(position)); + }else{ + Toast.makeText(RouterSetRepeater.this,"抱歉,当前AP需要输入无线密码",Toast.LENGTH_SHORT).show(); + } + } + }); + + btnno.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + router_setrepeater_pb.setVisibility(View.GONE); + } + }); + + dialog.setView(viewDialog); + dialog.setCancelable(true); + dialog.setCanceledOnTouchOutside(false); + dialog.show(); + } + } + }else{ + router_setrepeater_pb.setVisibility(View.VISIBLE); + //当前热点无加密 + Toast.makeText(RouterSetRepeater.this,"无线中继配置中,请稍等",Toast.LENGTH_SHORT).show(); + connectRouter(0,"root","holl0311",apssidList.get(position),"","none"); + } + } + }); + + router_setrepeater_iv = findViewById(R.id.router_setrepeater_iv); + router_setrepeater_iv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(isFresh){ + return; + } + isFresh = true; + + myBaLvAPInfosList.clear(); + myBaLvAPInfosAdapter.notifyDataSetChanged(); + scanAroundAP(); + } + }); + + router_setrepeater_switch = findViewById(R.id.router_setrepeater_switch); + router_setrepeater_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(isChecked){ + router_setrepeater_iv.setEnabled(true); + + //打开中继,扫描周围AP + scanAroundAP(); + }else{ + router_setrepeater_iv.setEnabled(false); + if(isRepeater){ + //关闭中继 + AlertDialog ad = null; + AlertDialog.Builder adb = new AlertDialog.Builder(RouterSetRepeater.this); + adb.setTitle("关闭提醒"); + adb.setMessage("是否要关闭无线中继"); + adb.setPositiveButton("关闭", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Toast.makeText(RouterSetRepeater.this,"正在关闭无线中继,请稍等",Toast.LENGTH_SHORT).show(); + myBaLvAPInfosList.clear(); + myBaLvAPInfosAdapter.notifyDataSetChanged(); + + connectRouter(1,"root","holl0311","","",""); + } + }); + adb.setNegativeButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + router_setrepeater_switch.setChecked(true); + dialog.dismiss(); + } + }); + ad = adb.create(); + ad.show(); + ad.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.GRAY); + ad.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.RED); + }else{ + //中继似乎并没有开启,存在没检测到中继状态的可能性,暂不解决 + } + } + } + }); + + router_setrepeater_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + /** + * 获取中继状态 + */ + private void getRepeaterState(){ + sendMsgToRouter(3,Consts.ROUTER_GET_INFO); + } + + /** + * 扫描周围AP信息 + */ + private void scanAroundAP(){ + router_setrepeater_pb.setVisibility(View.VISIBLE); + + Log.d("zouguo","扫描周围AP中..."); + sendMsgToRouter(4,Consts.ROUTER_SCAN_AP); + isFresh = false; + } + + /** + * 通过命令行的方式,配置路由器 + * @param user + * @param password + * @param STASSID + * @param STAKEY + */ + private void connectRouter(final int flag,final String user,final String password,final String STASSID,final String STAKEY,final String ENCRTPT){ + //操作路由器 + new Thread(new Runnable() { + @Override + public void run() { + telnetClient = new TelnetClient(); + try { + telnetClient.connect("192.168.80.1",23); + is = telnetClient.getInputStream(); + ps = new PrintStream(telnetClient.getOutputStream()); + prompt = user.equals("root") ? '#' : '$'; + + //登录 + telnetLogin(telnetClient,user,password); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + switch (flag){ + case 0: + //开启中继 + //配置Network + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_NETWORK_FIRST); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_NETWORK_TWO); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_NETWORK_THREE); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_NETWORK_OVER); + + //配置Wireless + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_FIRST); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_TWO); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_THREE); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_FOUR); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_FIVE.replace("**",STASSID)); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_SIX.replace("**",ENCRTPT)); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_SEVEN.replace("**",STAKEY)); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_WIRELESS_OVER); + + //配置Apconfig + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_FIRST); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_TWO.replace("**",STASSID)); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_THREE.replace("**",STAKEY)); + //sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_FOUR.replace("**","6")); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_FIVE.replace("**",ENCRTPT)); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_OVER); + + //配置中继开启标志 + sendCodeToRouter(telnetClient,Consts.REPEATER_ON_STASTATUS); + + //重启WIFI,使配置生效 + sendCodeToRouter(telnetClient,Consts.NETWORK_WIFI_RELAOD); + + isRepeater = true; + break; + case 1: + case 2: + //关闭中继 + sendCodeToRouter(telnetClient, Consts.REPEATER_DEL_NETWORK); + sendCodeToRouter(telnetClient, Consts.REPEATER_SET_NETWORK_OVER); + sendCodeToRouter(telnetClient,Consts.REPEATER_DEL_WIRELESS); + sendCodeToRouter(telnetClient, Consts.REPEATER_SET_WIRELESS_OVER); + sendCodeToRouter(telnetClient,Consts.REPEATER_DEL_APCONFIG); + sendCodeToRouter(telnetClient,Consts.REPEATER_SET_APCONFIG_OVER); + + //配置中继关闭标志 + sendCodeToRouter(telnetClient,Consts.REPEATER_OFF_STASTATUS); + + //重启WIFI,使配置生效 + sendCodeToRouter(telnetClient,Consts.NETWORK_WIFI_RELAOD); + + isRepeater = false; + break; + } + + //退出 + ps.println("exit\r\n"); + ps.flush(); + disConnection(); + + Message msg = new Message(); + msg.what = 9; + msg.arg1 = flag; + handler.sendMessage(msg); + } catch (IOException e) { + e.printStackTrace(); + + isRepeater = false; + + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + } + }).start(); + } + + + private void checkRepeaterStatus(final String user,final String password,final String code){ + //操作路由器 + new Thread(new Runnable() { + @Override + public void run() { + telnetClient = new TelnetClient(); + try { + telnetClient.connect("192.168.80.1",23); + + is = telnetClient.getInputStream(); + ps = new PrintStream(telnetClient.getOutputStream()); + + prompt = user.equals("root") ? '#' : '$'; + + //登录 + telnetLogin(telnetClient,user,password); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + String status = sendCodeToRouter(telnetClient,code); + + if(status != null && status.contains("sta")){ + //中继已开启,获取该AP名称 + String apName = sendCodeToRouter(telnetClient,Consts.REPEATERED_GET_APNAME); + + Message msg = new Message(); + msg.what = 11; + msg.obj = apName; + handler.sendMessage(msg); + } + + //退出 + ps.println("exit\r\n"); + ps.flush(); + disConnection(); + + Message msg = new Message(); + msg.what = 10; + msg.obj = status; + handler.sendMessage(msg); + }catch (Exception e){ + e.printStackTrace(); + + isRepeater = false; + + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + } + }).start(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + disConnection(); + } + + //Telnet登录到微路由 + private void telnetLogin(TelnetClient telnetClient,String user,String password){ + read(telnetClient,"Holl login:"); + write(telnetClient,user); + read(telnetClient,"Password:"); + write(telnetClient,password); + read(telnetClient,prompt + " "); + write(telnetClient,"cd /"); + read(telnetClient,prompt + " "); + } + + private String sendCodeToRouter(TelnetClient telnetClient,String code){ + write(telnetClient,code); + return read(telnetClient,prompt + " "); + } + + private String read(TelnetClient telnetClient,String code){ + char lastChar = code.charAt(code.length() - 1); + StringBuffer stringBuffer = new StringBuffer(); + try { + char ch = (char) is.read(); + + while(true){ + stringBuffer.append(ch); + if(ch == lastChar){ + if(stringBuffer.toString().endsWith(code)){ + Log.d("zouguo",stringBuffer.toString()); + return stringBuffer.toString(); + } + } + ch = (char) is.read(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private void write(TelnetClient telnetClient,String code){ + try { + ps.println(code); + ps.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void disConnection(){ + try { + if(telnetClient != null) + telnetClient.disconnect(); + if(is != null) + is.close(); + if(ps != null) + ps.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void sendMsgToRouter(final int flag,final String msg){ + + new Thread(new Runnable() { + @Override + public void run() { + + Socket socket = new Socket(); + InetSocketAddress inetSocketAddress = new InetSocketAddress("192.168.80.1",7888); + try { + socket.connect(inetSocketAddress,5000); + + OutputStream os = socket.getOutputStream(); + PrintWriter pw = new PrintWriter(os); + pw.write(msg); + pw.flush(); + + socket.shutdownOutput(); + + InputStream is = socket.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + + String infos = ""; + String info = null; + + while((info = br.readLine()) != null){ + infos = infos + info; + } + + //调用XML解析器 + if(flag == 2){ + //换行符丢失,需要对字符串格式化,否则XML解析失败 + infos = infos.replace("PARTITIONindex","PARTITION index"); + } + + Log.d("zouguo",infos); + //格式纠正 + if(flag == 4){ + infos = infos.replace("APindex","AP index"); + Log.d("zouguo","AP列表:" + infos); + } + + parseXMLWithPull(flag,infos); + + socket.close(); + os.close(); + pw.close(); + is.close(); + isr.close(); + br.close(); + + Message msg = new Message(); + msg.what = 8; + handler.sendMessage(msg); + } catch (IOException e) { + e.printStackTrace(); + + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + + isFresh = false; + } + }).start(); + } + + private void parseXMLWithPull(int flag,String xmlData){ + try { + XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); + xmlPullParser.setInput(new StringReader(xmlData)); + + int eventType = xmlPullParser.getEventType(); + + String routerIsRepeater = null; + int APIndex = 1; + String APSSID = null; + int APSignal = 100; + String APEncrypt = null; + + apindexList.clear(); + apssidList.clear(); + apsignalList.clear(); + apencryptList.clear(); + + while(eventType != XmlPullParser.END_DOCUMENT){ + switch (eventType){ + case XmlPullParser.START_TAG: + //开始解析某个节点 + String nodeName = xmlPullParser.getName(); + + switch (flag){ + case 3: + if("IS_ENABLE".equals(nodeName)){ + routerIsRepeater = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 15; + msg.obj = routerIsRepeater; + handler.sendMessage(msg); + } + break; + case 4: + if("AP".equals(nodeName)){ + APIndex = Integer.parseInt(xmlPullParser.getAttributeValue(0)); + } + if("SSID".equals(nodeName)){ + APSSID = xmlPullParser.nextText(); + } + if("SIGNAL".equals(nodeName)){ + APSignal = Integer.parseInt(xmlPullParser.nextText()); + } + if("ENCRYPT_MODE".equals(nodeName)){ + APEncrypt = xmlPullParser.nextText(); + } + break; + } + break; + case XmlPullParser.END_TAG: + //完成解析某个节点 + String node = xmlPullParser.getName(); + if(flag == 4 && node.equals("AP")) { + //代表一个AP信息读取完成 + apindexList.add(APIndex); + apssidList.add(APSSID); + apsignalList.add(APSignal); + //处理wifi加密方式 + if (APEncrypt.equals("WPA2")) { + apencryptList.add("psk2"); + } else if (APEncrypt.equals("WPA")) { + apencryptList.add("psk"); + } else if (APEncrypt.startsWith("WPA+WPA2")) { + apencryptList.add("psk-mixed"); + } else if (APEncrypt.equals("")) { + apencryptList.add(""); + }else{ + apencryptList.add("Other"); + } + } + break; + default: + break; + } + eventType = xmlPullParser.next(); + } + + if(flag == 4){ + Message msg = new Message(); + msg.what = 6; + handler.sendMessage(msg); + } + } catch (Exception e) { + e.printStackTrace(); + + Message msg = new Message(); + msg.what = 7; + handler.sendMessage(msg); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/RouterSetWan.java b/app/src/main/java/com/example/wgjrouter/RouterSetWan.java new file mode 100644 index 0000000..89eddb7 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/RouterSetWan.java @@ -0,0 +1,43 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; + +public class RouterSetWan extends AppCompatActivity { + + private Toolbar router_setwan_tb; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_router_setwan); + + initView(); + } + + private void initView(){ + router_setwan_tb = findViewById(R.id.router_setwan_tb); + router_setwan_tb.setNavigationIcon(R.mipmap.back); + router_setwan_tb.setTitle("外网设置"); + + router_setwan_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/RouterSetWiFiPwd.java b/app/src/main/java/com/example/wgjrouter/RouterSetWiFiPwd.java new file mode 100644 index 0000000..2453119 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/RouterSetWiFiPwd.java @@ -0,0 +1,344 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.example.consts.Consts; + +import org.apache.commons.net.telnet.TelnetClient; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class RouterSetWiFiPwd extends AppCompatActivity { + + private ProgressBar router_setwifipwd_pb; + private Toolbar router_setwifipwd_tb; + private Button router_setwifipwd_set; + private EditText router_setwifipwd_ssid_et; + private EditText router_setwifipwd_key_et; + private EditText router_setwifipwd_confirm_et; + + private TelnetClient telnetClient = null; + private InputStream is = null; + private PrintStream ps = null; + private char prompt = '$'; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + runOnUiThread(new Runnable() { + @Override + public void run() { + router_setwifipwd_pb.setVisibility(View.GONE); + } + }); + + switch (msg.what){ + case 0: + Toast.makeText(RouterSetWiFiPwd.this,"抱歉,与微路由通信超时",Toast.LENGTH_SHORT).show(); + break; + case 1: + router_setwifipwd_ssid_et.setText(msg.obj.toString()); + break; + case 9: + Toast.makeText(RouterSetWiFiPwd.this,"恭喜,WiFi配置成功,请重连热点",Toast.LENGTH_SHORT).show(); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_router_setwifipwd); + + initView(); + getWifiInfo(2,Consts.ROUTER_GET_INFOS); + } + + private void initView(){ + router_setwifipwd_pb = findViewById(R.id.router_setwifipwd_pb); + router_setwifipwd_tb = findViewById(R.id.router_setwifipwd_tb); + router_setwifipwd_tb.setNavigationIcon(R.mipmap.back); + router_setwifipwd_tb.setTitle("微路由WiFi设置"); + + router_setwifipwd_set = findViewById(R.id.router_setwifipwd_set); + + router_setwifipwd_ssid_et = findViewById(R.id.router_setwifipwd_ssid_et); + router_setwifipwd_key_et = findViewById(R.id.router_setwifipwd_key_et); + router_setwifipwd_confirm_et = findViewById(R.id.router_setwifipwd_confirm_et); + + router_setwifipwd_set.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(!router_setwifipwd_ssid_et.getText().toString().equals("")){ + if(!router_setwifipwd_key_et.getText().toString().equals("")){ + if(!router_setwifipwd_confirm_et.getText().toString().equals("")){ + if(router_setwifipwd_confirm_et.getText().toString().equals(router_setwifipwd_key_et.getText().toString())){ + Toast.makeText(RouterSetWiFiPwd.this,"WiFi信息配置中,请稍等",Toast.LENGTH_SHORT).show(); + router_setwifipwd_pb.setVisibility(View.VISIBLE); + + //设置WiFi + connectRouter("root","holl0311",router_setwifipwd_ssid_et.getText().toString().replaceAll("\\s*",""),router_setwifipwd_confirm_et.getText().toString().replaceAll("\\s*","")); + }else{ + router_setwifipwd_pb.setVisibility(View.GONE); + Toast.makeText(RouterSetWiFiPwd.this,"两次密码不一致",Toast.LENGTH_SHORT).show(); + } + } + } + } + } + }); + + router_setwifipwd_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + private void getWifiInfo(final int flag,final String code){ + //初始获取当前WiFi的名称、密码 + new Thread(new Runnable() { + @Override + public void run() { + try { + Socket socket = new Socket(); + InetSocketAddress isa = new InetSocketAddress("192.168.80.1",7888); + socket.connect(isa,5000); + + OutputStream os = socket.getOutputStream(); + PrintWriter pw = new PrintWriter(os); + pw.write(code); + pw.flush(); + + socket.shutdownOutput(); + + InputStream is = socket.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + + String info = null; + String infos = ""; + + while((info = br.readLine()) != null){ + infos = infos + info; + } + + //调用XML解析器 + if(flag == 2){ + //换行符丢失,需要对字符串格式化,否则XML解析失败 + infos = infos.replace("PARTITIONindex","PARTITION index"); + } + parseXMLWithPull(flag,infos); + + socket.close(); + os.close(); + pw.close(); + is.close(); + isr.close(); + br.close(); + } catch (IOException e) { + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + + } + }).start(); + } + + private void parseXMLWithPull(int flag,String xmlData) { + try { + XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); + xmlPullParser.setInput(new StringReader(xmlData)); + + int eventType = xmlPullParser.getEventType(); + + String apSSID = null; + + while (eventType != XmlPullParser.END_DOCUMENT) { + switch (eventType) { + case XmlPullParser.START_TAG: + //开始解析某个节点 + String nodeName = xmlPullParser.getName(); + + switch (flag) { + case 2: + if ("SSID".equals(nodeName)) { + apSSID = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 1; + msg.obj = apSSID; + handler.sendMessage(msg); + } + break; + } + break; + case XmlPullParser.END_TAG: + //完成解析某个节点 + break; + default: + break; + } + eventType = xmlPullParser.next(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void connectRouter(final String user,final String password,final String SSID,final String KEY){ + //操作路由器 + new Thread(new Runnable() { + @Override + public void run() { + telnetClient = new TelnetClient(); + try { + telnetClient.connect("192.168.80.1",23); + + is = telnetClient.getInputStream(); + ps = new PrintStream(telnetClient.getOutputStream()); + + prompt = user.equals("root") ? '#' : '$'; + + //登录 + telnetLogin(telnetClient,user,password); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //设置WIFI + sendCodeToRouter(telnetClient,Consts.CHANGE_WIFI_SSID.replace("**",SSID)); + sendCodeToRouter(telnetClient,Consts.CHANGE_WIFI_KEY.replace("**",KEY)); + sendCodeToRouter(telnetClient,Consts.CHANGE_WIFI_ENCR); + sendCodeToRouter(telnetClient,Consts.CHANGE_WIFI_COMMIT); + + //退出 + ps.println("exit\r\n"); + ps.flush(); + disConnection(); + + Message msg = new Message(); + msg.what = 9; + handler.sendMessage(msg); + } catch (IOException e) { + e.printStackTrace(); + + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + } + }).start(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + disConnection(); + } + + //Telnet登录到微路由 + private void telnetLogin(TelnetClient telnetClient,String user,String password){ + read(telnetClient,"Holl login:"); + write(telnetClient,user); + read(telnetClient,"Password:"); + write(telnetClient,password); + read(telnetClient,prompt + " "); + write(telnetClient,"cd /"); + read(telnetClient,prompt + " "); + } + + private void sendCodeToRouter(TelnetClient telnetClient,String code){ + write(telnetClient,code); + read(telnetClient,prompt + " "); + } + + private String read(TelnetClient telnetClient,String code){ + char lastChar = code.charAt(code.length() - 1); + StringBuffer stringBuffer = new StringBuffer(); + try { + char ch = (char) is.read(); + + while(true){ + stringBuffer.append(ch); + if(ch == lastChar){ + if(stringBuffer.toString().endsWith(code)){ + Log.d("zouguo",stringBuffer.toString()); + return stringBuffer.toString(); + } + } + ch = (char) is.read(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private void write(TelnetClient telnetClient,String code){ + try { + ps.println(code); + ps.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void disConnection(){ + try { + if(telnetClient != null) + telnetClient.disconnect(); + if(is != null) + is.close(); + if(ps != null) + ps.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/RouterStatus.java b/app/src/main/java/com/example/wgjrouter/RouterStatus.java new file mode 100644 index 0000000..fda38ce --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/RouterStatus.java @@ -0,0 +1,420 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.consts.Consts; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + + +public class RouterStatus extends AppCompatActivity { + + private Toolbar router_status_tb; + private TextView router_status_tv_devices; + private TextView router_status_tv_mode; + private TextView router_status_tv_ip; + private TextView router_status_tv_subnetmask; + private TextView router_status_tv_gateway; + private TextView router_status_tv_dns; + private TextView router_status_tv_isrepeater; + private TextView router_status_tv_product; + private TextView router_status_tv_hardwareversion; + private TextView router_status_tv_firmwareversion; + private TextView router_status_tv_ssid; + private TextView router_status_tv_encrypt; + private TextView router_status_tv_wiremac; + private TextView router_status_tv_wirelessmac; + private TextView router_status_tv_partition_number; + private TextView router_status_tv_partition_type; + private TextView router_status_tv_disktotalsize; + private TextView router_status_tv_disklastsize; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 0: + Toast.makeText(RouterStatus.this,"抱歉,与微路由通信超时",Toast.LENGTH_SHORT).show(); + break; + case 1: + router_status_tv_devices.setText(msg.obj.toString() + "台"); + break; + case 2: + router_status_tv_hardwareversion.setText(msg.obj.toString()); + break; + case 3: + router_status_tv_firmwareversion.setText(msg.obj.toString()); + break; + case 4: + router_status_tv_product.setText(msg.obj.toString()); + break; + case 5: + router_status_tv_ssid.setText(msg.obj.toString()); + break; + case 6: + router_status_tv_encrypt.setText(msg.obj.toString()); + break; + case 7: + router_status_tv_wirelessmac.setText(msg.obj.toString()); + break; + case 8: + router_status_tv_wiremac.setText(msg.obj.toString()); + break; + case 9: + List list = new ArrayList<>(); + list = (List) msg.obj; + + router_status_tv_partition_number.setText(list.get(0)); + router_status_tv_partition_type.setText(list.get(1)); + router_status_tv_disktotalsize.setText(list.get(2)); + router_status_tv_disklastsize.setText(list.get(3)); + break; + case 10: + router_status_tv_mode.setText(msg.obj.toString()); + break; + case 11: + router_status_tv_ip.setText(msg.obj.toString()); + break; + case 12: + router_status_tv_subnetmask.setText(msg.obj.toString()); + break; + case 13: + router_status_tv_gateway.setText(msg.obj.toString()); + break; + case 14: + router_status_tv_dns.setText(msg.obj.toString()); + break; + case 15: + router_status_tv_isrepeater.setText(msg.obj.toString()); + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_router_status); + + initView(); + + //获取连接终端 + sendMsgToRouter(0,Consts.ROUTER_ON_DEVICES); + //获取硬件版本、固件版本 + sendMsgToRouter(1,Consts.ROUTER_GET_VERSION); + //获取硬盘、WIFI、MAC信息 + sendMsgToRouter(2,Consts.ROUTER_GET_INFOS); + //获取路由信息 + sendMsgToRouter(3,Consts.ROUTER_GET_INFO); + + } + + private void initView(){ + router_status_tb = findViewById(R.id.router_status_tb); + router_status_tb.setNavigationIcon(R.mipmap.back); + router_status_tb.setTitle("路由器状态"); + + router_status_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + router_status_tv_devices = findViewById(R.id.router_status_tv_devices); + router_status_tv_mode = findViewById(R.id.router_status_tv_mode); + router_status_tv_ip = findViewById(R.id.router_status_tv_ip); + router_status_tv_subnetmask = findViewById(R.id.router_status_tv_subnetmask); + router_status_tv_gateway = findViewById(R.id.router_status_tv_gateway); + router_status_tv_dns = findViewById(R.id.router_status_tv_dns); + router_status_tv_isrepeater = findViewById(R.id.router_status_tv_isrepeater); + router_status_tv_product = findViewById(R.id.router_status_tv_product); + router_status_tv_hardwareversion = findViewById(R.id.router_status_tv_hardwareversion); + router_status_tv_firmwareversion = findViewById(R.id.router_status_tv_firmwareversion); + router_status_tv_ssid = findViewById(R.id.router_status_tv_ssid); + router_status_tv_encrypt = findViewById(R.id.router_status_tv_encrypt); + router_status_tv_wiremac = findViewById(R.id.router_status_tv_wiremac); + router_status_tv_wirelessmac = findViewById(R.id.router_status_tv_wirelessmac); + router_status_tv_partition_number = findViewById(R.id.router_status_tv_partition_number); + router_status_tv_partition_type = findViewById(R.id.router_status_tv_partition_type); + router_status_tv_disktotalsize = findViewById(R.id.router_status_tv_disktotalsize); + router_status_tv_disklastsize = findViewById(R.id.router_status_tv_disklastsize); + } + + private void sendMsgToRouter(final int flag,final String msg){ + + new Thread(new Runnable() { + @Override + public void run() { + + Socket socket = new Socket(); + InetSocketAddress inetSocketAddress = new InetSocketAddress("192.168.80.1",7888); + try { + socket.connect(inetSocketAddress,5000); + + OutputStream os = socket.getOutputStream(); + PrintWriter pw = new PrintWriter(os); + pw.write(msg); + pw.flush(); + + socket.shutdownOutput(); + + InputStream is = socket.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + + String infos = ""; + String info = null; + + while((info = br.readLine()) != null){ + infos = infos + info; + } + + //调用XML解析器 + if(flag == 2){ + //换行符丢失,需要对字符串格式化,否则XML解析失败 + infos = infos.replace("PARTITIONindex","PARTITION index"); + } + + parseXMLWithPull(flag,infos); + + socket.close(); + os.close(); + pw.close(); + is.close(); + isr.close(); + br.close(); + } catch (IOException e) { + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + } + }).start(); + } + + private void parseXMLWithPull(int flag,String xmlData){ + try { + XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); + XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); + xmlPullParser.setInput(new StringReader(xmlData)); + + int eventType = xmlPullParser.getEventType(); + + String devicesNum = null; + String routerMode = null; + String routerIP = null; + String routerSubnetMask = null; + String routerGateway = null; + String routerDNS = null; + String routerIsRepeater = null; + String product = null; + String hardwareV = null; + String firmwareV = null; + String apSSID = null; + String apEncrypt = null; + String wireMac = null; + String wirelessMac = null; + String diskPartition = null; + String diskPType = null; + String diskTotalSize = null; + String diskLastSize = null; + + while(eventType != XmlPullParser.END_DOCUMENT){ + switch (eventType){ + case XmlPullParser.START_TAG: + //开始解析某个节点 + String nodeName = xmlPullParser.getName(); + + switch (flag){ + case 0: + if("DEVICE_NUM".equals(nodeName)){ + devicesNum = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 1; + msg.obj = devicesNum; + handler.sendMessage(msg); + } + break; + case 1: + if("CUR_VER".equals(nodeName)){ + hardwareV = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 2; + msg.obj = hardwareV; + handler.sendMessage(msg); + } + if("FW".equals(nodeName)){ + firmwareV = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 3; + msg.obj = firmwareV; + handler.sendMessage(msg); + } + if("NAME".equals(nodeName)){ + product = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 4; + msg.obj = product; + handler.sendMessage(msg); + } + break; + case 2: + if("SSID".equals(nodeName)){ + apSSID = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 5; + msg.obj = apSSID; + handler.sendMessage(msg); + } + if("ENCRYPTION".equals(nodeName)){ + apEncrypt = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 6; + msg.obj = apEncrypt; + handler.sendMessage(msg); + } + if("ETH0_MAC".equals(nodeName)){ + wirelessMac = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 7; + msg.obj = wirelessMac; + handler.sendMessage(msg); + } + if("WAN0_MAC".equals(nodeName)){ + wireMac = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 8; + msg.obj = wireMac; + handler.sendMessage(msg); + } + if("PARTITION".equals(nodeName)){ + diskPartition = xmlPullParser.getAttributeValue(0); + diskPType = xmlPullParser.getAttributeValue(1); + diskTotalSize = xmlPullParser.getAttributeValue(2); + diskLastSize = xmlPullParser.getAttributeValue(3); + + List list = new ArrayList<>(); + list.add(diskPartition); + list.add(diskPType); + list.add(diskTotalSize); + list.add(diskLastSize); + + Message msg = new Message(); + msg.what = 9; + msg.obj = list; + handler.sendMessage(msg); + } + break; + case 3: + if("ROUTE_INFO".equals(nodeName)){ + routerMode = xmlPullParser.getAttributeValue(0); + + Message msg = new Message(); + msg.what = 10; + msg.obj = routerMode; + handler.sendMessage(msg); + } + if("IP".equals(nodeName)){ + routerIP = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 11; + msg.obj = routerIP; + handler.sendMessage(msg); + } + if("MASK".equals(nodeName)){ + routerSubnetMask = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 12; + msg.obj = routerSubnetMask; + handler.sendMessage(msg); + } + if("GATEWAY".equals(nodeName)){ + routerGateway = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 13; + msg.obj = routerGateway; + handler.sendMessage(msg); + } + if("DNS".equals(nodeName)){ + routerDNS = xmlPullParser.nextText(); + + Message msg = new Message(); + msg.what = 14; + msg.obj = routerDNS; + handler.sendMessage(msg); + } + if("IS_ENABLE".equals(nodeName)){ + if(xmlPullParser.nextText().equals("1")){ + //中继已开启 + routerIsRepeater = "已开启"; + }else{ + routerIsRepeater = "无"; + } + + Message msg = new Message(); + msg.what = 15; + msg.obj = routerIsRepeater; + handler.sendMessage(msg); + } + break; + } + break; + case XmlPullParser.END_TAG: + //完成解析某个节点 + break; + default: + break; + } + eventType = xmlPullParser.next(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/SettingAppActivity.java b/app/src/main/java/com/example/wgjrouter/SettingAppActivity.java new file mode 100644 index 0000000..19c6f54 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/SettingAppActivity.java @@ -0,0 +1,46 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; + +public class SettingAppActivity extends AppCompatActivity { + private Toolbar setting_app_toolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting_app); + + SettingAppFragment spf = new SettingAppFragment(); + getFragmentManager().beginTransaction() + .add(R.id.selfstyle_fg,spf) + .commit(); + + initView(); + } + + private void initView(){ + setting_app_toolbar = findViewById(R.id.setting_app_toolbar); + setting_app_toolbar.setTitle("个性化设置"); + setting_app_toolbar.setNavigationIcon(R.mipmap.back); + + setting_app_toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/SettingAppFragment.java b/app/src/main/java/com/example/wgjrouter/SettingAppFragment.java new file mode 100644 index 0000000..2866558 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/SettingAppFragment.java @@ -0,0 +1,73 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.util.Log; + +public class SettingAppFragment extends PreferenceFragment { + private CheckBoxPreference protect_ear_volume; + private EditTextPreference ideal_ear_volume; + private EditTextPreference max_concurrent_task; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.selfstyle_setting_preference); + + protect_ear_volume = (CheckBoxPreference) findPreference("protect_ear_volume"); + ideal_ear_volume = (EditTextPreference) findPreference("ideal_ear_volume"); + max_concurrent_task = (EditTextPreference) findPreference("max_concurrent_task"); + + if(protect_ear_volume.isChecked()){ + ideal_ear_volume.setEnabled(true); + }else{ + ideal_ear_volume.setEnabled(false); + } + + protect_ear_volume.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if(newValue.toString().equals("true")){ + ideal_ear_volume.setEnabled(true); + }else{ + ideal_ear_volume.setEnabled(false); + } + return true; + } + }); + + ideal_ear_volume.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if(newValue.toString().equals("")){ + return false; + } + + if(Integer.parseInt(newValue.toString()) > 100){ + return false; + } + return true; + } + }); + + max_concurrent_task.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if(newValue.toString().equals("")){ + return false; + } + + if(Integer.parseInt(newValue.toString()) <= 0){ + preference.setDefaultValue(1); + }else if(Integer.parseInt(newValue.toString()) > 10){ + preference.setDefaultValue(10); + } + return true; + } + }); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/SettingHollRouterActivity.java b/app/src/main/java/com/example/wgjrouter/SettingHollRouterActivity.java new file mode 100644 index 0000000..f17d11f --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/SettingHollRouterActivity.java @@ -0,0 +1,44 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; + +public class SettingHollRouterActivity extends AppCompatActivity { + + private Toolbar setting_toolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_hollrouter_setting); + + SettingHollRouterFragment settingHollRouterFragment = new SettingHollRouterFragment(); + getFragmentManager().beginTransaction() + .add(R.id.setting_hollrouter_fg, settingHollRouterFragment) + .commit(); + + setting_toolbar = findViewById(R.id.hollrouter_setting_toolbar); + + setting_toolbar.setTitle("汇尔路由器"); + setting_toolbar.setNavigationIcon(R.mipmap.back); + setting_toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/SettingHollRouterFragment.java b/app/src/main/java/com/example/wgjrouter/SettingHollRouterFragment.java new file mode 100644 index 0000000..3687631 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/SettingHollRouterFragment.java @@ -0,0 +1,254 @@ +package com.example.wgjrouter; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.util.Log; +import android.widget.Toast; + +import com.example.consts.Consts; + +import org.apache.commons.net.telnet.TelnetClient; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.concurrent.TimeUnit; + +public class SettingHollRouterFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener { + + private Preference wifi_setwifi; + private Preference wifi_repeater; + private Preference router_initweb; + private Preference router_devices; + private Preference router_state; + private Preference router_shutdown; + private Preference router_restore; + + private TelnetClient telnetClient = null; + private InputStream is = null; + private PrintStream ps = null; + private char prompt = '$'; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.hollrouter_setting_preference); + + wifi_setwifi = findPreference("wifi_setwifi"); + wifi_repeater = findPreference("wifi_repeater"); + router_initweb = findPreference("router_initwan"); + router_devices = findPreference("router_devices"); + router_state = findPreference("router_state"); + router_shutdown = findPreference("router_shutdown"); + router_restore = findPreference("router_restore"); + + wifi_setwifi.setOnPreferenceClickListener(this); + wifi_repeater.setOnPreferenceClickListener(this); + router_initweb.setOnPreferenceClickListener(this); + router_devices.setOnPreferenceClickListener(this); + router_state.setOnPreferenceClickListener(this); + router_shutdown.setOnPreferenceClickListener(this); + router_restore.setOnPreferenceClickListener(this); + } + + @Override + public boolean onPreferenceClick(Preference preference) { + switch (preference.getKey()){ + case "wifi_setwifi": + Intent routerSetPwd = new Intent(getActivity(),RouterSetWiFiPwd.class); + startActivity(routerSetPwd); + break; + case "wifi_repeater": + Intent routerSetRepeater = new Intent(getActivity(),RouterSetRepeater.class); + startActivity(routerSetRepeater); + break; + case "router_initwan": +// Intent routerSetWan = new Intent(getActivity(),RouterSetWan.class); +// startActivity(routerSetWan); + Toast.makeText(getActivity(),"暂不可用",Toast.LENGTH_SHORT).show(); + break; + case "router_devices": + Intent routerDevices = new Intent(getActivity(),RouterDevices.class); + startActivity(routerDevices); + break; + case "router_state": + Intent routerState = new Intent(getActivity(),RouterStatus.class); + startActivity(routerState); + break; + case "router_shutdown": + //警告提示框 + AlertDialog ad = null; + AlertDialog.Builder adb = new AlertDialog.Builder(getActivity()); + adb.setTitle("微路由关机提醒"); + adb.setMessage("关机后无法远程开机,是否关机?"); + adb.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + connectRouter(0,"root","holl0311"); + + Toast.makeText(getActivity(),"拜了个拜",Toast.LENGTH_SHORT).show(); + } + }); + adb.setNegativeButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + ad = adb.create(); + ad.show(); + ad.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.GRAY); + ad.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED); + break; + case "router_restore": + //警告提示框 + AlertDialog adr = null; + AlertDialog.Builder adbr = new AlertDialog.Builder(getActivity()); + adbr.setTitle("微路由初始化提醒"); + adbr.setMessage("初始化后将清空微路由的所有配置"); + adbr.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + connectRouter(1,"root","holl0311"); + + Toast.makeText(getActivity(),"初始化完成,请重连热点",Toast.LENGTH_SHORT).show(); + } + }); + adbr.setNegativeButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + adr = adbr.create(); + adr.show(); + adr.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.GRAY); + adr.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED); + break; + } + return false; + } + + //连接到路由器 + private void connectRouter(final int flag, final String user, final String password){ + //操作路由器 + new Thread(new Runnable() { + @Override + public void run() { + telnetClient = new TelnetClient(); + try { + telnetClient.connect("192.168.80.1",23); + + is = telnetClient.getInputStream(); + ps = new PrintStream(telnetClient.getOutputStream()); + + prompt = user.equals("root") ? '#' : '$'; + + //登录 + telnetLogin(telnetClient,user,password); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + switch (flag){ + case 0: + //关机 + sendCodeToRouter(telnetClient,Consts.SHUTDOWN_ROUTER_BYSH); + break; + case 1: + //恢复出厂设置 + sendCodeToRouter(telnetClient,Consts.RESTORE_ROUTER_BYSH); + break; + } + + //退出 + ps.println("exit\r\n"); + ps.flush(); + disConnection(); + }catch (Exception e) { + e.printStackTrace(); + } + } + }).start(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + disConnection(); + } + + //Telnet登录到微路由 + private void telnetLogin(TelnetClient telnetClient,String user,String password){ + read(telnetClient,"Holl login:"); + write(telnetClient,user); + read(telnetClient,"Password:"); + write(telnetClient,password); + read(telnetClient,prompt + " "); + write(telnetClient,"cd /"); + read(telnetClient,prompt + " "); + } + + private void sendCodeToRouter(TelnetClient telnetClient,String code){ + write(telnetClient,code); + read(telnetClient,prompt + " "); + } + + private String read(TelnetClient telnetClient,String code){ + char lastChar = code.charAt(code.length() - 1); + StringBuffer stringBuffer = new StringBuffer(); + try { + char ch = (char) is.read(); + + while(true){ + stringBuffer.append(ch); + if(ch == lastChar){ + if(stringBuffer.toString().endsWith(code)){ + Log.d("zouguo",stringBuffer.toString()); + return stringBuffer.toString(); + } + } + ch = (char) is.read(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private void write(TelnetClient telnetClient,String code){ + try { + ps.println(code); + ps.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void disConnection(){ + try { + if(telnetClient != null) + telnetClient.disconnect(); + if(is != null) + is.close(); + if(ps != null) + ps.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/com/example/wgjrouter/SettingSuperRouterActivity.java b/app/src/main/java/com/example/wgjrouter/SettingSuperRouterActivity.java new file mode 100644 index 0000000..05be0a5 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/SettingSuperRouterActivity.java @@ -0,0 +1,43 @@ +package com.example.wgjrouter; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; + +public class SettingSuperRouterActivity extends AppCompatActivity { + private Toolbar setting_toolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_superrouter_setting); + + SettingSuperRouterFragment ssrf = new SettingSuperRouterFragment(); + getFragmentManager().beginTransaction() + .add(R.id.setting_superrouter_fg,ssrf) + .commit(); + + setting_toolbar = findViewById(R.id.superrouter_setting_toolbar); + + setting_toolbar.setTitle("智能路由器"); + setting_toolbar.setNavigationIcon(R.mipmap.back); + setting_toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/SettingSuperRouterFragment.java b/app/src/main/java/com/example/wgjrouter/SettingSuperRouterFragment.java new file mode 100644 index 0000000..9838246 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/SettingSuperRouterFragment.java @@ -0,0 +1,224 @@ +package com.example.wgjrouter; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Toast; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class SettingSuperRouterFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener { + private ProgressBar setting_superrouter_pb; + + private EditTextPreference gateway_config; + private EditTextPreference penetration_config; + private EditTextPreference link_diskdir_config; + private CheckBoxPreference penetration_https_config; + private EditTextPreference aria2_dir_config; + + private Preference remote_admin_watch; + private Preference remote_file_watch; + private Preference remote_download; + private Preference local_download; + private Preference get_bttrackerlist; + + private Handler handler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + setting_superrouter_pb.setVisibility(View.GONE); + } + }); + + switch (msg.what){ + case 0: + Toast.makeText(getActivity(),"抱歉,获取Aria2-BT服务器地址失败",Toast.LENGTH_SHORT).show(); + break; + case 128: + String formatList = msg.obj.toString().replace("\n\n",","); + formatList = formatList.substring(0,formatList.length() - 1); + + ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); + ClipData cd = ClipData.newPlainText(null,formatList); + cm.setPrimaryClip(cd); + + Toast.makeText(getActivity(),"已复制到剪贴板",Toast.LENGTH_SHORT).show(); + break; + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.superrouter_setting_preference); + + setting_superrouter_pb = getActivity().findViewById(R.id.setting_superrouter_pb); + + gateway_config = (EditTextPreference) findPreference("gateway_config"); + penetration_config = (EditTextPreference) findPreference("penetration_config"); + link_diskdir_config = (EditTextPreference) findPreference("link_diskdir_config"); + penetration_https_config = (CheckBoxPreference) findPreference("penetration_https_config"); + aria2_dir_config = (EditTextPreference) findPreference("aria2_dir_config"); + + remote_admin_watch = findPreference("remote_admin_watch"); + remote_file_watch = findPreference("remote_file_watch"); + local_download = findPreference("local_download"); + remote_download = findPreference("remote_download"); + get_bttrackerlist = findPreference("get_bttrackerlist"); + + remote_admin_watch.setOnPreferenceClickListener(this); + remote_file_watch.setOnPreferenceClickListener(this); + local_download.setOnPreferenceClickListener(this); + remote_download.setOnPreferenceClickListener(this); + get_bttrackerlist.setOnPreferenceClickListener(this); + } + + @Override + public boolean onPreferenceClick(Preference preference) { + switch (preference.getKey()){ + case "remote_admin_watch": + String localOutUrl = penetration_config.getText(); + if(localOutUrl != null && localOutUrl != ""){ + if(!localOutUrl.startsWith("http")){ + if(penetration_https_config != null && penetration_https_config.isChecked()){ + localOutUrl = "https://" + localOutUrl + "/"; + }else{ + localOutUrl = "http://" + localOutUrl + "/"; + } + } + Intent goRemoteAdmin = new Intent(getActivity(),WebShow.class); + goRemoteAdmin.putExtra("web_showtitle",false); + goRemoteAdmin.putExtra("web_title","路由器Web管理"); + goRemoteAdmin.putExtra("web_url",localOutUrl); + startActivity(goRemoteAdmin); + }else{ + Toast.makeText(getActivity(),"内网穿透未配置",Toast.LENGTH_SHORT).show(); + } + break; + case "remote_file_watch": + String fileUrl = penetration_config.getText(); + String linkDir = link_diskdir_config.getText(); + if(fileUrl != null && fileUrl != "" && linkDir != null && linkDir != ""){ + if(!fileUrl.startsWith("http")){ + if(penetration_https_config != null && penetration_https_config.isChecked()){ + fileUrl = "https://" + fileUrl; + }else{ + fileUrl = "http://" + fileUrl; + } + } + + Intent goFileAdmin = new Intent(getActivity(),RemoteFileActivity.class); + goFileAdmin.putExtra("web_host",fileUrl); + goFileAdmin.putExtra("web_url",fileUrl + "/" + linkDir + "/"); + startActivity(goFileAdmin); + }else{ + Toast.makeText(getActivity(),"内网穿透、远程根目录未配置",Toast.LENGTH_SHORT).show(); + } + break; + case "local_download": + String gateway = gateway_config.getText(); + String aria2Dir = aria2_dir_config.getText(); + + if(gateway != null && gateway != ""){ + if(!gateway.startsWith("http")){ + if(penetration_https_config != null && penetration_https_config.isChecked()){ + gateway = "https://" + gateway + "/"; + }else{ + gateway = "http://" + gateway + "/"; + } + } + + if(aria2Dir != null && aria2Dir != ""){ + Intent goAria2LocalWeb = new Intent(getActivity(),WebShow.class); + goAria2LocalWeb.putExtra("web_showtitle",false); + goAria2LocalWeb.putExtra("web_showback",true); + goAria2LocalWeb.putExtra("web_title","内网AriaNg下载器"); + goAria2LocalWeb.putExtra("web_url",gateway + aria2Dir); + startActivity(goAria2LocalWeb); + }else{ + Toast.makeText(getActivity(),"Aria2 Web目录未配置",Toast.LENGTH_SHORT).show(); + } + }else{ + Toast.makeText(getActivity(),"网关未配置",Toast.LENGTH_SHORT).show(); + } + break; + case "remote_download": + String pentUrl = penetration_config.getText(); + String aria2Dirr = aria2_dir_config.getText(); + + if(pentUrl != null && pentUrl != ""){ + if(!pentUrl.startsWith("http")){ + if(penetration_https_config != null && penetration_https_config.isChecked()){ + pentUrl = "https://" + pentUrl + "/"; + }else{ + pentUrl = "http://" + pentUrl + "/"; + } + } + + if(aria2Dirr != null && aria2Dirr != ""){ + Intent goAria2RemoteWeb = new Intent(getActivity(),WebShow.class); + goAria2RemoteWeb.putExtra("web_showtitle",false); + goAria2RemoteWeb.putExtra("web_showback",true); + goAria2RemoteWeb.putExtra("web_title","外网AriaNg下载器"); + goAria2RemoteWeb.putExtra("web_url",pentUrl + aria2Dirr); + startActivity(goAria2RemoteWeb); + }else{ + Toast.makeText(getActivity(),"Aria2 Web目录名未配置",Toast.LENGTH_SHORT).show(); + } + }else{ + Toast.makeText(getActivity(),"内网穿透未配置",Toast.LENGTH_SHORT).show(); + } + break; + case "get_bttrackerlist": + setting_superrouter_pb.setVisibility(View.VISIBLE); + + OkHttpClient ohc = new OkHttpClient(); + Request req = new Request.Builder().url("https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt") + .method("GET",null) + .build(); + Call call = ohc.newCall(req); + call.enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + Message msg = new Message(); + msg.what = 0; + handler.sendMessage(msg); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + Message msg = new Message(); + msg.what = 128; + msg.obj = response.body().string(); + handler.sendMessage(msg); + } + }); + break; + } + return false; + } +} diff --git a/app/src/main/java/com/example/wgjrouter/VideoPlayVTM.java b/app/src/main/java/com/example/wgjrouter/VideoPlayVTM.java new file mode 100644 index 0000000..42abfec --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/VideoPlayVTM.java @@ -0,0 +1,1101 @@ +package com.example.wgjrouter; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.drawable.ColorDrawable; +import android.media.AudioManager; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.SeekBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.database.LiveVideoList; +import com.example.utils.MyPhoneUtils; +import com.example.utils.MyVideoUtils; + +import org.litepal.LitePal; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import io.vov.vitamio.MediaPlayer; +import io.vov.vitamio.Vitamio; +import io.vov.vitamio.widget.VideoView; + +public class VideoPlayVTM extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, View.OnClickListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnInfoListener { + + private FrameLayout vtmFLRoot; + private VideoView videoView; + + private FrameLayout vtmFLTop; + private ImageView vtmIVBack; + private TextView vtmTVTitle; + private TextView vtmTVSysTime; + private ImageView vtmIVSet; + private ImageView vtmIVFresh; + private ImageView vtmIVCollect; + + private FrameLayout vtmFLCenter; + private ImageView vtmIVBackward; + private ImageView vtmIVForward; + + private FrameLayout vtmFLBottom; + private SeekBar vtmSBar; + private ImageView vtmIVPlay; + private RelativeLayout lengthView; + private TextView vtmTVVideoProgress; + private TextView vtmTVVideoLength; + private TextView vtmTVNetRate; + private ImageView vtmIVListVideo; + + private ProgressBar vtmPBLoading; + + private TextView videoplay_layout_origin; + private TextView videoplay_layout_scale; + private TextView videoplay_layout_stretch; + private TextView videoplay_layout_zoom; + private TextView videoplay_quality_low; + private TextView videoplay_quality_medium; + private TextView videoplay_quality_high; + private TextView videoplay_speed_0_5; + private TextView videoplay_speed_0_8; + private TextView videoplay_speed_1_0; + private TextView videoplay_speed_1_2_5; + private TextView videoplay_speed_1_5; + private TextView videoplay_speed_2_0; + + //单击、双击判定 + int clickNum = 0; + boolean isPlay = false; + //标记路由文件、直播文件 + int videoType = 0; + private String videoTit = null; + private long TOUCH_SCREEN_TIME = 0; + private static int SHOW_OPTION_DELAY = 6000; + private long videoDuration = 0; + + //当前视频源地址 + private String curVideoUrl = ""; + private List nameList = new ArrayList<>(); + private List urlsList = new ArrayList<>(); + private int playItemPosition; + + private ArrayList srcList = new ArrayList<>(); + private ArrayList vTitleList = new ArrayList<>(); + + private boolean isCollected = false; + private PopupWindow pwVideoList; + + private SharedPreferences sp; + + private MediaPlayer mediaPlayer = null; + private AudioManager audioManager; + private int curVolume = 0; + private int maxVolume = 0; + //视频属性调整标记 + private int layoutFlag = 1; + private int qualityFlag = 1; + private int speedFlag = 2; + + private Handler clickHander = new Handler(); + private Handler hideHandler = new Handler(Looper.getMainLooper()); + private Handler progressTimeHandler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what){ + case 12138: + long currentPositionMesc = videoView.getCurrentPosition(); + vtmTVVideoProgress.setText(MyVideoUtils.getInstance().formatVideoDuration(currentPositionMesc)); + vtmSBar.setProgress((int)currentPositionMesc); + progressTimeHandler.sendEmptyMessageDelayed(12138,1000); + break; + default: + break; + } + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //初始化维他命 + Vitamio.isInitialized(VideoPlayVTM.this); + setContentView(R.layout.activity_videoplay); + + //初始化视图、配置 + initView(); + + Intent getVideoUrl = getIntent(); + //0--路由器;1--直播 + videoType = getVideoUrl.getIntExtra("videoType",0); + curVideoUrl = getVideoUrl.getStringExtra("videoUrl"); + videoTit = getVideoUrl.getStringExtra("videoTitle"); + playItemPosition = getVideoUrl.getIntExtra("videoPosition",0); + + Log.d("zouguo","videoType:" + videoType); + Log.d("zouguo","curVideoUrl:" + curVideoUrl); + Log.d("zouguo","videoTit:" + videoTit); + Log.d("zouguo","playItemPosition:" + playItemPosition); + + switch (videoType){ + case 0: + //路由器下视频 + //接收路由器硬盘目录下的视频列表 + srcList = getVideoUrl.getStringArrayListExtra("videoUrlList"); + vTitleList = getVideoUrl.getStringArrayListExtra("videoTitleList"); + + vtmFLCenter.setVisibility(View.VISIBLE); + vtmIVFresh.setVisibility(View.GONE); + vtmIVCollect.setVisibility(View.GONE); + break; + case 1: + //隐藏直播视频下不必要的控制组件 + vtmIVSet.setVisibility(View.GONE); + vtmSBar.setVisibility(View.GONE); + lengthView.setVisibility(View.GONE); + vtmFLCenter.setVisibility(View.GONE); + + //加载播放源 + new Thread(new Runnable() { + @Override + public void run() { + //收藏状态 + LiveVideoList lvlc = LitePal.where("liveName = ? and liveUrls = ?",videoTit,curVideoUrl).findFirst(LiveVideoList.class); + + if(lvlc.getIsCollect() == 1){ + isCollected = true; + } + + List allVideoList = LitePal.findAll(LiveVideoList.class); + + for(LiveVideoList lvl : allVideoList){ + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + } + }).start(); + break; + case 2: + //隐藏直播视频下不必要的控制组件 + vtmIVSet.setVisibility(View.GONE); + vtmSBar.setVisibility(View.GONE); + lengthView.setVisibility(View.GONE); + vtmFLCenter.setVisibility(View.GONE); + + //加载播放源 + new Thread(new Runnable() { + @Override + public void run() { + //收藏状态 + LiveVideoList lvlc = LitePal.where("liveName = ? and liveUrls = ?",videoTit,curVideoUrl).findFirst(LiveVideoList.class); + + if(lvlc.getIsCollect() == 1){ + isCollected = true; + } + + List allVideoList = LitePal.where("isplay = ?","1").find(LiveVideoList.class); + + for(LiveVideoList lvl : allVideoList){ + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + } + }).start(); + break; + case 3: + //隐藏直播视频下不必要的控制组件 + vtmIVSet.setVisibility(View.GONE); + vtmSBar.setVisibility(View.GONE); + lengthView.setVisibility(View.GONE); + vtmFLCenter.setVisibility(View.GONE); + + //加载播放源 + new Thread(new Runnable() { + @Override + public void run() { + //收藏状态 + LiveVideoList lvlc = LitePal.where("liveName = ? and liveUrls = ?",videoTit,curVideoUrl).findFirst(LiveVideoList.class); + + if(lvlc.getIsCollect() == 1){ + isCollected = true; + } + + List allVideoList = LitePal.where("iscollect = ?","1").find(LiveVideoList.class); + for(LiveVideoList lvl : allVideoList){ + nameList.add(lvl.getLiveName()); + urlsList.add(lvl.getLiveUrls()); + } + } + }).start(); + break; + } + + initSP(); + + showControlView(); + + playVideo(curVideoUrl); + } + + private void showControlView(){ + if(isCollected){ + //收藏状态 + vtmIVCollect.setImageResource(R.mipmap.collected); + } + + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm"); + vtmTVSysTime.setText(sdf.format(calendar.getTime())); + + vtmFLTop.setVisibility(View.VISIBLE); + if(videoType == 0) { + //路由文件 + vtmFLCenter.setVisibility(View.VISIBLE); + vtmFLBottom.setVisibility(View.VISIBLE); + }else{ + vtmFLCenter.setVisibility(View.GONE); + vtmIVSet.setVisibility(View.GONE); + vtmIVFresh.setVisibility(View.VISIBLE); + vtmIVCollect.setVisibility(View.VISIBLE); + vtmFLBottom.setVisibility(View.VISIBLE); + vtmSBar.setVisibility(View.GONE); + lengthView.setVisibility(View.GONE); + } + } + + private void hideControlView(){ + vtmFLTop.setVisibility(View.GONE); + vtmFLCenter.setVisibility(View.GONE); + vtmFLBottom.setVisibility(View.GONE); + } + + private void initView(){ + vtmFLRoot = findViewById(R.id.vtmFLRoot); + + videoView = findViewById(R.id.vtmVideoView); + + vtmPBLoading = findViewById(R.id.vtmPBLoading); + + vtmFLTop = findViewById(R.id.vtmFLTop); + vtmIVBack = findViewById(R.id.vtmIVBack); + vtmTVTitle = findViewById(R.id.vtmTVTitle); + vtmTVSysTime = findViewById(R.id.vtmTVSysTime); + vtmIVSet = findViewById(R.id.vtmIVSet); + vtmIVFresh = findViewById(R.id.vtmIVFresh); + vtmIVCollect = findViewById(R.id.vtmIVCollect); + + vtmFLCenter = findViewById(R.id.vtmFLCenter); + vtmIVBackward = findViewById(R.id.vtmIVBackward); + vtmIVForward = findViewById(R.id.vtmIVForward); + + vtmFLBottom = findViewById(R.id.vtmFLBottom); + vtmSBar = findViewById(R.id.vtmSBar); + vtmIVPlay = findViewById(R.id.vtmIVPlay); + lengthView = findViewById(R.id.lengthView); + vtmTVVideoProgress = findViewById(R.id.vtmTVVideoProgress); + vtmTVVideoLength = findViewById(R.id.vtmTVVideoLength); + vtmTVNetRate = findViewById(R.id.vtmTVNetRate); + vtmIVListVideo = findViewById(R.id.vtmIVListVideo); + + vtmIVSet.setOnClickListener(this); + vtmIVFresh.setOnClickListener(this); + vtmIVCollect.setOnClickListener(this); + vtmFLRoot.setOnClickListener(this); + vtmIVBack.setOnClickListener(this); + vtmIVPlay.setOnClickListener(this); + vtmIVListVideo.setOnClickListener(this); + vtmIVBackward.setOnClickListener(this); + vtmIVForward.setOnClickListener(this); + + audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); + maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + + vtmSBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + Log.d("zouguo","Touch:"); + TOUCH_SCREEN_TIME = System.currentTimeMillis(); + videoView.seekTo(seekBar.getProgress()); + } + }); + } + + private void initSP(){ + //初始化一些参数 + sp = getSharedPreferences("app_setting",MODE_PRIVATE); + } + + private void playVideo(String videoUrl){ + //检查网络类型 + if(MyPhoneUtils.getInstance(VideoPlayVTM.this).checkNetworkType() == 1){ + //流量 + Toast.makeText(VideoPlayVTM.this,"当前处于流量环境,请注意流量消耗",Toast.LENGTH_LONG).show(); + } + + if(videoTit != null){ + vtmTVTitle.setText(videoTit); + } + + if(videoUrl != ""){ + videoView.setVideoPath(videoUrl); + videoView.requestFocus(); + + videoView.setOnPreparedListener(this); + videoView.setOnErrorListener(this); + videoView.setOnInfoListener(this); + videoView.setOnBufferingUpdateListener(this); + videoView.setOnCompletionListener(this); + + //设置暂停按钮 + vtmIVPlay.setImageResource(R.mipmap.pausevideo); + isPlay = true; + }else{ + Toast.makeText(this,"出错:视频地址异常",Toast.LENGTH_SHORT).show(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch (keyCode){ + case KeyEvent.KEYCODE_BACK: + if(event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0){ + if(pwVideoList != null && pwVideoList.isShowing()){ + pwVideoList.dismiss(); + return true; + } + + //记录当前播放位置 + videoView.stopPlayback(); + if(videoType == 0) + //微路由文件 + sp.edit().putLong("vitamio_play_position",videoView.getCurrentPosition()).commit(); + + Intent data = new Intent(); + data.putExtra("videoPosition",playItemPosition); + setResult(RESULT_OK,data); + finish(); + } + break; + case KeyEvent.KEYCODE_VOLUME_UP: + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(VideoPlayVTM.this); + boolean setLimitVol = sp.getBoolean("protect_ear_volume",false); + + curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + 1; + + if(setLimitVol){ + //设置了音量保护 + int limitVol = Integer.parseInt(sp.getString("ideal_ear_volume","100")); + + limitVol = Integer.parseInt(String.valueOf(Math.round(limitVol / 100.0 * maxVolume))); + + if(curVolume > limitVol){ + Toast.makeText(VideoPlayVTM.this,"当前开启了音量保护,无法继续",Toast.LENGTH_SHORT).show(); + return true; + } + }else{ + if(curVolume > maxVolume){ + return true; + } + } + + audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,AudioManager.ADJUST_RAISE,AudioManager.FLAG_SHOW_UI); + break; + case KeyEvent.KEYCODE_VOLUME_DOWN: + if(curVolume != -1){ + curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - 1; + if(curVolume < 0){ + curVolume = 0; + } + + audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,AudioManager.ADJUST_LOWER,AudioManager.FLAG_SHOW_UI); + } + break; + } + return true; + } + + @Override + public void onPrepared(MediaPlayer mediaPlayer) { + if(videoType == 0) { + //微路由文件 + String tlength = MyVideoUtils.getInstance().formatVideoDuration(videoView.getDuration()); + + vtmTVVideoLength.setText(tlength); + videoDuration = videoView.getDuration(); + vtmSBar.setMax((int)videoDuration); + } + + videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0); + this.mediaPlayer = mediaPlayer; + mediaPlayer.setPlaybackSpeed(1.0f); + mediaPlayer.start(); + + vtmIVPlay.setImageResource(R.mipmap.pausevideo); + isPlay = true; + + //MINI_KIND: 512 x 384,MICRO_KIND: 96 x 96 + //Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(VideoPlayVTM.this,curVideoUrl, MediaStore.Video.Thumbnails.MINI_KIND); + } + + @Override + public boolean onError(MediaPlayer mediaPlayer, int what, int extra) { + Toast.makeText(this,"视频链接无效",Toast.LENGTH_SHORT).show(); + + vtmFLTop.setVisibility(View.VISIBLE); + vtmFLBottom.setVisibility(View.VISIBLE); + if(videoType != 0) { + //路由文件 + vtmFLBottom.setVisibility(View.VISIBLE); + vtmIVSet.setVisibility(View.GONE); + vtmIVFresh.setVisibility(View.VISIBLE); + vtmIVCollect.setVisibility(View.VISIBLE); + vtmSBar.setVisibility(View.GONE); + lengthView.setVisibility(View.GONE); + } + + vtmIVPlay.setImageResource(R.mipmap.playvideo); + isPlay = false; + + return false; + } + + @Override + public boolean onInfo(MediaPlayer mediaPlayer, int what, int extra) { + switch(what){ + case MediaPlayer.MEDIA_INFO_BUFFERING_START: + Log.d("zouguo","开始缓冲"); + if(videoType == 0){ + //直播视频不显示进度条 + vtmPBLoading.setVisibility(View.VISIBLE); + } + break; + case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED: + int rate = extra; + String unit = "Kb/s"; + if(rate > 1000){ + rate = rate / 1000; + unit = "Mb/s"; + } + vtmTVNetRate.setText(String.valueOf(rate) + unit); + break; + case MediaPlayer.MEDIA_INFO_BUFFERING_END: + Log.d("zouguo","缓冲结束"); + vtmPBLoading.setVisibility(View.GONE); + + if(System.currentTimeMillis() - TOUCH_SCREEN_TIME > SHOW_OPTION_DELAY){ + hideControlView(); + } + break; + } + return true; + } + + @Override + public void onBufferingUpdate(MediaPlayer mediaPlayer, int percent) { + Log.d("zouguo","percent:" + percent); + if(percent == 0 &&!videoView.isPlaying()){ + vtmPBLoading.setVisibility(View.GONE); + } + } + + @Override + public void onCompletion(MediaPlayer mediaPlayer) { + if(videoType == 0) { + vtmFLTop.setVisibility(View.VISIBLE); + vtmFLBottom.setVisibility(View.VISIBLE); + vtmPBLoading.setVisibility(View.GONE); + + //微路由文件,回到第一帧 + videoView.seekTo(0); + + vtmIVPlay.setImageResource(R.mipmap.playvideo); + isPlay = false; + } + } + + @Override + protected void onStart() { + super.onStart(); + Log.d("zouguo","onStart"); + if(videoType == 0) { + //微路由文件 + progressTimeHandler.sendEmptyMessage(12138); + long seekToLast = sp.getLong("vitamio_play_position",0); + videoView.seekTo(seekToLast); + } + } + + @Override + protected void onResume() { + super.onResume(); + //恢复播放 + videoView.resume(); + Log.d("zouguo","onResume"); + } + + @Override + protected void onPause() { + super.onPause(); + //记录播放位置 + videoView.pause(); + if(videoType == 0) + //微路由文件,记录播放位置 + sp.edit().putLong("vitamio_play_position",videoView.getCurrentPosition()).commit(); + Log.d("zouguo","onPause"); + } + + @Override + protected void onStop() { + super.onStop(); + Log.d("zouguo","onStop"); + } + + @Override + protected void onRestart() { + super.onRestart(); + Log.d("zouguo","onRestart"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + videoView.stopPlayback(); + if(videoType == 0) + //微路由文件 + progressTimeHandler.removeMessages(12138); + Log.d("zouguo","onDestroy"); + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.vtmFLRoot: + //判断单击、双击 + clickNum++; + clickHander.postDelayed(new Runnable() { + @Override + public void run() { + if(clickNum == 1){ + //单击 + if(vtmFLTop.isShown()){ + vtmFLTop.setVisibility(View.GONE); + vtmFLCenter.setVisibility(View.GONE); + vtmFLBottom.setVisibility(View.GONE); + }else{ + showControlView(); + TOUCH_SCREEN_TIME = System.currentTimeMillis(); + } + }else if(clickNum == 2){ + //双击 + if(videoView.isPlaying()){ + videoView.pause(); + vtmIVPlay.setImageResource(R.mipmap.playvideo); + isPlay = false; + + showControlView(); + }else{ + videoView.start(); + vtmIVPlay.setImageResource(R.mipmap.pausevideo); + isPlay = true; + + hideHandler.postDelayed(new Runnable() { + @Override + public void run() { + if(isPlay){ + //点击暂停播放的时候,不隐去 + hideControlView(); + } + } + },SHOW_OPTION_DELAY); + } + } + clickHander.removeCallbacksAndMessages(null); + clickNum = 0; + } + },300); + break; + case R.id.vtmIVBack: + videoView.stopPlayback(); + + Intent data = new Intent(); + data.putExtra("videoPosition",playItemPosition); + setResult(RESULT_OK,data); + finish(); + break; + case R.id.vtmIVSet: + View view = View.inflate(VideoPlayVTM.this,R.layout.dialog_videoplay_setting,null); + + PopupWindow popupWindow = new PopupWindow(view,ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.MATCH_PARENT); + + videoplay_layout_origin = view.findViewById(R.id.videoplay_layout_origin); + videoplay_layout_scale = view.findViewById(R.id.videoplay_layout_scale); + videoplay_layout_stretch = view.findViewById(R.id.videoplay_layout_stretch); + videoplay_layout_zoom = view.findViewById(R.id.videoplay_layout_zoom); + videoplay_quality_low = view.findViewById(R.id.videoplay_quality_low); + videoplay_quality_medium = view.findViewById(R.id.videoplay_quality_medium); + videoplay_quality_high = view.findViewById(R.id.videoplay_quality_high); + videoplay_speed_0_5 = view.findViewById(R.id.videoplay_speed_0_5); + videoplay_speed_0_8 = view.findViewById(R.id.videoplay_speed_0_8); + videoplay_speed_1_0 = view.findViewById(R.id.videoplay_speed_1_0); + videoplay_speed_1_2_5 = view.findViewById(R.id.videoplay_speed_1_2_5); + videoplay_speed_1_5 = view.findViewById(R.id.videoplay_speed_1_5); + videoplay_speed_2_0 = view.findViewById(R.id.videoplay_speed_2_0); + + switch (layoutFlag){ + case 0: + videoplay_layout_origin.setTextColor(Color.RED); + videoplay_layout_scale.setTextColor(Color.WHITE); + videoplay_layout_stretch.setTextColor(Color.WHITE); + videoplay_layout_zoom.setTextColor(Color.WHITE); + break; + case 1: + videoplay_layout_origin.setTextColor(Color.WHITE); + videoplay_layout_scale.setTextColor(Color.RED); + videoplay_layout_stretch.setTextColor(Color.WHITE); + videoplay_layout_zoom.setTextColor(Color.WHITE); + break; + case 2: + videoplay_layout_origin.setTextColor(Color.WHITE); + videoplay_layout_scale.setTextColor(Color.WHITE); + videoplay_layout_stretch.setTextColor(Color.RED); + videoplay_layout_zoom.setTextColor(Color.WHITE); + break; + case 3: + videoplay_layout_origin.setTextColor(Color.WHITE); + videoplay_layout_scale.setTextColor(Color.WHITE); + videoplay_layout_stretch.setTextColor(Color.WHITE); + videoplay_layout_zoom.setTextColor(Color.RED); + break; + } + + switch (qualityFlag){ + case 0: + videoplay_quality_low.setTextColor(Color.RED); + videoplay_quality_medium.setTextColor(Color.WHITE); + videoplay_quality_high.setTextColor(Color.WHITE); + break; + case 1: + videoplay_quality_low.setTextColor(Color.WHITE); + videoplay_quality_medium.setTextColor(Color.RED); + videoplay_quality_high.setTextColor(Color.WHITE); + break; + case 2: + videoplay_quality_low.setTextColor(Color.WHITE); + videoplay_quality_medium.setTextColor(Color.WHITE); + videoplay_quality_high.setTextColor(Color.RED); + break; + } + + switch (speedFlag){ + case 0: + videoplay_speed_0_5.setTextColor(Color.RED); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + break; + case 1: + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.RED); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + break; + case 2: + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.RED); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + break; + case 3: + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.RED); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + break; + case 4: + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.RED); + videoplay_speed_2_0.setTextColor(Color.WHITE); + break; + case 5: + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.RED); + break; + } + + videoplay_layout_origin.setOnClickListener(this); + videoplay_layout_scale.setOnClickListener(this); + videoplay_layout_stretch.setOnClickListener(this); + videoplay_layout_zoom.setOnClickListener(this); + videoplay_quality_low.setOnClickListener(this); + videoplay_quality_medium.setOnClickListener(this); + videoplay_quality_high.setOnClickListener(this); + + videoplay_speed_0_5.setOnClickListener(this); + videoplay_speed_0_8.setOnClickListener(this); + videoplay_speed_1_0.setOnClickListener(this); + videoplay_speed_1_2_5.setOnClickListener(this); + videoplay_speed_1_5.setOnClickListener(this); + videoplay_speed_2_0.setOnClickListener(this); + + ColorDrawable cd = new ColorDrawable(0xb0000000); + popupWindow.setBackgroundDrawable(cd); + popupWindow.setFocusable(true); + popupWindow.setOutsideTouchable(true); + popupWindow.showAtLocation(videoView, Gravity.RIGHT,0,0); + break; + case R.id.vtmIVFresh: + videoView.setVideoPath(curVideoUrl); + break; + case R.id.vtmIVCollect: + LiveVideoList lvl = LitePal.where("liveName = ? and liveUrls = ?",videoTit,curVideoUrl).findFirst(LiveVideoList.class); + + if(isCollected){ + lvl.setIsCollect(0); + + //取消收藏 + isCollected = false; + vtmIVCollect.setImageResource(R.mipmap.collect); + }else{ + lvl.setIsCollect(1); + + //添加收藏 + isCollected = true; + vtmIVCollect.setImageResource(R.mipmap.collected); + } + + lvl.save(); + break; + case R.id.vtmIVBackward: + Log.d("zouguo","Current1:" + videoView.getCurrentPosition()); + TOUCH_SCREEN_TIME = System.currentTimeMillis(); + + long backwardTo = videoView.getCurrentPosition() - 10 * 1000;//回退5秒 + if(backwardTo < 0){ + backwardTo = 0; + } + videoView.seekTo(backwardTo); + Log.d("zouguo","Current2:" + videoView.getCurrentPosition()); + break; + case R.id.vtmIVForward: + Log.d("zouguo","Current3:" + videoView.getCurrentPosition()); + TOUCH_SCREEN_TIME = System.currentTimeMillis(); + + long forwardTo = videoView.getCurrentPosition() + 10 * 1000;//快进5秒 + if(forwardTo > videoView.getDuration()){ + forwardTo = videoView.getDuration() - 5 * 1000;//防止直接到终点 + } + videoView.seekTo(forwardTo); + Log.d("zouguo","Current4:" + videoView.getCurrentPosition()); + break; + case R.id.vtmIVPlay: + if(videoView.isPlaying()){ + videoView.pause(); + vtmIVPlay.setImageResource(R.mipmap.playvideo); + isPlay = false; + return; + } + videoView.start(); + vtmIVPlay.setImageResource(R.mipmap.pausevideo); + isPlay = true; + break; + case R.id.vtmIVListVideo: + View videolist = View.inflate(VideoPlayVTM.this,R.layout.dialog_videoplay_list,null); + + TextView list_video_nums_tv = videolist.findViewById(R.id.list_video_nums_tv); + ListView list_video_lv = videolist.findViewById(R.id.list_video_lv); + + if(videoType == 0){ + list_video_nums_tv.setText("视频:" + String.valueOf(vTitleList.size())); + ArrayAdapter aa = new ArrayAdapter(this,R.layout.item_lv_listvideo_white,vTitleList); + list_video_lv.setAdapter(aa); + }else{ + list_video_nums_tv.setText("直播:" + String.valueOf(nameList.size())); + ArrayAdapter aa = new ArrayAdapter(this,R.layout.item_lv_listvideo_white,nameList); + list_video_lv.setAdapter(aa); + } + + list_video_lv.setSelection(playItemPosition); + + list_video_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + playItemPosition = position; + + Calendar calendar = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm"); + vtmTVSysTime.setText(sdf.format(calendar.getTime())); + + vtmFLTop.setVisibility(View.VISIBLE); + vtmFLBottom.setVisibility(View.VISIBLE); + if(videoType != 0) { + vtmIVSet.setVisibility(View.GONE); + vtmFLBottom.setVisibility(View.VISIBLE); + vtmSBar.setVisibility(View.GONE); + lengthView.setVisibility(View.GONE); + } + + if(videoType == 0){ + curVideoUrl = srcList.get(position); + vtmTVTitle.setText(vTitleList.get(position)); + }else{ + curVideoUrl = urlsList.get(position); + vtmTVTitle.setText(nameList.get(position)); + } + + vtmTVVideoLength.setText("读取中..."); + videoView.setVideoPath(curVideoUrl); + + hideHandler.postDelayed(new Runnable() { + @Override + public void run() { + + if(isPlay){ + //点击暂停播放的时候,不隐去 + hideControlView(); + } + } + },SHOW_OPTION_DELAY); + } + }); + + pwVideoList = new PopupWindow(videolist,ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.MATCH_PARENT); + + ColorDrawable df = new ColorDrawable(0xb0000000); + pwVideoList.setBackgroundDrawable(df); + pwVideoList.setTouchable(true); + pwVideoList.setOutsideTouchable(true); + pwVideoList.showAtLocation(videoView,Gravity.RIGHT,0,0); + break; + case R.id.videoplay_layout_origin: + //视频--原始画面 + videoplay_layout_origin.setTextColor(Color.RED); + videoplay_layout_scale.setTextColor(Color.WHITE); + videoplay_layout_stretch.setTextColor(Color.WHITE); + videoplay_layout_zoom.setTextColor(Color.WHITE); + videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_ORIGIN,0); + + layoutFlag = 0; + break; + case R.id.videoplay_layout_scale: + //视频--全屏画面 + videoplay_layout_origin.setTextColor(Color.WHITE); + videoplay_layout_scale.setTextColor(Color.RED); + videoplay_layout_stretch.setTextColor(Color.WHITE); + videoplay_layout_zoom.setTextColor(Color.WHITE); + videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE,0); + + layoutFlag = 1; + break; + case R.id.videoplay_layout_stretch: + //视频--拉伸画面 + videoplay_layout_origin.setTextColor(Color.WHITE); + videoplay_layout_scale.setTextColor(Color.WHITE); + videoplay_layout_stretch.setTextColor(Color.RED); + videoplay_layout_zoom.setTextColor(Color.WHITE); + videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_STRETCH,0); + + layoutFlag = 2; + break; + case R.id.videoplay_layout_zoom: + //视频--裁剪画面 + videoplay_layout_origin.setTextColor(Color.WHITE); + videoplay_layout_scale.setTextColor(Color.WHITE); + videoplay_layout_stretch.setTextColor(Color.WHITE); + videoplay_layout_zoom.setTextColor(Color.RED); + videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_ZOOM,0); + + layoutFlag = 3; + break; + case R.id.videoplay_quality_low: + //视频--流畅 + videoplay_quality_low.setTextColor(Color.RED); + videoplay_quality_medium.setTextColor(Color.WHITE); + videoplay_quality_high.setTextColor(Color.WHITE); + videoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_LOW); + + qualityFlag = 0; + break; + case R.id.videoplay_quality_medium: + //视频--普通 + videoplay_quality_low.setTextColor(Color.WHITE); + videoplay_quality_medium.setTextColor(Color.RED); + videoplay_quality_high.setTextColor(Color.WHITE); + videoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_MEDIUM); + + qualityFlag = 1; + break; + case R.id.videoplay_quality_high: + //视频--高质 + videoplay_quality_low.setTextColor(Color.WHITE); + videoplay_quality_medium.setTextColor(Color.WHITE); + videoplay_quality_high.setTextColor(Color.RED); + videoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH); + + qualityFlag = 2; + break; + case R.id.videoplay_speed_0_5: + //视频--0.5速 + if(mediaPlayer != null){ + videoplay_speed_0_5.setTextColor(Color.RED); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + + mediaPlayer.setPlaybackSpeed(0.5f); + + speedFlag = 0; + }else{ + Toast.makeText(VideoPlayVTM.this,"抱歉,媒体播放器尚未初始化",Toast.LENGTH_SHORT).show(); + } + + break; + case R.id.videoplay_speed_0_8: + //视频--0.8速 + if(mediaPlayer != null){ + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.RED); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + + mediaPlayer.setPlaybackSpeed(0.8f); + + speedFlag = 1; + }else{ + Toast.makeText(VideoPlayVTM.this,"抱歉,媒体播放器尚未初始化",Toast.LENGTH_SHORT).show(); + } + break; + case R.id.videoplay_speed_1_0: + //视频--1倍速 + if(mediaPlayer != null){ + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.RED); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + + mediaPlayer.setPlaybackSpeed(1.0f); + + speedFlag = 2; + }else{ + Toast.makeText(VideoPlayVTM.this,"抱歉,媒体播放器尚未初始化",Toast.LENGTH_SHORT).show(); + } + break; + case R.id.videoplay_speed_1_2_5: + //视频--1.25速 + if(mediaPlayer != null){ + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.RED); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.WHITE); + + mediaPlayer.setPlaybackSpeed(1.25f); + + speedFlag = 3; + }else{ + Toast.makeText(VideoPlayVTM.this,"抱歉,媒体播放器尚未初始化",Toast.LENGTH_SHORT).show(); + } + break; + case R.id.videoplay_speed_1_5: + //视频--1.5速 + if(mediaPlayer != null){ + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.RED); + videoplay_speed_2_0.setTextColor(Color.WHITE); + + mediaPlayer.setPlaybackSpeed(1.5f); + + speedFlag = 4; + }else{ + Toast.makeText(VideoPlayVTM.this,"抱歉,媒体播放器尚未初始化",Toast.LENGTH_SHORT).show(); + } + break; + case R.id.videoplay_speed_2_0: + //视频--2.0速 + if(mediaPlayer != null){ + videoplay_speed_0_5.setTextColor(Color.WHITE); + videoplay_speed_0_8.setTextColor(Color.WHITE); + videoplay_speed_1_0.setTextColor(Color.WHITE); + videoplay_speed_1_2_5.setTextColor(Color.WHITE); + videoplay_speed_1_5.setTextColor(Color.WHITE); + videoplay_speed_2_0.setTextColor(Color.RED); + + mediaPlayer.setPlaybackSpeed(2.0f); + + speedFlag = 5; + }else{ + Toast.makeText(VideoPlayVTM.this,"抱歉,媒体播放器尚未初始化",Toast.LENGTH_SHORT).show(); + } + break; + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } +} diff --git a/app/src/main/java/com/example/wgjrouter/WebShow.java b/app/src/main/java/com/example/wgjrouter/WebShow.java new file mode 100644 index 0000000..b77a0b3 --- /dev/null +++ b/app/src/main/java/com/example/wgjrouter/WebShow.java @@ -0,0 +1,155 @@ +package com.example.wgjrouter; + +import android.annotation.TargetApi; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageView; + +public class WebShow extends AppCompatActivity { + + private Toolbar help_tb; + private ImageView help_back; + private WebView help_wv; + private ImageView help_rollback; + + private int REQUEST_CHOOSE_FILE_CODE = 13579; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_help); + + initView(); + + Intent getIntent = getIntent(); + boolean showTitle = getIntent.getBooleanExtra("web_showtitle",true); + boolean showBack = getIntent.getBooleanExtra("web_showback",false); + String title = getIntent.getStringExtra("web_title"); + String url = getIntent.getStringExtra("web_url"); + + Log.d("zouguo",title + " - " + url); + + if(showTitle) { + help_tb.setVisibility(View.VISIBLE); + }else{ + help_tb.setVisibility(View.GONE); + } + + if(showBack){ + help_back.setVisibility(View.VISIBLE); + }else{ + help_back.setVisibility(View.GONE); + } + + help_tb.setTitle(title); + help_wv.loadUrl(url); + } + + private void initView(){ + help_tb = findViewById(R.id.help_tb); + help_back = findViewById(R.id.help_back); + help_tb.setNavigationIcon(R.mipmap.back); + help_rollback = findViewById(R.id.help_rollback); + + help_back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + help_tb.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + help_wv = findViewById(R.id.help_wv); + + WebSettings ws = help_wv.getSettings(); + ws.setLoadWithOverviewMode(true); + ws.setUseWideViewPort(true); + ws.setDefaultTextEncodingName("utf-8"); + ws.setLoadsImagesAutomatically(true); + ws.setJavaScriptEnabled(true); + ws.setSupportZoom(true); + ws.setBuiltInZoomControls(true); + ws.setDisplayZoomControls(false); + + //5.1以上版本默认禁止http和https的混用 + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ + ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); + } + + WebViewClient wvc = new WebViewClient(){ + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + if(help_wv.canGoBack()){ + help_rollback.setVisibility(View.VISIBLE); + }else{ + help_rollback.setVisibility(View.GONE); + } + } + }; + +// WebChromeClient wcc = new WebChromeClient(){ +// @TargetApi(Build.VERSION_CODES.LOLLIPOP) +// @Override +// public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { +// Intent intent = fileChooserParams.createIntent(); +// intent.addCategory(Intent.CATEGORY_OPENABLE); +// intent.setType("*/*"); +// startActivityForResult(intent,REQUEST_CHOOSE_FILE_CODE); +// return true; +// } +// }; + + help_wv.setWebViewClient(wvc); +// help_wv.setWebChromeClient(wcc); + + help_rollback.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + help_wv.goBack(); + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode == REQUEST_CHOOSE_FILE_CODE && resultCode == RESULT_OK){ + Log.d("zouguo","1111"); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if(keyCode == KeyEvent.KEYCODE_BACK + &&event.getRepeatCount() == 0){ + finish(); + } + return false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + help_wv.destroy(); + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..971add5 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_dashboard_black_24dp.xml b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml new file mode 100644 index 0000000..46fc8de --- /dev/null +++ b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000..f8bb0b5 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background_bak.xml b/app/src/main/res/drawable/ic_launcher_background_bak.xml new file mode 100644 index 0000000..eed7a42 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background_bak.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/app/src/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000..78b75c3 --- /dev/null +++ b/app/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_aboutapp.xml b/app/src/main/res/layout/activity_aboutapp.xml new file mode 100644 index 0000000..73bc8df --- /dev/null +++ b/app/src/main/res/layout/activity_aboutapp.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_file_trans_finish.xml b/app/src/main/res/layout/activity_file_trans_finish.xml new file mode 100644 index 0000000..891b9cf --- /dev/null +++ b/app/src/main/res/layout/activity_file_trans_finish.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/layout/activity_funny_collect.xml b/app/src/main/res/layout/activity_funny_collect.xml new file mode 100644 index 0000000..78d2149 --- /dev/null +++ b/app/src/main/res/layout/activity_funny_collect.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/app/src/main/res/layout/activity_funny_live.xml b/app/src/main/res/layout/activity_funny_live.xml new file mode 100644 index 0000000..c8c8a48 --- /dev/null +++ b/app/src/main/res/layout/activity_funny_live.xml @@ -0,0 +1,58 @@ + + + + + + + + + +