├── README.md ├── appupgrade.json ├── home.json ├── home1.json ├── release └── mothership.apk └── tvhome ├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── libs │ ├── MiStats_SDK_Client_1_2_0.jar │ ├── analytics_api.jar │ ├── glide-3.7.0.jar │ └── mitvmiddleware.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── aidl │ └── android │ │ └── content │ │ └── pm │ │ ├── IPackageDataObserver.aidl │ │ ├── IPackageDeleteObserver.aidl │ │ └── IPackageInstallObserver.aidl │ ├── java │ ├── com │ │ ├── duokan │ │ │ ├── MediaMetadataRetriever.java │ │ │ └── VolleyHelper.java │ │ ├── mothership │ │ │ └── tvhome │ │ │ │ ├── ChannelActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── SearchActivity.java │ │ │ │ ├── TvHomeApplication.java │ │ │ │ ├── Utils.java │ │ │ │ ├── app │ │ │ │ ├── BaseFragment.java │ │ │ │ ├── BaseListFragment.java │ │ │ │ ├── BaseRowsFragment.java │ │ │ │ ├── BaseVolleyFragment.java │ │ │ │ ├── HeadersFragment.java │ │ │ │ ├── KeyboardFragment.java │ │ │ │ ├── MainFragment.java │ │ │ │ ├── MediaListFragment.java │ │ │ │ ├── PageRowsFragment.java │ │ │ │ ├── PagesFragment.java │ │ │ │ └── SearchResultFragment.java │ │ │ │ ├── tv │ │ │ │ └── TVSurfaceView.java │ │ │ │ ├── util │ │ │ │ └── ViewUtils.java │ │ │ │ ├── view │ │ │ │ ├── AdView.java │ │ │ │ ├── AlertDialogHelper.java │ │ │ │ ├── BaseCardView.java │ │ │ │ ├── ChannelContainer.java │ │ │ │ ├── DiBaseView.java │ │ │ │ ├── DiImgSw.java │ │ │ │ ├── DiViewT2.java │ │ │ │ ├── EmptyLoadingView.java │ │ │ │ ├── ProgressNotifiable.java │ │ │ │ ├── RetryView.java │ │ │ │ ├── TagViewGroup.java │ │ │ │ └── TvViewGroup.java │ │ │ │ └── widget │ │ │ │ ├── BasePresenter.java │ │ │ │ ├── BlockAdapter.java │ │ │ │ ├── BlockBasePresenter.java │ │ │ │ ├── BlockGridPresenter.java │ │ │ │ ├── BlockHorizontalPresenter.java │ │ │ │ ├── BlockPresenterSelector.java │ │ │ │ ├── BlockVerticalPresenter.java │ │ │ │ ├── BlockView.java │ │ │ │ ├── CardPresenter.java │ │ │ │ ├── CardPresenterSelector.java │ │ │ │ ├── ChannelPresenter.java │ │ │ │ ├── DebugVerticalGridView.java │ │ │ │ ├── DisplayItemSelector.java │ │ │ │ ├── FocusGridLayout.java │ │ │ │ ├── FocusHLMgr.java │ │ │ │ ├── FocusHelper.java │ │ │ │ ├── FocusVerticalGridView.java │ │ │ │ ├── ItemTextView.java │ │ │ │ ├── LandCardPresenter.java │ │ │ │ ├── ListRowPresenter.java │ │ │ │ ├── MainHeaderPresenter.java │ │ │ │ ├── MainHeaderView.java │ │ │ │ ├── PagerGroup.java │ │ │ │ ├── PresenterT2.java │ │ │ │ ├── PresenterT3.java │ │ │ │ ├── RowContainerView.java │ │ │ │ ├── RowPresenter.java │ │ │ │ ├── TVhomBlockPresenter.java │ │ │ │ └── TvViewGroupPresenter.java │ │ ├── tv │ │ │ └── ui │ │ │ │ └── metro │ │ │ │ └── model │ │ │ │ ├── AppVersion.java │ │ │ │ ├── Block.java │ │ │ │ ├── Constants.java │ │ │ │ ├── DisplayItem.java │ │ │ │ ├── GenericBlock.java │ │ │ │ ├── Image.java │ │ │ │ ├── ImageGroup.java │ │ │ │ ├── LayoutConstant.java │ │ │ │ ├── PlaySource.java │ │ │ │ ├── TokenInfo.java │ │ │ │ ├── VideoBlocks.java │ │ │ │ ├── VideoItem.java │ │ │ │ └── XiaomiStatistics.java │ │ └── video │ │ │ ├── ads │ │ │ └── AdsReport.java │ │ │ ├── cp │ │ │ └── model │ │ │ │ ├── AppPkgInfo.java │ │ │ │ ├── AppPluginCpInfo.java │ │ │ │ ├── BaseEpItem.java │ │ │ │ ├── ExternalPackageData.java │ │ │ │ ├── PlayerPluginInfo.java │ │ │ │ ├── RawCpItem.java │ │ │ │ └── VideoPlayerConstant.java │ │ │ ├── search │ │ │ ├── Action.java │ │ │ ├── Config.java │ │ │ ├── Constants.java │ │ │ ├── access │ │ │ │ ├── CommonUrl.java │ │ │ │ ├── CommonUrlBuilder.java │ │ │ │ ├── MyGlideModule.java │ │ │ │ ├── Params.java │ │ │ │ ├── ResponseStatus.java │ │ │ │ ├── VolleyErrorHelper.java │ │ │ │ ├── VolleyHelper.java │ │ │ │ ├── VolleyHttpUtils.java │ │ │ │ ├── api │ │ │ │ │ ├── ApiCallback.java │ │ │ │ │ ├── ApiGetEntity.java │ │ │ │ │ └── ParseException.java │ │ │ │ └── msg │ │ │ │ │ ├── Message.java │ │ │ │ │ └── RequestMessage.java │ │ │ ├── model │ │ │ │ ├── BaseEntity.java │ │ │ │ ├── Cineaste.java │ │ │ │ ├── CineasteSR.java │ │ │ │ ├── HotSR.java │ │ │ │ ├── Image.java │ │ │ │ ├── Item.java │ │ │ │ ├── MediaBase.java │ │ │ │ └── MediaSR.java │ │ │ └── recyclerview │ │ │ │ └── adapter │ │ │ │ ├── AlphaAnimatorAdapter.java │ │ │ │ ├── AnimatorAdapter.java │ │ │ │ └── helper │ │ │ │ ├── AnimatorUtil.java │ │ │ │ └── ViewAnimator.java │ │ │ ├── ui │ │ │ ├── Util.java │ │ │ ├── idata │ │ │ │ ├── AccountUtils.java │ │ │ │ ├── BackgroundService.java │ │ │ │ ├── SyncServiceHelper.java │ │ │ │ ├── iDataORM.java │ │ │ │ └── iDataProvider.java │ │ │ └── loader │ │ │ │ ├── AppGson.java │ │ │ │ ├── BaseGsonLoader.java │ │ │ │ ├── CommonBaseUrl.java │ │ │ │ ├── CommonUrl.java │ │ │ │ ├── CommonUrlBuilder.java │ │ │ │ ├── OnNextPageLoader.java │ │ │ │ ├── ProgressNotifiable.java │ │ │ │ ├── Utils.java │ │ │ │ ├── VideoContentLengthRetriever.java │ │ │ │ ├── VideoUrlHeaderRetriever.java │ │ │ │ └── video │ │ │ │ ├── CommonRequest.java │ │ │ │ ├── GenericAlbumLoader.java │ │ │ │ ├── GenericDetailLoader.java │ │ │ │ └── TabsGsonLoader.java │ │ │ └── utils │ │ │ ├── IOUtil.java │ │ │ ├── IPackageManagerConstants.java │ │ │ ├── ReflectUtil.java │ │ │ ├── SignatureUtil.java │ │ │ ├── Tools.java │ │ │ ├── ViewHelper.java │ │ │ └── WLReflect.java │ └── miui │ │ ├── os │ │ └── BuildV5.java │ │ └── sdk │ │ └── framework │ │ └── ExtraNetwork.java │ └── res │ ├── color │ ├── header_text.xml │ ├── tv_seach_button_text.xml │ ├── tv_seach_result_text.xml │ └── tv_text.xml │ ├── drawable-xhdpi │ ├── a1.png │ ├── a2.png │ ├── a3.png │ ├── a4.png │ ├── a5.png │ ├── a6.png │ ├── arrow_right.png │ ├── background.jpg │ ├── bg_app.9.png │ ├── bg_search.png │ ├── defaultposter.jpg │ ├── focus.png │ ├── headerfocus.png │ ├── ic_backspace.png │ ├── img_focus.9.png │ └── star_small_hl.png │ ├── drawable │ ├── blue_gradient.xml │ ├── item_bg_default.xml │ ├── key_btn_bg.xml │ ├── lb_headers_bottom_fading.xml │ ├── list_item_bg.xml │ ├── list_item_bg_focus.xml │ ├── list_item_bg_normal.xml │ └── main_header_bg.xml │ ├── layout │ ├── activity_main.xml │ ├── activity_search.xml │ ├── ad_main_layout.xml │ ├── block_horizontal.xml │ ├── block_vertical.xml │ ├── browse_fragment.xml │ ├── di_base_view.xml │ ├── di_img_sw.xml │ ├── di_view_t2.xml │ ├── di_view_t3.xml │ ├── fragment_keyboard.xml │ ├── fragment_list.xml │ ├── fragment_search_result.xml │ ├── headers_fragment.xml │ ├── home_block.xml │ ├── item_tag_view.xml │ ├── lb_rows_fragment.xml │ ├── list_item_media.xml │ ├── load_view.xml │ ├── main_header.xml │ ├── pagers_fragment.xml │ ├── reload_view_dark.xml │ ├── row_container.xml │ └── tvsurfaceview.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── transition-v19 │ ├── lb_browse_headers_in.xml │ └── lb_browse_headers_out.xml │ ├── transition-v21 │ ├── lb_browse_enter_transition.xml │ ├── lb_browse_entrance_transition.xml │ ├── lb_browse_headers_in.xml │ ├── lb_browse_headers_out.xml │ ├── lb_browse_return_transition.xml │ ├── lb_details_enter_transition.xml │ ├── lb_details_return_transition.xml │ ├── lb_enter_transition.xml │ ├── lb_guidedstep_activity_enter.xml │ ├── lb_return_transition.xml │ ├── lb_shared_element_enter_transition.xml │ ├── lb_shared_element_return_transition.xml │ ├── lb_title_in.xml │ ├── lb_title_out.xml │ ├── lb_vertical_grid_enter_transition.xml │ ├── lb_vertical_grid_entrance_transition.xml │ └── lb_vertical_grid_return_transition.xml │ ├── transition-v22 │ ├── lb_browse_entrance_transition.xml │ └── lb_browse_return_transition.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── themes.xml ├── build.gradle ├── design ├── MIUI_Video_Scrum.pdf ├── TV01.jpg ├── TV02.jpg ├── TV03.jpg ├── TV04.jpg ├── TV05.jpg ├── TV06.jpg ├── TV07.jpg ├── TV08.jpg ├── block.png ├── pvideo.png └── vp.png ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── tvhome.iml /appupgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "version_code":12, 4 | "recent_change":"TV All In One", 5 | "version_name":"MotherShip(Vi12)", 6 | "apk_url":"https://raw.githubusercontent.com/AiAndroid/tvhome/master/release/mothership.apk", 7 | "release_date":"2016-06-21 19:30PM", 8 | "released_by":"TV All In One" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /release/mothership.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/release/mothership.apk -------------------------------------------------------------------------------- /tvhome/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /tvhome/.idea/.name: -------------------------------------------------------------------------------- 1 | MotherShip -------------------------------------------------------------------------------- /tvhome/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tvhome/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tvhome/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /tvhome/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /tvhome/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tvhome/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /tvhome/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tvhome/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /tvhome/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion '23.0.1' 6 | defaultConfig { 7 | applicationId 'com.mothership.tvhome' 8 | minSdkVersion 17 9 | targetSdkVersion 23 10 | versionCode 5 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | productFlavors { 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(dir: 'libs', include: ['*.jar']) 25 | compile files('libs/analytics_api.jar') 26 | compile files('libs/MiStats_SDK_Client_1_2_0.jar') 27 | compile 'com.android.support:appcompat-v7:23.1.1' 28 | compile 'com.squareup.picasso:picasso:2.5.2' 29 | compile 'com.google.code.gson:gson:2.6.1' 30 | compile 'com.squareup.okhttp3:okhttp:3.1.2' 31 | compile 'com.squareup.okio:okio:1.6.0' 32 | compile 'eu.the4thfloor.volley:com.android.volley:2015.05.28' 33 | compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2' 34 | compile 'com.android.support:leanback-v17:23.1.1' 35 | compile 'com.android.support:recyclerview-v7:23.1.1' 36 | compile 'com.android.support:support-v4:23.1.1' 37 | compile files('libs/glide-3.7.0.jar') 38 | compile 'com.facebook.fresco:fresco:0.9.0+' 39 | compile 'com.facebook.fresco:imagepipeline-okhttp:0.9.0+' 40 | compile 'com.android.support:gridlayout-v7:23.2.0' 41 | compile files('libs/mitvmiddleware.jar') 42 | compile 'com.alibaba:fastjson:1.2.8' 43 | } 44 | -------------------------------------------------------------------------------- /tvhome/app/libs/MiStats_SDK_Client_1_2_0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/libs/MiStats_SDK_Client_1_2_0.jar -------------------------------------------------------------------------------- /tvhome/app/libs/analytics_api.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/libs/analytics_api.jar -------------------------------------------------------------------------------- /tvhome/app/libs/glide-3.7.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/libs/glide-3.7.0.jar -------------------------------------------------------------------------------- /tvhome/app/libs/mitvmiddleware.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/libs/mitvmiddleware.jar -------------------------------------------------------------------------------- /tvhome/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/liuhuadonbg/soft/android-sdk-linux/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /tvhome/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tvhome/app/src/main/aidl/android/content/pm/IPackageDataObserver.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2007, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | package android.content.pm; 19 | 20 | /** 21 | * API for package data change related callbacks from the Package Manager. 22 | * Some usage scenarios include deletion of cache directory, generate 23 | * statistics related to code, data, cache usage(TODO) 24 | * {@hide} 25 | */ 26 | oneway interface IPackageDataObserver { 27 | void onRemoveCompleted(in String packageName, boolean succeeded); 28 | } 29 | -------------------------------------------------------------------------------- /tvhome/app/src/main/aidl/android/content/pm/IPackageDeleteObserver.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2007, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | package android.content.pm; 19 | 20 | /** 21 | * API for deletion callbacks from the Package Manager. 22 | * 23 | * {@hide} 24 | */ 25 | oneway interface IPackageDeleteObserver { 26 | void packageDeleted(in String packageName, in int returnCode); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tvhome/app/src/main/aidl/android/content/pm/IPackageInstallObserver.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2007, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | package android.content.pm; 19 | 20 | /** 21 | * API for installation callbacks from the Package Manager. 22 | * @hide 23 | */ 24 | oneway interface IPackageInstallObserver { 25 | void packageInstalled(in String packageName, int returnCode); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/duokan/VolleyHelper.java: -------------------------------------------------------------------------------- 1 | package com.duokan; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.support.v4.util.LruCache; 6 | 7 | import com.android.volley.Request; 8 | import com.android.volley.RequestQueue; 9 | import com.android.volley.toolbox.ImageLoader; 10 | import com.android.volley.toolbox.Volley; 11 | 12 | public class VolleyHelper { 13 | private final static String TAG="VolleyHelper"; 14 | private static final int IMAGE_CACHE_SIZE = (int) (0.3f * Runtime.getRuntime().maxMemory()); 15 | private static VolleyHelper mInstance; 16 | private RequestQueue mAPIRequestQueue, mImageLoaderRequestQueue; 17 | private ImageLoader mImageLoader; 18 | private static Context mCtx; 19 | 20 | public static synchronized VolleyHelper getInstance(Context context) { 21 | if (mInstance == null) { 22 | mInstance = new VolleyHelper(context); 23 | } 24 | return mInstance; 25 | } 26 | 27 | private VolleyHelper(Context context) { 28 | mCtx = context.getApplicationContext(); 29 | mAPIRequestQueue = getAPIRequestQueue(); 30 | mImageLoaderRequestQueue = getImageLoaderRequestQueue(); 31 | 32 | mImageLoader = new ImageLoader(mImageLoaderRequestQueue, new ImageLoader.ImageCache() { 33 | int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 34 | int cacheSize = (int) ((maxMemory/24)); 35 | 36 | private final LruCache cache = new LruCache(cacheSize){ 37 | @Override 38 | protected int sizeOf(String key, Bitmap bitmap) { 39 | return bitmap.getByteCount()/1024; 40 | } 41 | }; 42 | 43 | @Override 44 | public Bitmap getBitmap(String url) { 45 | Bitmap tmp = cache.get(url); 46 | return tmp; 47 | } 48 | 49 | @Override 50 | public void putBitmap(String url, Bitmap bitmap) { 51 | cache.put(url, bitmap); 52 | } 53 | }); 54 | } 55 | 56 | public RequestQueue getAPIRequestQueue() { 57 | if (mAPIRequestQueue == null) { 58 | // getApplicationContext() is key, it keeps you from leaking the 59 | // Activity or BroadcastReceiver if someone passes one in. 60 | mAPIRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); 61 | } 62 | return mAPIRequestQueue; 63 | } 64 | 65 | public RequestQueue getImageLoaderRequestQueue() { 66 | if (mImageLoaderRequestQueue == null) { 67 | // getApplicationContext() is key, it keeps you from leaking the 68 | // Activity or BroadcastReceiver if someone passes one in. 69 | mImageLoaderRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); 70 | } 71 | return mImageLoaderRequestQueue; 72 | } 73 | 74 | public void addToAPIRequestQueue(Request req) { 75 | getAPIRequestQueue().add(req); 76 | } 77 | public void addToImageLoaderRequestQueue(Request req) { 78 | getAPIRequestQueue().add(req); 79 | } 80 | 81 | public ImageLoader getImageLoader() { 82 | return mImageLoader; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/ChannelActivity.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | 6 | import com.tv.ui.metro.model.DisplayItem; 7 | import com.video.ui.loader.video.GenericAlbumLoader; 8 | 9 | /** 10 | * Created by liuhuadonbg on 3/21/16. 11 | */ 12 | public class ChannelActivity extends MainActivity { 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | } 17 | 18 | //please override this fun 19 | protected void createTabsLoader() { 20 | if(item == null){ 21 | item = new DisplayItem(); 22 | item.ns = "home"; 23 | item.type = "album"; 24 | item.title = "home"; 25 | } 26 | 27 | mLoader = GenericAlbumLoader.generateTabsLoader(getBaseContext(), item); 28 | } 29 | 30 | @Override 31 | protected void onResume() { 32 | super.onResume(); 33 | View view = findViewById(R.id.back_arrow); 34 | view.setVisibility(View.VISIBLE); 35 | } 36 | @Override 37 | protected void onPause() { 38 | super.onPause(); 39 | View view = findViewById(R.id.back_arrow); 40 | view.setVisibility(View.GONE); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/SearchActivity.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.v4.app.FragmentActivity; 7 | import android.support.v4.app.FragmentManager; 8 | import com.mothership.tvhome.app.KeyboardFragment; 9 | import com.mothership.tvhome.app.SearchResultFragment; 10 | 11 | /** 12 | * 搜索界面 13 | * 14 | * Created by zhuzhenhua on 15-12-22. 15 | */ 16 | public class SearchActivity extends FragmentActivity 17 | { 18 | 19 | private KeyboardFragment mKeyboardFragment; 20 | private SearchResultFragment mSearchResultFragment; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_search); 26 | initViews(); 27 | } 28 | 29 | private void initViews() { 30 | FragmentManager manager = getSupportFragmentManager(); 31 | mSearchResultFragment = (SearchResultFragment) manager.findFragmentById(R.id.fragment_search_result); 32 | mKeyboardFragment = (KeyboardFragment) manager.findFragmentById(R.id.fragment_keyboard); 33 | mKeyboardFragment.setOnTextChangedListener(new KeyboardFragment.OnTextChangedListener() { 34 | 35 | @Override 36 | public void onTextChanged(String text) 37 | { 38 | mSearchResultFragment.search(text); 39 | } 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/TvHomeApplication.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.drawee.backends.pipeline.Fresco; 6 | import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory; 7 | import com.facebook.imagepipeline.core.ImagePipelineConfig; 8 | import com.squareup.okhttp.OkHttpClient; 9 | 10 | /** 11 | * Created by liuhuadonbg on 3/14/16. 12 | */ 13 | public class TvHomeApplication extends Application { 14 | 15 | @Override 16 | public void onCreate() { 17 | super.onCreate(); 18 | 19 | OkHttpClient okHttpClient = new OkHttpClient(); 20 | ImagePipelineConfig config = OkHttpImagePipelineConfigFactory.newBuilder(getApplicationContext(), okHttpClient).build(); 21 | 22 | Fresco.initialize(getApplicationContext(), config); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/app/BaseListFragment.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.app; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | 13 | import com.mothership.tvhome.R; 14 | 15 | /** 16 | * Base List Fragment 17 | * 18 | * Created by zhuzhenhua on 15-12-15. 19 | */ 20 | public abstract class BaseListFragment extends BaseFragment { 21 | 22 | protected TextView mTitleTv; 23 | protected RecyclerView mListView; 24 | 25 | @Nullable 26 | @Override 27 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 28 | View res = inflater.inflate(R.layout.fragment_list, container, false); 29 | initViews(res); 30 | initData(); 31 | return res; 32 | } 33 | 34 | protected void initData() 35 | { 36 | 37 | } 38 | 39 | protected void initViews(View root) { 40 | mTitleTv = (TextView) root.findViewById(R.id.title); 41 | LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mTitleTv.getLayoutParams(); 42 | params.bottomMargin = (int) getResources().getDimension(R.dimen.margin_small); 43 | mListView = (RecyclerView) root.findViewById(R.id.list); 44 | mListView.setFocusable(false);// 布局中设置不生效 45 | mListView.setHasFixedSize(true); 46 | mListView.setLayoutManager(new LinearLayoutManager(getContext())); 47 | // mListView.addItemDecoration(new DividerItemDecoration(getContext())); 48 | mListView.post(new Runnable() { 49 | @Override 50 | public void run() { 51 | onRvLayoutFinish(mListView.getWidth(), mListView.getHeight()); 52 | } 53 | }); 54 | } 55 | 56 | public void requestFocus() { 57 | mListView.requestFocus(); 58 | } 59 | 60 | protected void onRvLayoutFinish(int width, int height) { 61 | // TODO 子类根据需要重载该方法.可用得到Rv的宽高 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/app/BaseVolleyFragment.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.app; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.view.View; 6 | 7 | import com.android.volley.RequestQueue; 8 | import com.video.search.access.VolleyHelper; 9 | 10 | /** 11 | * Created by zhuzhenhua on 16-1-7. 12 | */ 13 | public class BaseVolleyFragment extends BaseFragment { 14 | 15 | protected VolleyHelper mVolleyHelper; 16 | protected RequestQueue mRequestQueue; 17 | 18 | @Override 19 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 20 | mVolleyHelper = VolleyHelper.getInstance(getContext()); 21 | mRequestQueue = mVolleyHelper.getRequestQueue(); 22 | super.onActivityCreated(savedInstanceState); 23 | initViews(getView()); 24 | initData(); 25 | } 26 | 27 | protected void initViews(View root) { 28 | 29 | } 30 | 31 | 32 | 33 | protected void initData() { 34 | 35 | } 36 | 37 | @Override 38 | public void onStop() { 39 | super.onStop(); 40 | 41 | mRequestQueue.cancelAll(getReqTag()); 42 | System.gc(); 43 | } 44 | 45 | protected String getReqTag() { 46 | return getClass().getSimpleName(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/view/DiBaseView.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.LinearLayout; 8 | 9 | import com.mothership.tvhome.R; 10 | import com.mothership.tvhome.widget.FocusHLMgr; 11 | 12 | /** 13 | * Created by Shawn on 16/3/15. 14 | */ 15 | public class DiBaseView extends LinearLayout 16 | { 17 | static final float UnFocusAlpha = 0.6f; 18 | static final float FocusAlpha = 1.0f; 19 | public DiBaseView(Context context, AttributeSet attrs) 20 | { 21 | super(context, attrs); 22 | //setAlpha(UnFocusAlpha); 23 | } 24 | 25 | @Override 26 | protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) 27 | { 28 | super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); 29 | onFocusChange(this, gainFocus); 30 | } 31 | 32 | static final void onFocusChange(View aView, boolean aGainFocus) 33 | { 34 | FocusHLMgr mgr = FocusHLMgr.getMgr(aView.getContext()); 35 | if(aGainFocus) 36 | { 37 | // aView.animate().withLayer().alpha(FocusAlpha); 38 | 39 | if(mgr != null) 40 | { 41 | mgr.viewGotFocus(aView); 42 | } 43 | } 44 | else 45 | { 46 | if(mgr != null) 47 | { 48 | mgr.viewLostFocus(aView); 49 | } 50 | // aView.animate().withLayer().alpha(UnFocusAlpha); 51 | } 52 | 53 | View tv = aView.findViewById(R.id.di_title); 54 | View text = aView.findViewById(R.id.di_text); 55 | if(tv != null) 56 | { 57 | tv.setSelected(aGainFocus); 58 | } 59 | if(tv!=null&&text!=null){ 60 | if(aGainFocus){ 61 | tv.setVisibility(View.VISIBLE); 62 | text.setVisibility(View.GONE); 63 | }else{ 64 | tv.setVisibility(View.GONE); 65 | text.setVisibility(View.VISIBLE); 66 | } 67 | } 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/view/DiImgSw.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.FrameLayout; 6 | import android.widget.ImageSwitcher; 7 | 8 | /** 9 | * Created by Shawn on 16/3/8. 10 | */ 11 | public class DiImgSw extends FrameLayout 12 | { 13 | ImageSwitcher mSw; 14 | public DiImgSw(Context context, AttributeSet attrs) 15 | { 16 | super(context, attrs); 17 | } 18 | 19 | @Override 20 | protected void onFinishInflate() 21 | { 22 | super.onFinishInflate(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/view/DiViewT2.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.FrameLayout; 8 | import android.widget.LinearLayout; 9 | 10 | /** 11 | * Created by Shawn on 16/3/15. 12 | */ 13 | public class DiViewT2 extends FrameLayout 14 | { 15 | public DiViewT2(Context context, AttributeSet attrs) 16 | { 17 | super(context, attrs); 18 | // setAlpha(DiBaseView.UnFocusAlpha); 19 | } 20 | 21 | @Override 22 | protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) 23 | { 24 | super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); 25 | DiBaseView.onFocusChange(this, gainFocus); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/view/ProgressNotifiable.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.view; 2 | 3 | public interface ProgressNotifiable { 4 | 5 | //每一阶段的载入开始时均会调用该方法 6 | public void startLoading(boolean hasData); 7 | 8 | //每一阶段的载入结束时均会调用该方法 9 | public void stopLoading(boolean hasData, boolean hasNext); 10 | 11 | //绑定时马上会被调用,用于初始化当前的载入状态 12 | public void init(boolean hasData, boolean isLoading); 13 | 14 | public void loginExpired(); 15 | } 16 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/view/RetryView.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) 2013 DuoKan TV Group 3 | * 4 | * RetryLoadingView.java 5 | * 6 | * @author xuanmingliu(liuxuanming@duokan.com) 7 | * 8 | * 2013-4-15 9 | */ 10 | 11 | package com.mothership.tvhome.view; 12 | 13 | import android.content.Context; 14 | import android.util.AttributeSet; 15 | import android.view.Gravity; 16 | import android.view.View; 17 | import android.widget.FrameLayout; 18 | import android.widget.TextView; 19 | import com.mothership.tvhome.*; 20 | 21 | 22 | /** 23 | *@author xuanmingliu 24 | * 25 | */ 26 | 27 | public class RetryView extends FrameLayout{ 28 | 29 | public OnRetryLoadListener onRetryLoadListener; 30 | private TextView mTitle; 31 | public static int STYLE_NORMAL = 0; 32 | public static int STYLE_LIGHT = 1; 33 | private int style = STYLE_NORMAL; 34 | 35 | public interface OnRetryLoadListener { 36 | public void OnRetryLoad(View vClicked); 37 | } 38 | 39 | public RetryView(Context context, AttributeSet attrs, int defStyle) { 40 | super(context, attrs, defStyle); 41 | init(); 42 | } 43 | 44 | public RetryView(Context context, AttributeSet attrs) { 45 | this(context, attrs, 0); 46 | } 47 | 48 | public RetryView(Context context, int style) { 49 | super(context); 50 | this.style = style; 51 | init(); 52 | } 53 | 54 | public RetryView(Context context) { 55 | this(context, null, 0); 56 | } 57 | 58 | private void init() { 59 | View vContent = null; 60 | vContent = View.inflate(getContext(), R.layout.reload_view_dark, null); 61 | mTitle = (TextView) vContent.findViewById(R.id.retry_view_title); 62 | this.setOnClickListener(new OnClickListener() { 63 | 64 | @Override 65 | public void onClick(View v) { 66 | if( onRetryLoadListener != null) { 67 | onRetryLoadListener.OnRetryLoad(v); 68 | } 69 | } 70 | }); 71 | 72 | LayoutParams ltParams = new LayoutParams(LayoutParams.WRAP_CONTENT, 73 | LayoutParams.WRAP_CONTENT); 74 | ltParams.gravity = Gravity.CENTER; 75 | vContent.setLayoutParams(ltParams); 76 | addView(vContent); 77 | } 78 | 79 | public void setTitle(int res){ 80 | if(mTitle != null){ 81 | mTitle.setText(res); 82 | } 83 | } 84 | 85 | public void setTitle(String res){ 86 | if(mTitle != null){ 87 | mTitle.setText(res); 88 | } 89 | } 90 | 91 | public void setOnRetryLoadListener(OnRetryLoadListener onRetryLoadListener) { 92 | this.onRetryLoadListener = onRetryLoadListener; 93 | } 94 | } 95 | 96 | 97 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/BlockAdapter.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.support.v17.leanback.widget.ArrayObjectAdapter; 4 | import android.support.v17.leanback.widget.Presenter; 5 | import android.support.v17.leanback.widget.PresenterSelector; 6 | 7 | import com.tv.ui.metro.model.Block; 8 | import com.tv.ui.metro.model.DisplayItem; 9 | 10 | /** 11 | * Created by wangwei on 3/4/16. 12 | */ 13 | public class BlockAdapter extends ArrayObjectAdapter { 14 | public Block mBlock; 15 | public boolean mHasBlocks = false; 16 | /** 17 | * Constructs an adapter with the given {@link PresenterSelector}. 18 | */ 19 | public BlockAdapter(Block block,PresenterSelector presenterSelector) { 20 | super(presenterSelector); 21 | mBlock = block; 22 | if(mBlock.blocks==null){ 23 | mHasBlocks = false; 24 | }else{ 25 | mHasBlocks = true; 26 | } 27 | } 28 | 29 | /** 30 | * Constructs an adapter that uses the given {@link Presenter} for all items. 31 | */ 32 | public BlockAdapter(Block block,Presenter presenter) { 33 | super(presenter); 34 | mBlock = block; 35 | if(mBlock.blocks==null){ 36 | mHasBlocks = false; 37 | }else{ 38 | mHasBlocks = true; 39 | } 40 | } 41 | 42 | /** 43 | * Constructs an adapter. 44 | */ 45 | public BlockAdapter(Block block) { 46 | super(); 47 | mBlock = block; 48 | if(mBlock.blocks==null){ 49 | mHasBlocks = false; 50 | }else{ 51 | mHasBlocks = true; 52 | } 53 | } 54 | 55 | @Override 56 | public int size() { 57 | if(mHasBlocks){ 58 | return mBlock.blocks.size(); 59 | }else if(mBlock.items!=null){ 60 | return mBlock.items.size(); 61 | } 62 | return 0; 63 | } 64 | 65 | @Override 66 | public Object get(int index) { 67 | if(mHasBlocks){ 68 | return mBlock.blocks.get(index); 69 | }else if(mBlock.items!=null){ 70 | return mBlock.items.get(index); 71 | } 72 | return null; 73 | } 74 | 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/BlockHorizontalPresenter.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.view.ViewGroup; 4 | 5 | import com.mothership.tvhome.R; 6 | 7 | /** 8 | * Created by wangwei on 2/29/16. 9 | */ 10 | public class BlockHorizontalPresenter extends BlockBasePresenter{ 11 | 12 | @Override 13 | protected BlockBasePresenter.ViewHolder createBlockViewHolder(ViewGroup parent) { 14 | BlockView rowView = new BlockView(parent.getContext()); 15 | rowView.initLayout(R.layout.block_horizontal); 16 | return new BlockBasePresenter.ViewHolder(rowView, rowView.getGridView(), this); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/BlockPresenterSelector.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.support.v17.leanback.widget.Presenter; 4 | import android.support.v17.leanback.widget.PresenterSelector; 5 | import android.util.SparseArray; 6 | 7 | import com.mothership.tvhome.Utils; 8 | import com.tv.ui.metro.model.DisplayItem; 9 | 10 | /** 11 | * Created by wangwei on 3/10/16. 12 | */ 13 | public class BlockPresenterSelector extends PresenterSelector { 14 | SparseArray mPresenters = new SparseArray(); 15 | BlockVerticalPresenter mVerticalPresenter = new BlockVerticalPresenter(); 16 | BlockHorizontalPresenter mHorizontalPresenter = new BlockHorizontalPresenter(); 17 | TVhomBlockPresenter mTVhomBlockPresenter = new TVhomBlockPresenter(); 18 | public BlockPresenterSelector() 19 | { 20 | mPresenters.put(0, mTVhomBlockPresenter); 21 | mPresenters.put(1, mVerticalPresenter); 22 | mPresenters.put(11, new BlockGridPresenter()); 23 | } 24 | @Override 25 | public Presenter getPresenter(Object item) { 26 | DisplayItem di = (DisplayItem) item; 27 | DisplayItem.UI type = di.ui_type; 28 | int id = Utils.UiNameToId(di); 29 | if(type != null) 30 | { 31 | return mPresenters.get(id/100%100, mVerticalPresenter); 32 | } 33 | else 34 | { 35 | //Log.d(TAG, di.title + " doesn't has ui_type"); 36 | //return mDefaultPresenter; 37 | } 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/BlockVerticalPresenter.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.view.ViewGroup; 4 | 5 | import com.mothership.tvhome.R; 6 | 7 | /** 8 | * Created by wangwei on 3/4/16. 9 | */ 10 | public class BlockVerticalPresenter extends BlockBasePresenter{ 11 | 12 | @Override 13 | protected BlockBasePresenter.ViewHolder createBlockViewHolder(ViewGroup parent) { 14 | BlockView rowView = new BlockView(parent.getContext()); 15 | rowView.initLayout(R.layout.block_vertical); 16 | return new ViewHolder(rowView, rowView.getGridView(), this); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/BlockView.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.util.AttributeSet; 6 | import android.view.LayoutInflater; 7 | import android.view.ViewGroup; 8 | import android.widget.FrameLayout; 9 | 10 | import com.mothership.tvhome.R; 11 | 12 | /** 13 | * Created by wangwei on 3/7/16. 14 | */ 15 | public class BlockView extends FrameLayout { 16 | 17 | private RecyclerView mGridView; 18 | private boolean mIsVertical = false; 19 | 20 | public BlockView(Context context) { 21 | this(context, null); 22 | } 23 | 24 | public BlockView(Context context, AttributeSet attrs) { 25 | this(context, attrs, 0); 26 | } 27 | 28 | public BlockView(Context context, AttributeSet attrs, int defStyle) { 29 | super(context, attrs, defStyle); 30 | 31 | } 32 | 33 | protected void initLayout(int resId){ 34 | LayoutInflater inflater = LayoutInflater.from(getContext()); 35 | 36 | inflater.inflate(resId, this); 37 | mGridView = (RecyclerView) findViewById(R.id.block_content); 38 | 39 | // Uncomment this to experiment with page-based scrolling. 40 | // mGridView.setFocusScrollStrategy(HorizontalGridView.FOCUS_SCROLL_PAGE); 41 | 42 | setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 43 | /*if(mGridView instanceof HorizontalGridView){ 44 | HorizontalGridView view = (HorizontalGridView)mGridView; 45 | view.setFocusScrollStrategy(HorizontalGridView.FOCUS_SCROLL_ALIGNED); 46 | }else if(mGridView instanceof VerticalGridView){ 47 | VerticalGridView view = (VerticalGridView)mGridView; 48 | view.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED); 49 | }*/ 50 | //mGridView.setFocusable(false); 51 | 52 | } 53 | /** 54 | * Returns the HorizontalGridView. 55 | */ 56 | public RecyclerView getGridView() { 57 | return mGridView; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/CardPresenterSelector.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.support.v17.leanback.widget.Presenter; 4 | import android.support.v17.leanback.widget.PresenterSelector; 5 | 6 | import com.tv.ui.metro.model.DisplayItem; 7 | 8 | /** 9 | * Created by wangwei on 2/29/16. 10 | */ 11 | public class CardPresenterSelector extends PresenterSelector{ 12 | private final Presenter mPresenterPort = new CardPresenter(); 13 | private final Presenter mPresenterLand = new LandCardPresenter(); 14 | private final Presenter[] mPresenters = new Presenter[] { 15 | mPresenterPort, mPresenterLand}; 16 | @Override 17 | public Presenter getPresenter(Object item) { 18 | DisplayItem displayItem = (DisplayItem)item; 19 | if(displayItem.id!=null&&displayItem.id.equals("land")){ 20 | return mPresenterLand; 21 | }else{ 22 | return mPresenterPort; 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/ChannelPresenter.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.content.Context; 4 | import android.support.v17.leanback.widget.ItemBridgeAdapterShadowOverlayWrapper; 5 | import android.support.v17.leanback.widget.Presenter; 6 | import android.support.v17.leanback.widget.ShadowOverlayHelper; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | 11 | import com.mothership.tvhome.view.ChannelContainer; 12 | import com.mothership.tvhome.view.DiViewT2; 13 | import com.tv.ui.metro.model.Image; 14 | 15 | import java.sql.Wrapper; 16 | 17 | /** 18 | * Created by Shawn on 16/3/15. 19 | */ 20 | public class ChannelPresenter extends Presenter 21 | { 22 | ItemBridgeAdapterShadowOverlayWrapper mWrapper; 23 | 24 | @Override 25 | public ViewHolder onCreateViewHolder(ViewGroup parent) 26 | { 27 | DiViewT2 t2 = new DiViewT2(parent.getContext(), null); 28 | 29 | ImageView img = new ImageView(parent.getContext()); 30 | t2.addView(img); 31 | t2.setFocusable(true); 32 | t2.setFocusableInTouchMode(true); 33 | return new Presenter.ViewHolder(t2); 34 | } 35 | 36 | @Override 37 | public void onBindViewHolder(ViewHolder viewHolder, Object item) 38 | { 39 | ((ImageView)((ViewGroup)viewHolder.view).getChildAt(0)).setImageResource(((Integer) item).intValue()); 40 | } 41 | 42 | @Override 43 | public void onUnbindViewHolder(ViewHolder viewHolder) 44 | { 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/DisplayItemSelector.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.support.v17.leanback.widget.Presenter; 4 | import android.support.v17.leanback.widget.PresenterSelector; 5 | import android.util.Log; 6 | import android.util.SparseArray; 7 | 8 | import com.mothership.tvhome.Utils; 9 | import com.tv.ui.metro.model.DisplayItem; 10 | 11 | /** 12 | * Created by Shawn on 16/3/8. 13 | */ 14 | public class DisplayItemSelector extends PresenterSelector 15 | { 16 | private static final String TAG = "DisplayItemSelector"; 17 | SparseArray mPresenters = new SparseArray(); 18 | BasePresenter mDefaultPresenter = new BasePresenter(); 19 | 20 | public DisplayItemSelector() 21 | { 22 | mPresenters.put(1, mDefaultPresenter); 23 | mPresenters.put(2, new PresenterT2()); 24 | mPresenters.put(3, new PresenterT3()); 25 | } 26 | @Override 27 | public Presenter getPresenter(Object aItem) 28 | { 29 | DisplayItem di = (DisplayItem) aItem; 30 | DisplayItem.UI type = di.ui_type; 31 | // return mDefaultPresenter; 32 | int id = Utils.UiNameToId(di); 33 | if(type != null) 34 | { 35 | 36 | Log.d(TAG, "type " + type.id()); 37 | return mPresenters.get(id%100, mDefaultPresenter); 38 | } 39 | else 40 | { 41 | Log.d(TAG, di.title + " doesn't has ui_type"); 42 | return mDefaultPresenter; 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/mothership/tvhome/widget/FocusVerticalGridView.java: -------------------------------------------------------------------------------- 1 | package com.mothership.tvhome.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.support.v17.leanback.widget.VerticalGridView; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | 9 | /** 10 | * Created by wangwei on 3/22/16. 11 | */ 12 | public class FocusVerticalGridView extends VerticalGridView { 13 | final String TAG = "FocusVerticalGridView"; 14 | 15 | public FocusVerticalGridView(Context context) { 16 | this(context, null); 17 | } 18 | 19 | public FocusVerticalGridView(Context context, AttributeSet attrs) { 20 | this(context, attrs, 0); 21 | } 22 | 23 | public FocusVerticalGridView(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | } 26 | 27 | @Override 28 | public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 29 | 30 | int index; 31 | int increment; 32 | int end; 33 | int count = getChildCount(); 34 | if((direction & FOCUS_UP) != 0) { 35 | Rect better = new Rect(); 36 | getChildAt(0).getFocusedRect(better); 37 | this.offsetDescendantRectToMyCoords(getChildAt(0), better); 38 | int pos = 0; 39 | for (int i = 1; i != count; i += 1) { 40 | View child = getChildAt(i); 41 | if (child.getVisibility() == VISIBLE) { 42 | Rect rect = new Rect(); 43 | getChildAt(i).getFocusedRect(rect); 44 | this.offsetDescendantRectToMyCoords(getChildAt(i), rect); 45 | if(rect.bottom>better.bottom){ 46 | better = rect; 47 | pos = i; 48 | } 49 | } 50 | } 51 | if(pos extends DisplayItem implements Serializable { 10 | private static final long serialVersionUID = 2L; 11 | public Filter filters; 12 | public ArrayList items; 13 | public ArrayList> blocks; 14 | public ArrayList> footers; 15 | 16 | public String toString(){ 17 | return "\n\nBlock: " + super.toString() +" \n\titems:"+items + "\n\tend\n\n\n"; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/GenericBlock.java: -------------------------------------------------------------------------------- 1 | package com.tv.ui.metro.model; 2 | 3 | import java.io.Serializable; 4 | import java.text.SimpleDateFormat; 5 | import java.util.ArrayList; 6 | import java.util.Date; 7 | import java.util.HashMap; 8 | 9 | /** 10 | * Created by liuhuadong on 9/23/14. 11 | */ 12 | public class GenericBlock implements Serializable { 13 | private static final long serialVersionUID = 3L; 14 | public HashMap header; 15 | public HashMap ui_type; 16 | public ArrayList> blocks; 17 | public DisplayItem.Times times; 18 | 19 | public String toString() { 20 | StringBuilder sb = new StringBuilder(); 21 | sb.append(" GenericBlock: "); 22 | 23 | if(times != null) 24 | sb.append("update_time=" + dateToString(new Date(times.updated))); 25 | 26 | sb.append("\n"); 27 | return sb.toString(); 28 | } 29 | 30 | public static String dateToString(Date time){ 31 | SimpleDateFormat formatter; 32 | formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 33 | String ctime = formatter.format(time); 34 | 35 | return ctime; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/ImageGroup.java: -------------------------------------------------------------------------------- 1 | package com.tv.ui.metro.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public class ImageGroup extends HashMap implements Serializable{ 7 | private static final long serialVersionUID = 5L; 8 | public Image back(){return get("back");} 9 | public Image big(){return get("big");} 10 | public Image fuzzy(){return get("fuzzy");} 11 | public Image icon(){return get("icon");} 12 | public Image spirit(){return get("spirit");} 13 | public Image text(){return get("text");} 14 | public Image thumbnail(){return get("thumbnail");} 15 | public Image screenshot(){return get("screenshot");} 16 | public Image poster(){return get("poster");} 17 | public Image smallerPoster(){return get("poster");} 18 | public Image normal(){return get("normal");} 19 | public Image pressed(){return get("pressed");} 20 | public Image left_top_corner(){return get("left_top_corner");} 21 | public Image right_top_corner(){return get("right_top_corner");} 22 | public Image bottom(){return get("bottom");} 23 | 24 | public ImageGroup clone(){ 25 | ImageGroup item = new ImageGroup(); 26 | if(back() != null)item.put("back", back().clone()); 27 | if(big() != null)item.put("big", big().clone()); 28 | 29 | if(fuzzy() != null)item.put("fuzzy", fuzzy().clone()); 30 | if(icon() != null)item.put("icon", icon().clone()); 31 | if(spirit() != null)item.put("spirit", spirit().clone()); 32 | if(text() != null)item.put("text", text().clone()); 33 | if(thumbnail() != null)item.put("thumbnail", thumbnail().clone()); 34 | if(screenshot() != null)item.put("screenshot", screenshot().clone()); 35 | if(normal() != null)item.put("normal", normal().clone()); 36 | if(pressed() != null)item.put("pressed", pressed().clone()); 37 | return item; 38 | } 39 | public String toString(){ 40 | StringBuilder sb = new StringBuilder(); 41 | sb.append("ImageGroup: \tposter="+poster()); 42 | sb.append(" \ticon="+icon()); 43 | sb.append(" \tnormal="+normal()); 44 | sb.append(" \tpressed="+pressed()); 45 | return sb.toString(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/PlaySource.java: -------------------------------------------------------------------------------- 1 | package com.tv.ui.metro.model; 2 | 3 | import com.google.gson.JsonObject; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * Created by liuhuadonbg on 1/27/15. 8 | * 9 | * 10 | { 11 | "app_info": {}, 12 | "cp": "iqiyi", 13 | "cp_id": "288655700", 14 | "h5_url": "http://m.iqiyi.com/v_19rrmjn3ug.html", 15 | "id": "v001804745", 16 | "pc_url": "http://www.iqiyi.com/v_19rrmjn3ug.html?src=3_69_145", 17 | "sdk_url": "", 18 | "vid": "V001123291" 19 | } 20 | */ 21 | public class PlaySource implements Serializable{ 22 | private static final long serialVersionUID = 1L; 23 | public String cp; 24 | public int cp_code; 25 | public String cp_id; // media ID from CP 26 | public String h5_url; 27 | public String id; 28 | public String pc_url; 29 | public String sdk_url; 30 | public String vid; 31 | public boolean h5_preferred; 32 | 33 | public JsonObject app_info; 34 | public JsonObject app_infos; //all the cps info 35 | public boolean offline; 36 | public DisplayItem.Settings extra; 37 | 38 | public String toString(){ 39 | return "cp: "+cp + " cp_id:"+cp_id + " h5_url:"+h5_url + " id:"+id + " pc_url:"+pc_url + " sdk_url:"+sdk_url + " vid:"+vid + " app_info:"+app_info +" app_infos:"+app_infos; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/TokenInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright(c) 2012 DuoKan TV Group 3 | * 4 | * TokenInfo.java 5 | * 6 | * @author tianli(tianli@duokan.com) 7 | * 8 | * 2012-9-6 9 | */ 10 | package com.tv.ui.metro.model; 11 | 12 | import android.text.TextUtils; 13 | 14 | import java.io.Serializable; 15 | 16 | /** 17 | * @author tianli 18 | * 19 | */ 20 | public class TokenInfo implements Serializable { 21 | 22 | private static final long serialVersionUID = 4L; 23 | public static final String AUTH_TOKEY_TYPE_XIAOMI = "video"; 24 | public static final String AUTH_TOKEY_TYPE_BSS = "tvideo"; 25 | 26 | public TokenInfo(){ 27 | tick = System.currentTimeMillis(); 28 | } 29 | 30 | public long tick; 31 | public String uid; // unique identifier for device 32 | public UserAccount userAccount; // token info for XiaoMi account. 33 | public LoginData loginData; 34 | // public String userToken; 35 | // public String userKey; 36 | 37 | public UserAccount bssUserAccount; 38 | 39 | public void setUserAccount(String accountName, String authToken, String ssec, String tokenType){ 40 | if (AUTH_TOKEY_TYPE_XIAOMI.equals(tokenType)){ 41 | if (userAccount == null) 42 | userAccount = new UserAccount(); 43 | 44 | if (!TextUtils.isEmpty(accountName)){ 45 | userAccount.accountName = accountName; 46 | } 47 | userAccount.authToken = authToken; 48 | userAccount.ssec = ssec; 49 | }else if (AUTH_TOKEY_TYPE_BSS.equals(tokenType)){ 50 | if (bssUserAccount == null) 51 | bssUserAccount = new UserAccount(); 52 | 53 | if (!TextUtils.isEmpty(accountName)){ 54 | bssUserAccount.accountName = accountName; 55 | } 56 | bssUserAccount.authToken = authToken; 57 | bssUserAccount.ssec = ssec; 58 | } 59 | } 60 | 61 | public void setLoginData(String access_key, String access_token){ 62 | if (loginData == null){ 63 | loginData = new LoginData(); 64 | } 65 | 66 | loginData.access_token = access_token; 67 | loginData.access_key = access_key; 68 | } 69 | 70 | //after auth from server 71 | public static class UserAccount implements Serializable { 72 | private static final long serialVersionUID = 2L; 73 | 74 | public String accountName; //mi id 75 | public String authToken; //for sign 76 | public String ssec; //for sign 77 | public String tokenType; 78 | } 79 | 80 | public static class LoginData implements Serializable { 81 | public int level; 82 | public String access_token; 83 | public String access_key; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/VideoBlocks.java: -------------------------------------------------------------------------------- 1 | package com.tv.ui.metro.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | 6 | /** 7 | * Created by liuhuadonbg on 1/24/15. 8 | */ 9 | public class VideoBlocks implements Serializable { 10 | private static final long serialVersionUID = 1L; 11 | public ArrayList blocks; 12 | 13 | public String toString(){ 14 | return "\n\nVideoBlocks: blocks:"+blocks + "\n\tend\n\n\n"; 15 | } 16 | } -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/VideoItem.java: -------------------------------------------------------------------------------- 1 | package com.tv.ui.metro.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | 7 | /** 8 | * Created by liuhuadong on 12/1/14. 9 | */ 10 | public class VideoItem extends DisplayItem { 11 | private static final long serialVersionUID = 2L; 12 | 13 | public ArrayList> blocks; 14 | 15 | public ArrayList> headers; 16 | } 17 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/tv/ui/metro/model/XiaomiStatistics.java: -------------------------------------------------------------------------------- 1 | package com.tv.ui.metro.model; 2 | 3 | 4 | /** 5 | * Created by liuhuadonbg on 4/18/15. 6 | */ 7 | public class XiaomiStatistics { 8 | public static final String AppID = "2882303761517147566"; 9 | public static final String AppKey = "5481714735566"; 10 | public static final String AppSecret = "YP8heNSP0BWdA1P8rCXiMA=="; 11 | 12 | public static final String CHANNEL = "miphone"; 13 | public static final String MiMarket_CHANNEL = "mimarket-v5"; 14 | public static final String DisplayItemLaunch = "DisplayItemLaunch"; 15 | public static final String VersionCheck = "VersionCheck"; 16 | public static final String TAB = "tab"; 17 | public static final String DETAIL_TAB = "detail_tab"; 18 | public static final String Offline = "offline"; 19 | public static final String Advertise = "advertise"; 20 | public static final String Star = "actor"; 21 | public static final String VersionChange = "VersionChange"; 22 | public static final String UserOffline = "user-offline"; 23 | public static final String action_click = "action_click"; 24 | public static final String from_push_click = "from_push_click"; 25 | public static final String api_call_ref = "api_call_ref"; 26 | public static final String api_call_ref_detail= "api_call_ref_detail"; 27 | public static final String play_click = "play_click"; 28 | public static final String app_install = "app_install"; 29 | public static final String Video_share = "video_share"; 30 | public static final String VersionUpgrade = "version_upgrade"; 31 | public static final String VersionDownload = "version_download"; 32 | public static final String local_play = "local_play"; 33 | public static final String Actor_share = "actor_share"; 34 | 35 | public static final String episode_play = "episode_play"; 36 | 37 | public static final String ads_record = "ads_record"; 38 | 39 | public static final String VIP = "vip"; 40 | 41 | public static boolean initialed = false; 42 | 43 | //change by manual 44 | public static boolean mimarket_version = true; 45 | } 46 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/cp/model/AppPluginCpInfo.java: -------------------------------------------------------------------------------- 1 | package com.video.cp.model; 2 | 3 | /** 4 | * Created by lijianbo1 on 15-3-25. 5 | */ 6 | public class AppPluginCpInfo extends BaseEpItem { 7 | 8 | public AppPluginCpInfo(RawCpItem item) { 9 | copyFrom(item); 10 | } 11 | 12 | 13 | // define specific get method for convenience 14 | public String toString() { 15 | StringBuilder sb = new StringBuilder() 16 | .append(super.toString()); 17 | // add more field output 18 | 19 | return sb.toString(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/cp/model/RawCpItem.java: -------------------------------------------------------------------------------- 1 | package com.video.cp.model; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Created by lijianbo1 on 15-3-31. 7 | */ 8 | public class RawCpItem { 9 | public String name; 10 | public String id; 11 | public String icon; 12 | 13 | public RawAppItem app; 14 | public RawPluginItem plugin; 15 | 16 | static class RawAppItem { 17 | public String apk_url; 18 | public String desc; 19 | 20 | @Override 21 | public String toString() { 22 | return "RawAppItem{" + 23 | "apk_url='" + apk_url + '\'' + 24 | ", desc='" + desc + '\'' + 25 | '}'; 26 | } 27 | } 28 | 29 | static class RawPluginItem { 30 | public String type; 31 | public String url; 32 | public String md5; 33 | public String version_name; 34 | public String version; 35 | public String updated_at; 36 | public HashMap params; 37 | 38 | @Override 39 | public String toString() { 40 | return "RawPluginItem{" + 41 | ", type='" + type + '\'' + 42 | ", url='" + url + '\'' + 43 | ", md5='" + md5 + '\'' + 44 | ", version_name='" + version_name + '\'' + 45 | ", version'" + version + '\'' + 46 | ", updated_at='" + updated_at + '\'' + 47 | ", params=" + params + 48 | '}'; 49 | } 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return "RawCpItem{" + 55 | "name='" + name + '\'' + 56 | ", id='" + id + '\'' + 57 | ", icon='" + icon + '\'' + 58 | ", app=" + app + 59 | ", plugin=" + plugin + 60 | '}'; 61 | } 62 | 63 | public String getItemType() { 64 | if (plugin != null) { 65 | return plugin.type; 66 | } 67 | return null; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/cp/model/VideoPlayerConstant.java: -------------------------------------------------------------------------------- 1 | package com.video.cp.model; 2 | 3 | /** 4 | * Created by lijianbo1 on 15-7-17. 5 | */ 6 | public class VideoPlayerConstant { 7 | 8 | 9 | // Version History: 10 | // 20150428 -- support plugin context - all 11 | // 20150604 -- PPTV sport activity plugin support 12 | // 20150713 -- optimized offline solution (H5 Video URL Retrieve) (YouKu autoplay, autoplay js config) 13 | // 20150716 -- support cloud setting to enable offline CP even if it is configured as disable offline 14 | // 20150818 -- support PluginContext.getHostActivity() PluginContext.getSoLibPath() 15 | // 20150826 -- add more info for app_apk_plugin installation / launching (cancelable, show_start_donwload dialog, always launch app 16 | // 20150827 -- improve for iqiyi mini APK 17 | // 20150911 -- support server changes WebView UA for offline url retrieval 18 | // 20151106 -- support iqiyi vip 19 | // 20151111 -- support iqiyi offline download 20 | // 20151125 -- [server] update for AD API 21 | public static final String VERSION = "20151125"; 22 | } 23 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/Action.java: -------------------------------------------------------------------------------- 1 | package com.video.search; 2 | 3 | /** 4 | * Action Constants 5 | * 6 | * Created by zhuzhenhua on 16-1-7. 7 | */ 8 | public class Action { 9 | 10 | public static final String ACTION_ALBUM = "com.mitv.ACTION.VIDEO_ALBUM"; 11 | public static final String ACTION_CHANNEL = "android.intent.action.MITV_VIDEO_CHANNEL"; 12 | public static final String ACTION_RANK = "android.intent.action.MITV_VIDEO_RANK"; 13 | public static final String ACTION_WORKS = "android.intent.action.MITV_VIDEO_CINEASTE_WORKS"; 14 | public static final String ACTION_SEARCH = "android.intent.action.MITV_VIDEO_SEARCH"; 15 | public static final String ACTION_SEARCH_CINEASTE = "android.intent.action.MITV_VIDEO_SEARCH_CINEASTE"; 16 | public static final String ACTION_FAVORITE = "android.intent.action.MITV_VIDEO_FAVORITE"; 17 | public static final String ACTION_PLAY_RECORD = "android.intent.action.MITV_VIDEO_PLAY_RECORD"; 18 | public static final String ACTION_BUY_VIP = "android.intent.action.MITV_VIDEO_BUY_VIP"; 19 | public static final String ACTION_PAID = "android.intent.action.MITV_PAID"; 20 | public static final String ACTION_EXCHANGE = "android.intent.action.MITV_EXCHANGE"; 21 | public static final String ACTION_UPDATE_DIALOG = "android.intent.action.UPDATE_DIALOG"; 22 | public static final String ACTION_API = "android.intent.action.VIDEO_API"; 23 | public static final String ACTION_COLLECTION = "android.intent.action.VIDEO_MI_LIST_COLLECTION"; 24 | public static final String ACTION_DETAILS = "android.intent.action.MITV_VIDEO_DETAILS"; 25 | public static final String ACTION_PAID_RECORD = "android.intent.action.MITV_PAIDRECORD"; 26 | } 27 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/Constants.java: -------------------------------------------------------------------------------- 1 | package com.video.search; 2 | 3 | /** 4 | * 常量 5 | * 6 | * Created on 15-12-7. 7 | */ 8 | public class Constants { 9 | 10 | public static final String API_TOKEN = "0f9dfa001cba164d7bda671649c50abf"; 11 | public static final String API_SECRET_KEY = "581582928c881b42eedce96331bff5d3"; 12 | 13 | public static final String DEF_SEPARATOR = " "; 14 | public static final String SEPARATOR = " | "; 15 | 16 | public static final String RANK_TYPE_HOT = "10001";// 热播榜 17 | public static final String RANK_TYPE_LATEST = "10003";// 最新上线 18 | public static final String RANK_TYPE_COLLECTION = "10004";// 收藏榜 19 | public static final String RANK_TYPE_STAR = "10006";// 影人榜/明星榜 20 | 21 | public static final int ID_BASE = 1; 22 | 23 | public static final int DEF_DELAY_TIME = 250; 24 | public static final int DEF_GRID_LAYOUT_COL_COUNT = 6;// 格式布局的默认列数 25 | public static final int DEF_MI_LIST_COL_COUNT = 3; 26 | public static final int DEF_WORKS_COL_COUNT = 5; 27 | public static final int DEF_EPISODE_COL_COUNT = 2; 28 | 29 | public static final int DISPLAY_1_ROW = 0; 30 | public static final int DISPLAY_2_ROW = 1; 31 | public static final int DISPLAY_1_OR_2_ROW = 2; 32 | 33 | public static final int MEDIA_TYPE_MORE = 1; 34 | public static final int MEDIA_TYPE_ALL = 2; 35 | public static final int DISPLAY_TYPE_END_WITH_MORE = 1; 36 | 37 | public static final int GENDER_MALE = 1; 38 | public static final int GENDER_FEMALE = 2; 39 | 40 | public static final int PIXEL_DEVIATION = 100; 41 | 42 | public static final float PIC_METRO_VER_WH_RATIO = 402 / 606f; 43 | public static final float PIC_VER_WH_RATIO = 412 / 600f; 44 | public static final float PIC_HOR_WH_RATIO = 606 / 300f;// 780 × 350 45 | } 46 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/CommonUrl.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | import android.util.Log; 4 | 5 | import com.video.search.Config; 6 | import com.video.search.Constants; 7 | import com.video.utils.Tools; 8 | 9 | import java.net.MalformedURLException; 10 | import java.net.URL; 11 | 12 | public class CommonUrl { 13 | 14 | private static final String TAG = "CommonUrl"; 15 | private CommonUrlBuilder mUrlBuilder; 16 | 17 | 18 | public CommonUrl(String url) { 19 | mUrlBuilder = new CommonUrlBuilder(Config.HOST + url); 20 | } 21 | 22 | public CommonUrl(String host, String url) { 23 | mUrlBuilder = new CommonUrlBuilder(host + url); 24 | } 25 | 26 | public void putParam(String key, String value) { 27 | mUrlBuilder.put(key, value); 28 | } 29 | 30 | public String build() { 31 | String res = build(Constants.API_TOKEN, Constants.API_SECRET_KEY); 32 | Log.d(TAG, "build " + res); 33 | return res; 34 | } 35 | 36 | public String build(String token, String key) { 37 | //TODO:use real dev info ptf=207&codever=1&deviceid=deb49000000000000000000000000001 38 | mUrlBuilder.put("ptf", "207"); 39 | mUrlBuilder.put("codever", "15"); 40 | mUrlBuilder.put("deviceid", "deb49000000000000000000000000001"); 41 | 42 | String url = mUrlBuilder.toUrl(); 43 | String path; 44 | try { 45 | path = new URL(url).getPath(); 46 | } catch (MalformedURLException e) { 47 | return url; 48 | } 49 | 50 | int indexOfPath = url.indexOf(path); 51 | String strForSign = url.substring(indexOfPath); 52 | String sign = Tools.genSignature(strForSign, token, key); 53 | mUrlBuilder.put("opaque", sign); 54 | 55 | return mUrlBuilder.toUrl(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/CommonUrlBuilder.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.UnsupportedEncodingException; 6 | import java.net.URLEncoder; 7 | import java.util.Iterator; 8 | import java.util.LinkedHashMap; 9 | import java.util.Map; 10 | 11 | public class CommonUrlBuilder { 12 | 13 | private String mBaseUrl; 14 | private StringBuilder mStringBuilder; 15 | private Map mParamsMap; 16 | private boolean mIsFirstAdd = true; 17 | 18 | private static final String QUESTION_MARK = "?"; 19 | private static final String EQUAL = "="; 20 | private static final String AMPERSAND = "&"; 21 | private static final String UTF_8 = "UTF-8"; 22 | 23 | public CommonUrlBuilder(String baseUrl) { 24 | mBaseUrl = baseUrl; 25 | mParamsMap = new LinkedHashMap<>(); 26 | } 27 | 28 | public void put(String name, String value) { 29 | mParamsMap.put(name, value); 30 | } 31 | 32 | public void remove(String name) { 33 | mParamsMap.remove(name); 34 | } 35 | 36 | public String toUrl() { 37 | if (TextUtils.isEmpty(mBaseUrl) || mParamsMap.size() == 0) { 38 | return mBaseUrl; 39 | } 40 | this.mStringBuilder = new StringBuilder(mBaseUrl); 41 | mIsFirstAdd = true; 42 | 43 | Iterator it = mParamsMap.keySet().iterator(); 44 | while (it.hasNext()) { 45 | String key = it.next(); 46 | String value = mParamsMap.get(key); 47 | if (mIsFirstAdd) { 48 | mIsFirstAdd = false; 49 | if (mStringBuilder.indexOf(QUESTION_MARK) < 1) { 50 | // does not contain "?" 51 | mStringBuilder.append(QUESTION_MARK); 52 | encode(key, value); 53 | } else { 54 | // contains "?" 55 | mStringBuilder.append(AMPERSAND); 56 | encode(key, value); 57 | } 58 | } else { 59 | mStringBuilder.append(AMPERSAND); 60 | encode(key, value); 61 | } 62 | } 63 | 64 | return mStringBuilder.toString(); 65 | } 66 | 67 | private void encode(String name, String value) { 68 | try { 69 | mStringBuilder.append(URLEncoder.encode(name, UTF_8)); 70 | mStringBuilder.append(EQUAL); 71 | mStringBuilder.append(URLEncoder.encode(value, UTF_8)); 72 | } catch (UnsupportedEncodingException uee) { 73 | throw new RuntimeException("VM does not support UTF-8 encoding"); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/MyGlideModule.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | import android.content.Context; 4 | 5 | import com.bumptech.glide.Glide; 6 | import com.bumptech.glide.GlideBuilder; 7 | import com.bumptech.glide.load.DecodeFormat; 8 | import com.bumptech.glide.module.GlideModule; 9 | 10 | public class MyGlideModule implements GlideModule { 11 | 12 | @Override 13 | public void applyOptions(Context context, GlideBuilder builder) { 14 | builder.setDecodeFormat(DecodeFormat.PREFER_RGB_565); 15 | 16 | /* MemorySizeCalculator calculator = new MemorySizeCalculator(context); 17 | int defaultMemoryCacheSize = calculator.getMemoryCacheSize(); 18 | int defaultBitmapPoolSize = calculator.getBitmapPoolSize(); 19 | 20 | int customMemoryCacheSize = (int) (0.1f * defaultMemoryCacheSize); 21 | int customBitmapPoolSize = (int) (0.1f * defaultBitmapPoolSize); 22 | 23 | builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize)); 24 | builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize));*/ 25 | } 26 | 27 | @Override 28 | public void registerComponents(Context context, Glide glide) { 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/Params.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | public interface Params { 4 | 5 | String VERSION = "version"; 6 | String DEVICE = "device"; 7 | String STATUS = "status"; 8 | 9 | String INVOKER = "invoker"; 10 | String INVOKER_INT = "invokerInt"; 11 | 12 | String ID = "id"; 13 | String NAME = "name"; 14 | String PASSWORD = "psw"; 15 | String TOKEN = "token"; 16 | String URL = "url"; 17 | String TYPE = "type"; 18 | String DATA = "data"; 19 | String INDEX = "index"; 20 | String COUNT = "count"; 21 | String MEDIA_ID = "mediaid"; 22 | String MEDIA_IDS = "mediaids"; 23 | String ORDER_BY = "orderby"; 24 | String LIMIT = "limit"; 25 | String CHANNEL_ID = "channelid"; 26 | String CHANNEL_IDS = "channelids"; 27 | String LIST_TYPE = "listtype"; 28 | String MEDIA_TYPE = "media_type"; 29 | String PAGE_NO = "pageno"; 30 | String PAGE_SIZE = "pagesize"; 31 | String TITLE = "title"; 32 | String PARENT_TITLE = "parentTitle"; 33 | String CHANNEL_COL = "channelcolumn"; 34 | String WIDTH = "width"; 35 | String HEIGHT = "height"; 36 | String RATING = "rating"; 37 | String CINEASTE_ID = "cineasteid"; 38 | String CINEASTE_NAME = "cineastename"; 39 | String MEDIA_NAME = "medianame"; 40 | String SEARCH_KEY = "key"; 41 | String SEARCH_TYPE = "searchtype"; 42 | String SOURCE = "source"; 43 | String CI = "ci"; 44 | String MEDIA_INFO = "mediainfo"; 45 | String MEDIA_CI_INFO = "mediaciinfo"; 46 | String STYLE = "style"; 47 | String VIDEOS = "videos"; 48 | String PRODUCT = "product"; 49 | String CP_MID = "cp_mid"; 50 | String OPEN_ID = "openID"; 51 | String PRODUCT_PRICE_LIST = "prices"; 52 | String SHOULD_LOGIN = "login"; 53 | String PAID = "paid"; 54 | String DISPLAY_TYPE = "display_type"; 55 | String API_ID = "api_id"; 56 | String API_PARAMS = "api_params"; 57 | String API_URL = "api_url"; 58 | String API_METHOD = "api_method"; 59 | String SHOW_ICON = "show_icon"; 60 | } 61 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/ResponseStatus.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | /** 4 | * Response Status 5 | * 6 | * Created by zhuzhenhua on 15-12-16. 7 | */ 8 | public enum ResponseStatus { 9 | 10 | SUCCESS(0, "OK"), 11 | EMPTY_RESULT(13, "空返回结果"), 12 | INVALID_PARAM(14, "非法参数"), 13 | USER_AUTH_FAILED(19, "签名验证错误"), 14 | SESSION_TIMEOUT(22, "超时"), 15 | INVALID_IP(28, "非法IP"), 16 | SERVER_ERROR(32, "服务器端错误"), 17 | NOT_MODIFIED(64, "数据未改变"), 18 | LIVE_STREAM_NOT_AVAILABLE(1001, "直播当前时间不可用"), 19 | LIVE_STREAM_TOKEN_ERROR(1002, "获取直播令牌出错"); 20 | 21 | public final int status; 22 | public final String msg; 23 | ResponseStatus(int status, String msg) { 24 | this.status = status; 25 | this.msg = msg; 26 | } 27 | 28 | public static ResponseStatus valueOf(int status) { 29 | ResponseStatus rs = SUCCESS; 30 | if (EMPTY_RESULT.status == status) 31 | rs = EMPTY_RESULT; 32 | else if(INVALID_PARAM.status == status) 33 | rs = INVALID_PARAM; 34 | else if(USER_AUTH_FAILED.status == status) 35 | rs = USER_AUTH_FAILED; 36 | else if(SESSION_TIMEOUT.status == status) 37 | rs = SESSION_TIMEOUT; 38 | else if(INVALID_IP.status == status) 39 | rs = INVALID_IP; 40 | else if(SERVER_ERROR.status == status) 41 | rs = SERVER_ERROR; 42 | else if(NOT_MODIFIED.status == status) 43 | rs = NOT_MODIFIED; 44 | else if(LIVE_STREAM_NOT_AVAILABLE.status == status) 45 | rs = LIVE_STREAM_NOT_AVAILABLE; 46 | else if(LIVE_STREAM_TOKEN_ERROR.status == status) 47 | rs = LIVE_STREAM_TOKEN_ERROR; 48 | return rs; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/VolleyErrorHelper.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.TypeReference; 5 | import com.android.volley.AuthFailureError; 6 | import com.android.volley.NetworkError; 7 | import com.android.volley.NetworkResponse; 8 | import com.android.volley.NoConnectionError; 9 | import com.android.volley.ServerError; 10 | import com.android.volley.TimeoutError; 11 | import com.android.volley.VolleyError; 12 | 13 | import java.util.HashMap; 14 | 15 | public class VolleyErrorHelper { 16 | 17 | public static String getMessage(Object error) { 18 | if (error instanceof TimeoutError) { 19 | return "server time out"; 20 | } else if (isServerProblem(error)) { 21 | return handleServerError(error); 22 | } else if (isNetworkProblem(error)) { 23 | return "network err"; 24 | } 25 | return "server err"; 26 | } 27 | 28 | private static boolean isNetworkProblem(Object error) { 29 | return (error instanceof NetworkError) || (error instanceof NoConnectionError); 30 | } 31 | 32 | private static boolean isServerProblem(Object error) { 33 | return (error instanceof ServerError) || (error instanceof AuthFailureError); 34 | } 35 | 36 | private static String handleServerError(Object err) { 37 | VolleyError error = (VolleyError) err; 38 | 39 | NetworkResponse response = error.networkResponse; 40 | 41 | if (response != null) { 42 | switch (response.statusCode) { 43 | case 404: 44 | case 422: 45 | case 401: 46 | try { 47 | /* HashMap result = new Gson().fromJson(new String(response.data), 48 | new TypeToken() { 49 | }.getType());*/ 50 | 51 | HashMap result = JSON.parseObject(new String(response.data), 52 | new TypeReference>() { 53 | }.getType()); 54 | 55 | if (result != null && result.containsKey("error")) { 56 | return result.get("error"); 57 | } 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | return e.getMessage(); 61 | } 62 | return error.getMessage(); 63 | default: 64 | return "server err " + response.statusCode; 65 | } 66 | } 67 | return "server err"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/VolleyHelper.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | import android.content.Context; 3 | 4 | import com.android.volley.RequestQueue; 5 | import com.android.volley.toolbox.Volley; 6 | 7 | public class VolleyHelper { 8 | 9 | private static VolleyHelper mInstance; 10 | private RequestQueue mAPIRequestQueue; 11 | 12 | private Context mContext; 13 | 14 | public static synchronized VolleyHelper getInstance(Context aCt) { 15 | if (mInstance == null) { 16 | mInstance = new VolleyHelper(aCt.getApplicationContext()); 17 | } 18 | return mInstance; 19 | } 20 | 21 | private VolleyHelper(Context context) { 22 | mContext = context; 23 | mAPIRequestQueue = getRequestQueue(); 24 | } 25 | 26 | public RequestQueue getRequestQueue() { 27 | return mAPIRequestQueue != null ? mAPIRequestQueue : Volley.newRequestQueue(mContext); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/VolleyHttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access; 2 | 3 | import com.android.volley.Request; 4 | import com.android.volley.Response; 5 | import com.android.volley.VolleyError; 6 | import com.android.volley.toolbox.JsonObjectRequest; 7 | import com.video.search.access.api.ApiCallback; 8 | import com.video.search.access.api.ParseException; 9 | import com.video.search.access.msg.RequestMessage; 10 | 11 | import org.json.JSONObject; 12 | 13 | /** 14 | * HttpUtils for volley 15 | * 16 | * Created by zhuzhenhua 17 | */ 18 | public class VolleyHttpUtils { 19 | 20 | private static final String Tag = "HttpUtils"; 21 | 22 | public static JsonObjectRequest newPostRequest(RequestMessage msg, final ApiCallback callback) { 23 | return newRequest(Request.Method.POST, msg, callback); 24 | } 25 | 26 | public static JsonObjectRequest newGetRequest(RequestMessage msg, final ApiCallback callback) { 27 | return newRequest(Request.Method.GET, msg, callback); 28 | } 29 | 30 | public static JsonObjectRequest newRequest(int method, RequestMessage msg, final ApiCallback callback) { 31 | JsonObjectRequest request = new JsonObjectRequest(method, msg.getUrl(), msg.getMessage(), 32 | new Response.Listener() { 33 | 34 | @Override 35 | public void onResponse(JSONObject response) { 36 | if (callback.isSuccess(response)) { 37 | try { 38 | Object obj = callback.parse(response); 39 | callback.onSuccess(obj); 40 | } catch (ParseException e) { 41 | e.printStackTrace(); 42 | callback.onFail(e.getMessage()); 43 | } 44 | } else { 45 | String message = "错误码:" + callback.code; 46 | callback.onFail(message); 47 | } 48 | } 49 | }, new Response.ErrorListener() { 50 | 51 | @Override 52 | public void onErrorResponse(VolleyError error) { 53 | String message = VolleyErrorHelper.getMessage(error); 54 | callback.onFail(message); 55 | //ToastUtil.showShortToast(message); 56 | } 57 | }); 58 | 59 | return request; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/api/ApiCallback.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access.api; 2 | 3 | import com.video.search.access.Params; 4 | import com.video.search.access.ResponseStatus; 5 | 6 | import org.json.JSONObject; 7 | 8 | public abstract class ApiCallback { 9 | 10 | /* 接口服务器处理正常 */ 11 | public static final int RES_OK = ResponseStatus.SUCCESS.status; 12 | 13 | public int code; 14 | 15 | public String msg; 16 | 17 | public boolean isSuccess(JSONObject json) { 18 | code = json.optInt(Params.STATUS); 19 | return RES_OK == code; 20 | } 21 | 22 | public abstract Object parse(JSONObject json) throws ParseException; 23 | 24 | public void onSuccess(T result) { 25 | } 26 | 27 | public void onFail(String err) 28 | { 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/api/ApiGetEntity.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access.api; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.video.utils.ReflectUtil; 5 | 6 | import org.json.JSONObject; 7 | 8 | /** 9 | * Created by zzh on 2015/10/7. 10 | */ 11 | public class ApiGetEntity extends ApiCallback { 12 | 13 | @Override 14 | public T parse(JSONObject json) throws ParseException { 15 | Class cls = (Class) ReflectUtil.getTClass(getClass()); 16 | return JSON.parseObject(json.toString(), cls); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/api/ParseException.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access.api; 2 | /** 3 | * 4 | * @since 2014-7-10 16:03:43 5 | * @author zzh 6 | */ 7 | public class ParseException extends Exception { 8 | 9 | private static final long serialVersionUID = 1L; 10 | 11 | public ParseException() { 12 | super("parse data exception!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/msg/Message.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access.msg; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 描述: 报文基类 9 | * 创建时间:2013-12-7 16:24 10 | * 11 | * @author zzh 12 | */ 13 | public class Message implements Serializable { 14 | 15 | protected String url; 16 | protected String version; 17 | 18 | protected JSONObject message; 19 | 20 | public JSONObject getMessage() { 21 | return message; 22 | } 23 | 24 | public void setMessage(JSONObject message) { 25 | this.message = message; 26 | } 27 | 28 | public String getUrl() { 29 | return url; 30 | } 31 | 32 | public void setUrl(String url) { 33 | this.url = url; 34 | } 35 | } -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/access/msg/RequestMessage.java: -------------------------------------------------------------------------------- 1 | package com.video.search.access.msg; 2 | 3 | import org.json.JSONObject; 4 | 5 | /** 6 | * 描述: 请求报文 7 | * 创建时间:2013-12-7 下午5:54 8 | * 9 | * @author zzh 10 | */ 11 | public class RequestMessage extends Message 12 | { 13 | 14 | public RequestMessage() { 15 | message = new JSONObject(); 16 | } 17 | 18 | public RequestMessage(String url) { 19 | this.message = new JSONObject(); 20 | this.url = url; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | /** 4 | * Created by zhuzhenhua on 15-12-3. 5 | */ 6 | public abstract class BaseEntity { 7 | 8 | public int status; 9 | 10 | public long ver; 11 | 12 | public String license_type; 13 | 14 | public String language; 15 | 16 | public String encoding; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/Cineaste.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | import android.text.TextUtils; 4 | 5 | /** 6 | * Cineaste 编剧,编导,导演,电影业人士 7 | * Created by zhuzhenhua on 15-12-25. 8 | */ 9 | public class Cineaste extends Item { 10 | public String cineasteid; 11 | public int gender; 12 | public int order; 13 | public Image poster; 14 | 15 | public String getId() { 16 | if (TextUtils.isEmpty(id)) { 17 | return cineasteid; 18 | } 19 | return id; 20 | } 21 | 22 | public String getAvatarUrl() { 23 | String url = poster.posterurl; 24 | if (TextUtils.isEmpty(url)) { 25 | url = poster.url; 26 | } 27 | return url; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/CineasteSR.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * Cineaste Search Result 9 | * 10 | * Created by zhuzhenhua on 16-1-8. 11 | */ 12 | public class CineasteSR extends BaseEntity { 13 | 14 | public Data data; 15 | 16 | public static class Data implements Serializable { 17 | public int count; 18 | public List cineastes; 19 | 20 | public List getTags() { 21 | List tags = new ArrayList<>(cineastes.size()); 22 | for (int i = 0, size = cineastes.size(); i < size; i++) 23 | tags.add(cineastes.get(i).name); 24 | return tags; 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/HotSR.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | 5 | /** 6 | * Hot Search Result 7 | * Created by zhuzhenhua on 16-1-7. 8 | */ 9 | public class HotSR extends BaseEntity { 10 | 11 | public HotSRItem[] data; 12 | 13 | public static class HotSRItem { 14 | @JSONField(name="default") 15 | public boolean def; 16 | public String name; 17 | public MediaBase[] medias; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/Image.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | /** 4 | * 海报图/角标 5 | * 6 | * Created by zhuzhenhua on 15-12-8. 7 | */ 8 | public class Image { 9 | /*public int posterindex; 10 | public int posterposx; 11 | public int posterposy;*/ 12 | public int id; 13 | public String posterurl; 14 | public String url; 15 | public String md5; 16 | } 17 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/Item.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | public class Item { 4 | public String id; 5 | public String name; 6 | 7 | public Item() { 8 | 9 | } 10 | 11 | public Item(String id, String name) { 12 | this.id = id; 13 | this.name = name; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/model/MediaSR.java: -------------------------------------------------------------------------------- 1 | package com.video.search.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Media Search Result 7 | * Created by zhuzhenhua on 16-1-7. 8 | */ 9 | public class MediaSR extends BaseEntity { 10 | 11 | public List data; 12 | } 13 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/recyclerview/adapter/AlphaAnimatorAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ****************************************************************************** 3 | * Copyright (c) 2015 Gabriele Mariotti. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * ***************************************************************************** 17 | */ 18 | package com.video.search.recyclerview.adapter; 19 | 20 | import android.animation.Animator; 21 | import android.support.annotation.NonNull; 22 | import android.support.v7.widget.RecyclerView; 23 | import android.view.View; 24 | 25 | /** 26 | * @Author Gabriele Mariotti 27 | */ 28 | public class AlphaAnimatorAdapter extends AnimatorAdapter { 29 | 30 | public AlphaAnimatorAdapter(RecyclerView.Adapter adapter, RecyclerView recyclerView) { 31 | super(adapter, recyclerView); 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public Animator[] getAnimators(@NonNull View view) { 37 | return new Animator[0]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/search/recyclerview/adapter/helper/AnimatorUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Thanks to Niek Haarman for the original idea 3 | * https://github.com/nhaarman/ListViewAnimations/blob/master/lib-core/src/main/java/com/nhaarman/listviewanimations/util/AnimatorUtil.java 4 | * 5 | * ****************************************************************************** 6 | * Copyright (c) 2015 Gabriele Mariotti. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * ***************************************************************************** 20 | */ 21 | package com.video.search.recyclerview.adapter.helper; 22 | 23 | import android.animation.Animator; 24 | import android.support.annotation.NonNull; 25 | 26 | /** 27 | * @Author Gabriele Mariotti 28 | */ 29 | public class AnimatorUtil { 30 | 31 | private AnimatorUtil() { 32 | } 33 | 34 | /** 35 | * Merges given Animators into one array. 36 | */ 37 | @NonNull 38 | public static Animator[] concatAnimators(@NonNull final Animator[] animators, @NonNull final Animator alphaAnimator) { 39 | Animator[] allAnimators = new Animator[animators.length + 1]; 40 | int i = 0; 41 | 42 | for (Animator animator : animators) { 43 | allAnimators[i] = animator; 44 | ++i; 45 | } 46 | allAnimators[allAnimators.length - 1] = alphaAnimator; 47 | return allAnimators; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/AppGson.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.tv.ui.metro.model.DisplayItem; 6 | 7 | public class AppGson { 8 | private static final Gson gson; 9 | 10 | static { 11 | gson = new GsonBuilder() 12 | //.registerTypeAdapter(DisplayItem.Target.class, new DisplayItem.Target.Deserializer()) 13 | .create(); 14 | } 15 | 16 | 17 | public static Gson get() { 18 | return gson; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/CommonUrl.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | import android.content.Context; 4 | import android.text.TextUtils; 5 | import android.util.DisplayMetrics; 6 | import android.util.Log; 7 | import com.video.ui.idata.iDataORM; 8 | 9 | import java.net.MalformedURLException; 10 | import java.net.URL; 11 | import java.security.InvalidKeyException; 12 | import java.security.NoSuchAlgorithmException; 13 | import java.util.Locale; 14 | 15 | public class CommonUrl extends CommonBaseUrl{ 16 | public CommonUrl(Context appContext) { 17 | super(appContext); 18 | getBaseURLFromLoacalSetting(); 19 | 20 | } 21 | 22 | @Override 23 | protected void getBaseURLFromLoacalSetting() { 24 | if(fetchedBaseUrl == -1) { 25 | String base_url = iDataORM.getInstance(mAppContext).getSettingValue(iDataORM.base_url); 26 | if (TextUtils.isEmpty(base_url) == false) { 27 | BaseHost = base_url; 28 | 29 | BaseURL = "http://"+BaseHost +"/api/a1/"; 30 | LoginURL = "http://"+BaseHost +"/api/"; 31 | } 32 | 33 | fetchedBaseUrl = 1; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/CommonUrlBuilder.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | import com.tv.ui.metro.model.Constants; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | import java.net.URLEncoder; 9 | import java.util.Iterator; 10 | import java.util.LinkedHashMap; 11 | import java.util.Map; 12 | 13 | public class CommonUrlBuilder { 14 | 15 | private String mBaseUrl; 16 | private StringBuilder mStringBuilder; 17 | private Map mParamsMap; 18 | private boolean mIsFirstAdd = true; 19 | 20 | private static final String QUESTION_MARK = "?"; 21 | private static final String EQUAL = "="; 22 | private static final String AMPERSAND = "&"; 23 | private static final String UTF_8 = "UTF-8"; 24 | 25 | public CommonUrlBuilder(String baseUrl) { 26 | mBaseUrl = baseUrl; 27 | mParamsMap = new LinkedHashMap(); 28 | } 29 | 30 | public void put(String name, String value) { 31 | mParamsMap.put(name, value); 32 | } 33 | 34 | public void remove(String name) { 35 | mParamsMap.remove(name); 36 | } 37 | 38 | public String toUrl() { 39 | if (TextUtils.isEmpty(mBaseUrl) || mParamsMap.size() == 0) { 40 | return mBaseUrl; 41 | } 42 | this.mStringBuilder = new StringBuilder(mBaseUrl); 43 | mIsFirstAdd = true; 44 | 45 | Iterator it = mParamsMap.keySet().iterator(); 46 | while (it.hasNext()) { 47 | String key = it.next(); 48 | String value = mParamsMap.get(key); 49 | if (mIsFirstAdd) { 50 | mIsFirstAdd = false; 51 | if (mStringBuilder.indexOf(QUESTION_MARK) < 1) { 52 | // does not contain "?" 53 | mStringBuilder.append(QUESTION_MARK); 54 | encode(key, value); 55 | } else { 56 | // contains "?" 57 | mStringBuilder.append(AMPERSAND); 58 | encode(key, value); 59 | } 60 | } else { 61 | mStringBuilder.append(AMPERSAND); 62 | encode(key, value); 63 | } 64 | } 65 | 66 | if(Constants.DEBUG) 67 | Log.d("xxx", "toUrl:" + mStringBuilder.toString()); 68 | 69 | return mStringBuilder.toString(); 70 | } 71 | 72 | private void encode(String name, String value) { 73 | try { 74 | mStringBuilder.append(URLEncoder.encode(name, UTF_8)); 75 | mStringBuilder.append(EQUAL); 76 | mStringBuilder.append(URLEncoder.encode(value, UTF_8)); 77 | } catch (UnsupportedEncodingException uee) { 78 | throw new RuntimeException("VM does not support UTF-8 encoding"); 79 | } catch (Exception ne){ 80 | ne.printStackTrace(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/OnNextPageLoader.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | /** 4 | * Created by liuhuadong on 12/2/14. 5 | */ 6 | public interface OnNextPageLoader { 7 | public boolean nextPage(); 8 | } 9 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/ProgressNotifiable.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | public interface ProgressNotifiable { 4 | 5 | //每一阶段的载入开始时均会调用该方法 6 | public void startLoading(boolean hasData); 7 | 8 | //每一阶段的载入结束时均会调用该方法 9 | public void stopLoading(boolean hasData, boolean hasNext); 10 | 11 | //绑定时马上会被调用,用于初始化当前的载入状态 12 | public void init(boolean hasData, boolean isLoading); 13 | 14 | public void loginExpired(); 15 | } 16 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/VideoContentLengthRetriever.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | 6 | import java.io.IOException; 7 | import java.net.HttpURLConnection; 8 | import java.net.URL; 9 | import java.util.concurrent.Callable; 10 | import java.util.concurrent.FutureTask; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * Created by user on 3/19/15. 15 | */ 16 | public class VideoContentLengthRetriever { 17 | private static final String TAG = "ContentLengthRetriever"; 18 | 19 | private String mUrl; 20 | private long mTimeout; 21 | 22 | public VideoContentLengthRetriever(String url){ 23 | mUrl = url; 24 | } 25 | 26 | public int get(long timeout){ 27 | mTimeout = timeout; 28 | FutureTask future = new FutureTask(mRunner); 29 | new Thread(future).start(); 30 | int size = 0; 31 | try { 32 | size = future.get(mTimeout, TimeUnit.MILLISECONDS); 33 | }catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | return size; 37 | } 38 | 39 | private Callable mRunner = new Callable() { 40 | @Override 41 | public Integer call() throws Exception { 42 | int retry = 3; 43 | for(int i = 0; i < retry; i++){ 44 | try { 45 | Log.d(TAG, "retry count " + i); 46 | int size = doGet(); 47 | return size; 48 | } catch (Exception e) { 49 | } 50 | } 51 | return 0; 52 | } 53 | 54 | private int doGet() throws IOException { 55 | HttpURLConnection connection = null; 56 | int size = 0; 57 | try{ 58 | URL url = new URL(mUrl); 59 | connection = (HttpURLConnection) url.openConnection(); 60 | connection.setRequestMethod("GET"); 61 | connection.setConnectTimeout((int)mTimeout); 62 | size = connection.getContentLength(); 63 | String type = connection.getContentType(); 64 | 65 | Log.d(TAG, "url: " + mUrl + ", size is " + size + " type:"+type); 66 | //for none-video, return the max len to let download 67 | if(!TextUtils.isEmpty(type) && !type.contains("video") && !type.equals("application/octet-stream")){ 68 | return Integer.MAX_VALUE; 69 | } 70 | }finally{ 71 | if(connection != null){ 72 | connection.disconnect(); 73 | } 74 | } 75 | return size; 76 | } 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/VideoUrlHeaderRetriever.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader; 2 | 3 | import android.util.Log; 4 | 5 | import org.apache.http.HttpEntity; 6 | import org.apache.http.HttpResponse; 7 | import org.apache.http.client.HttpClient; 8 | import org.apache.http.client.methods.HttpGet; 9 | import org.apache.http.impl.client.DefaultHttpClient; 10 | 11 | import java.io.IOException; 12 | import java.util.concurrent.Callable; 13 | import java.util.concurrent.FutureTask; 14 | import java.util.concurrent.TimeUnit; 15 | 16 | /** 17 | * Created by lijianbo1 on 15-7-10. 18 | */ 19 | public class VideoUrlHeaderRetriever { 20 | private static final String TAG = "VideoUrlHeaderRetriever"; 21 | private static final boolean DEBUG = false; 22 | 23 | private String mUrl; 24 | private long mTimeout; 25 | 26 | public VideoUrlHeaderRetriever(String url){ 27 | mUrl = url; 28 | } 29 | 30 | public VideoUrlHeader get(long timeout){ 31 | mTimeout = timeout; 32 | FutureTask future = new FutureTask(mRunner); 33 | new Thread(future).start(); 34 | VideoUrlHeader r = null; 35 | try { 36 | r = future.get(mTimeout, TimeUnit.MILLISECONDS); 37 | }catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | return r; 41 | } 42 | 43 | private Callable mRunner = new Callable() { 44 | @Override 45 | public VideoUrlHeader call() throws Exception { 46 | int retry = 3; 47 | for(int i = 0; i < retry; i++){ 48 | try { 49 | if (DEBUG) Log.d(TAG, "retry count " + i); 50 | VideoUrlHeader result = doGet(); 51 | return result; 52 | } catch (Exception e) { 53 | } 54 | } 55 | return null; 56 | } 57 | 58 | private VideoUrlHeader doGet() throws IOException { 59 | VideoUrlHeader result = new VideoUrlHeader(); 60 | 61 | HttpGet httpGet = new HttpGet(mUrl); 62 | HttpClient httpClient = new DefaultHttpClient(); 63 | HttpResponse response = httpClient.execute(httpGet); 64 | // Log.i(TAG, "line: " + response.getStatusLine()); 65 | 66 | HttpEntity httpEntity = response.getEntity(); 67 | result.ContentLength = httpEntity.getContentLength(); 68 | result.ContentType = httpEntity.getContentType().getValue(); 69 | 70 | if (DEBUG) Log.i(TAG, "size: " + result.ContentLength + " type: " + result.ContentType + " url:" + mUrl); 71 | 72 | return result; 73 | } 74 | }; 75 | 76 | public static class VideoUrlHeader { 77 | public long ContentLength; 78 | public String ContentType; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/video/CommonRequest.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader.video; 2 | 3 | import android.content.Context; 4 | import com.android.volley.Request; 5 | import com.android.volley.Response.ErrorListener; 6 | import com.video.ui.loader.CommonBaseUrl; 7 | import com.video.ui.loader.CommonUrl; 8 | 9 | public abstract class CommonRequest extends Request { 10 | 11 | private CommonBaseUrl mCommonUrl; 12 | 13 | public CommonRequest(Context context, int method, String url, ErrorListener listener) { 14 | super(method, url, listener); 15 | 16 | mCommonUrl = new CommonUrl(context); 17 | } 18 | 19 | @Override 20 | public String getUrl() { 21 | String url = super.getUrl(); 22 | return mCommonUrl.addCommonParams(url); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/ui/loader/video/TabsGsonLoader.java: -------------------------------------------------------------------------------- 1 | package com.video.ui.loader.video; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.android.volley.DefaultRetryPolicy; 7 | import com.android.volley.RequestQueue; 8 | import com.duokan.VolleyHelper; 9 | import com.google.gson.reflect.TypeToken; 10 | import com.tv.ui.metro.model.DisplayItem; 11 | import com.tv.ui.metro.model.GenericBlock; 12 | import com.video.ui.loader.BaseGsonLoader; 13 | import com.video.ui.loader.CommonUrl; 14 | 15 | /** 16 | * Created by tv metro on 9/1/14. 17 | */ 18 | public class TabsGsonLoader extends BaseGsonLoader> { 19 | public static int LOADER_ID = 0x401; 20 | @Override 21 | public void setCacheFileName() { 22 | cacheFileName = "tabs_content.cache"; 23 | } 24 | 25 | @Override 26 | public void setLoaderURL(DisplayItem item) { 27 | //only for test 28 | //calledURL = "https://raw.githubusercontent.com/AiAndroid/mobilevideo/master/mobile_port.json"; 29 | //calledURL = "https://raw.githubusercontent.com/AiAndroid/tvhome/master/home.json"; 30 | 31 | // String homeurl = "https://raw.githubusercontent.com/AiAndroid/tvhome/master/home1.json"; 32 | String homeurl = "http://media.tv.mitvos.com/tv/lean/aio/home?ptf=207&codever=1&deviceid=deb49000000000000000000000000001&opaque=aedf5d2c3d4e03e7841c4faa7210ba74b86c666d"; 33 | String baseURL = CommonUrl.BaseURL; 34 | if(item != null && item.settings != null && "1".equals(item.settings.get("from_push"))){ 35 | baseURL += "push/"; 36 | } 37 | 38 | //setRawURL(baseURL + "c/home"); 39 | setRawURL(homeurl); 40 | 41 | String url = getRawURL(); 42 | if(item != null && item.settings != null && "1".equals(item.settings.get("from_push"))){ 43 | if(url.indexOf("?")<1) 44 | url += "?from_push=1"; 45 | else 46 | url += "&from_push=1"; 47 | } 48 | 49 | calledURL = new CommonUrl(getContext()).addCommonParams(url); 50 | } 51 | 52 | public TabsGsonLoader(Context context, DisplayItem item) { 53 | super(context, item, 1); 54 | } 55 | 56 | @Override 57 | protected void loadDataByGson() { 58 | RequestQueue requestQueue = VolleyHelper.getInstance(getContext().getApplicationContext()).getAPIRequestQueue(); 59 | GsonRequest> gsonRequest = new GsonRequest>(calledURL, new TypeToken>(){}.getType(), null, listener, errorListener); 60 | gsonRequest.setRawURL(getRawURL()); 61 | Log.d("loader", "RawURL " + getRawURL()); 62 | gsonRequest.setCacheNeed(getContext().getCacheDir() + "/" + cacheFileName); 63 | gsonRequest.setShouldCache(false); 64 | gsonRequest.setRetryPolicy(new DefaultRetryPolicy(DEFAULT_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT)); 65 | requestQueue.add(gsonRequest); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/utils/ReflectUtil.java: -------------------------------------------------------------------------------- 1 | package com.video.utils; 2 | 3 | import java.lang.reflect.ParameterizedType; 4 | import java.lang.reflect.Type; 5 | 6 | /** 7 | * 反射工具类 8 | * 9 | * Created by zzh on 2015/10/20. 10 | */ 11 | public class ReflectUtil { 12 | 13 | /** 14 | * 获取 T.class 15 | * 16 | * Type genType = getClass().getGenericSuperclass(); 17 | * Class cls = (Class) ((ParameterizedType) genType).getActualTypeArguments()[0]; 18 | * 19 | * @param c 20 | * @param 21 | * @return 22 | */ 23 | public static Class getTClass(Class c) { 24 | Type genType = c.getGenericSuperclass(); 25 | return (Class) ((ParameterizedType) genType).getActualTypeArguments()[0]; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /tvhome/app/src/main/java/com/video/utils/SignatureUtil.java: -------------------------------------------------------------------------------- 1 | package com.video.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.InputStream; 7 | import java.security.MessageDigest; 8 | 9 | public class SignatureUtil { 10 | public static final String TAG = "SignatureUtil"; 11 | 12 | public static String getMD5(String message) { 13 | if (message == null) { 14 | return ""; 15 | } 16 | return getMD5(message.getBytes()); 17 | } 18 | 19 | public static String getMD5(byte[] bytes) { 20 | if (bytes == null) { 21 | return ""; 22 | } 23 | try { 24 | MessageDigest algorithm = MessageDigest.getInstance("MD5"); 25 | algorithm.update(bytes); 26 | return IOUtil.byteArray2HexString(algorithm.digest()); 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | } 30 | return ""; 31 | } 32 | 33 | public static String getMD5(File file) { 34 | if (file == null) { 35 | return ""; 36 | } 37 | try { 38 | return getMD5(new FileInputStream(file)); 39 | } catch (FileNotFoundException e) { 40 | e.printStackTrace(); 41 | } 42 | return ""; 43 | } 44 | 45 | public static String getMD5(InputStream is) { 46 | if (is == null) { 47 | return ""; 48 | } 49 | try { 50 | byte[] buffer = new byte[1024]; 51 | MessageDigest digest = MessageDigest.getInstance("MD5"); 52 | int numRead = 0; 53 | while (numRead != -1) { 54 | numRead = is.read(buffer); 55 | if (numRead > 0) { 56 | digest.update(buffer, 0, numRead); 57 | } 58 | } 59 | return IOUtil.byteArray2HexString(digest.digest()); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } finally { 63 | try { 64 | is.close(); 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | return ""; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/color/header_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/color/tv_seach_button_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/color/tv_seach_result_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/color/tv_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/a1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/a1.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/a2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/a2.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/a3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/a3.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/a4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/a4.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/a5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/a5.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/a6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/a6.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/arrow_right.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/background.jpg -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/bg_app.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/bg_app.9.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/bg_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/bg_search.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/defaultposter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/defaultposter.jpg -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/focus.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/headerfocus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/headerfocus.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/ic_backspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/ic_backspace.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/img_focus.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/img_focus.9.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable-xhdpi/star_small_hl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AiAndroid/tvhome/a2235d91f6385b08eaad11b3b0dafc496c3e5210/tvhome/app/src/main/res/drawable-xhdpi/star_small_hl.png -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/blue_gradient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/item_bg_default.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/key_btn_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/lb_headers_bottom_fading.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 25 | 26 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/list_item_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/list_item_bg_focus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/list_item_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/drawable/main_header_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/layout/activity_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 17 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /tvhome/app/src/main/res/layout/ad_main_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 41 | 42 | 43 | 49 | 50 |