├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── TalkingdataAnalytics.jar │ └── android-support-v4.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── geniusgithub │ │ └── mediarender │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── geniusgithub │ │ │ └── mediarender │ │ │ ├── BaseActivity.java │ │ │ ├── DeviceInfo.java │ │ │ ├── DeviceUpdateBrocastFactory.java │ │ │ ├── DeviceUpdateBrocastReceiver.java │ │ │ ├── ItatisticsEvent.java │ │ │ ├── MainActivity.java │ │ │ ├── RenderApplication.java │ │ │ ├── center │ │ │ ├── DLNAGenaEventBrocastFactory.java │ │ │ ├── DLNAGenaEventBrocastReceiver.java │ │ │ ├── DMRCenter.java │ │ │ ├── DMRWorkThread.java │ │ │ ├── DlnaMediaModel.java │ │ │ ├── DlnaMediaModelFactory.java │ │ │ ├── IBaseEngine.java │ │ │ ├── IDMRAction.java │ │ │ ├── MediaControlBrocastFactory.java │ │ │ ├── MediaControlBrocastReceiver.java │ │ │ └── MediaRenderProxy.java │ │ │ ├── datastore │ │ │ └── LocalConfigSharePreference.java │ │ │ ├── image │ │ │ ├── DownLoadHelper.java │ │ │ ├── FileDownTask.java │ │ │ ├── FileManager.java │ │ │ └── ImageActivity.java │ │ │ ├── jni │ │ │ ├── PlatinumJniProxy.java │ │ │ └── PlatinumReflection.java │ │ │ ├── music │ │ │ ├── ImageUtils.java │ │ │ ├── LoaderHelper.java │ │ │ ├── MusicActivity.java │ │ │ ├── NetUtils.java │ │ │ ├── VisualizerView.java │ │ │ └── lrc │ │ │ │ ├── ErrorThrowable.java │ │ │ │ ├── HttpManager.java │ │ │ │ ├── LrcDownLoadHelper.java │ │ │ │ ├── LyricHelper.java │ │ │ │ ├── LyricObject.java │ │ │ │ ├── LyricView.java │ │ │ │ └── MusicUtils.java │ │ │ ├── player │ │ │ ├── AbstractMediaPlayEngine.java │ │ │ ├── AbstractTimer.java │ │ │ ├── CheckDelayTimer.java │ │ │ ├── IBasePlayEngine.java │ │ │ ├── MusicPlayEngineImpl.java │ │ │ ├── PlayState.java │ │ │ ├── PlayerEngineListener.java │ │ │ ├── SingleSecondTimer.java │ │ │ └── VideoPlayEngineImpl.java │ │ │ ├── service │ │ │ └── MediaRenderService.java │ │ │ ├── util │ │ │ ├── CommonLog.java │ │ │ ├── CommonUtil.java │ │ │ ├── DlnaUtils.java │ │ │ ├── FileHelper.java │ │ │ └── LogFactory.java │ │ │ └── video │ │ │ └── VideoActivity.java │ ├── jniLibs │ │ └── armeabi │ │ │ └── libgit-platinum.so │ └── res │ │ ├── drawable-ldpi │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ │ ├── drawable │ │ ├── btn_pause_n.png │ │ ├── btn_pause_p.png │ │ ├── btn_play_n.png │ │ ├── btn_play_p.png │ │ ├── button_normal.9.png │ │ ├── button_pressed.9.png │ │ ├── cm_progress_anim.xml │ │ ├── input_disabled.9.png │ │ ├── input_normal.9.png │ │ ├── input_pressed.9.png │ │ ├── logo.png │ │ ├── main_bg.png │ │ ├── media_bacground.png │ │ ├── media_prepare_startup.png │ │ ├── media_progress.png │ │ ├── media_tool_bg1.png │ │ ├── media_tool_bg2.png │ │ ├── mp_music_default.png │ │ ├── progress_blue.xml │ │ ├── progress_bottom.png │ │ ├── progress_first.png │ │ ├── progress_second.png │ │ ├── progress_thumb_n.png │ │ ├── progress_thumb_p.png │ │ ├── progress_white.xml │ │ ├── progressbar.xml │ │ ├── seekbar_background.xml │ │ ├── seekbar_thumb.xml │ │ ├── selector_btn.xml │ │ ├── selector_btn_pause.xml │ │ ├── selector_btn_play.xml │ │ └── selector_edit.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── image_player_layout.xml │ │ ├── media_loading_layout.xml │ │ ├── media_prepare_layout.xml │ │ ├── media_toolbar_layout.xml │ │ ├── music_loading_layout.xml │ │ ├── music_player_layout.xml │ │ ├── music_toolbar_layout.xml │ │ └── video_player_layout.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── geniusgithub │ └── mediarender │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | MediaRender -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 | 57 | 1.7 58 | 59 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | a MediaRender Player run in Android Platform 2 | =========== 3 | MediaRender is a DLNA device(DMR) that can be found and control
It uses the framework of Platinum 4 | 5 | Example screenshot below: 6 | 7 | ![github](http://img.my.csdn.net/uploads/201305/20/1369039180_2648.png "github") 8 | 9 | ![github](http://img.my.csdn.net/uploads/201305/20/1369039181_1241.png "github") 10 | 11 | ![github](http://img.my.csdn.net/uploads/201312/27/1388139669_8703.png "github") 12 | 13 | ![github](http://img.my.csdn.net/uploads/201305/20/1369039181_3596.png "github") 14 | 15 | ![github](http://img.my.csdn.net/uploads/201305/20/1369039181_7415.png "github") 16 | 17 | 18 | Code fragment 19 | -------------------- 20 | 21 | 22 | public class MediaRenderService extends Service implements IBaseEngine{ 23 | private static final CommonLog log = LogFactory.createLog(); 24 | 25 | public static final String START_RENDER_ENGINE = "com.geniusgithub.start.engine"; 26 | public static final String RESTART_RENDER_ENGINE = "com.geniusgithub.restart.engine"; 27 | 28 | 29 | private DMRWorkThread mWorkThread; 30 | 31 | private ActionReflectionListener mListener; 32 | private DLNAGenaEventBrocastFactory mMediaGenaBrocastFactory; 33 | 34 | private Handler mHandler; 35 | private static final int START_ENGINE_MSG_ID = 0x0001; 36 | private static final int RESTART_ENGINE_MSG_ID = 0x0002; 37 | 38 | private static final int DELAY_TIME = 1000; 39 | 40 | @Override 41 | public IBinder onBind(Intent intent) { 42 | return null; 43 | } 44 | 45 | @Override 46 | public void onCreate() { 47 | super.onCreate(); 48 | initRenderService(); 49 | log.e("MediaRenderService onCreate"); 50 | } 51 | 52 | @Override 53 | public void onDestroy() { 54 | unInitRenderService(); 55 | log.e("MediaRenderService onDestroy"); 56 | super.onDestroy(); 57 | 58 | } 59 | 60 | @Override 61 | public int onStartCommand(Intent intent, int flags, int startId) { 62 | 63 | if (intent != null){ 64 | String actionString = intent.getAction(); 65 | if (actionString != null){ 66 | if (actionString.equalsIgnoreCase(START_RENDER_ENGINE)){ 67 | delayToSendStartMsg(); 68 | }else if (actionString.equalsIgnoreCase(RESTART_RENDER_ENGINE)){ 69 | delayToSendRestartMsg(); 70 | } 71 | } 72 | } 73 | 74 | return super.onStartCommand(intent, flags, startId); 75 | 76 | } 77 | 78 | 79 | private void initRenderService(){ 80 | 81 | mListener = new DMRCenter(this); 82 | PlatinumReflection.setActionInvokeListener(mListener); 83 | mMediaGenaBrocastFactory = new DLNAGenaEventBrocastFactory(this); 84 | mMediaGenaBrocastFactory.registerBrocast(); 85 | mWorkThread = new DMRWorkThread(this); 86 | 87 | mHandler = new Handler(){ 88 | @Override 89 | public void handleMessage(Message msg) { 90 | switch(msg.what){ 91 | case START_ENGINE_MSG_ID: 92 | startEngine(); 93 | break; 94 | case RESTART_ENGINE_MSG_ID: 95 | restartEngine(); 96 | break; 97 | } 98 | } 99 | 100 | }; 101 | } 102 | 103 | 104 | private void unInitRenderService(){ 105 | stopEngine(); 106 | removeStartMsg(); 107 | removeRestartMsg(); 108 | mMediaGenaBrocastFactory.unRegisterBrocast(); 109 | } 110 | 111 | private void delayToSendStartMsg(){ 112 | removeStartMsg(); 113 | mHandler.sendEmptyMessageDelayed(START_ENGINE_MSG_ID, DELAY_TIME); 114 | } 115 | 116 | private void delayToSendRestartMsg(){ 117 | removeStartMsg(); 118 | removeRestartMsg(); 119 | mHandler.sendEmptyMessageDelayed(RESTART_ENGINE_MSG_ID, DELAY_TIME); 120 | } 121 | 122 | private void removeStartMsg(){ 123 | mHandler.removeMessages(START_ENGINE_MSG_ID); 124 | } 125 | 126 | private void removeRestartMsg(){ 127 | mHandler.removeMessages(RESTART_ENGINE_MSG_ID); 128 | } 129 | 130 | 131 | @Override 132 | public boolean startEngine() { 133 | awakeWorkThread(); 134 | return true; 135 | } 136 | 137 | @Override 138 | public boolean stopEngine() { 139 | mWorkThread.setParam("", ""); 140 | exitWorkThread(); 141 | return true; 142 | } 143 | 144 | @Override 145 | public boolean restartEngine() { 146 | String friendName = DlnaUtils.getDevName(this); 147 | String uuid = DlnaUtils.creat12BitUUID(this); 148 | mWorkThread.setParam(friendName, uuid); 149 | if (mWorkThread.isAlive()){ 150 | mWorkThread.restartEngine(); 151 | }else{ 152 | mWorkThread.start(); 153 | } 154 | return true; 155 | } 156 | 157 | private void awakeWorkThread(){ 158 | String friendName = DlnaUtils.getDevName(this); 159 | String uuid = DlnaUtils.creat12BitUUID(this); 160 | mWorkThread.setParam(friendName, uuid); 161 | 162 | 163 | if (mWorkThread.isAlive()){ 164 | mWorkThread.awakeThread(); 165 | }else{ 166 | mWorkThread.start(); 167 | } 168 | } 169 | 170 | private void exitWorkThread(){ 171 | if (mWorkThread != null && mWorkThread.isAlive()){ 172 | mWorkThread.exit(); 173 | long time1 = System.currentTimeMillis(); 174 | while(mWorkThread.isAlive()){ 175 | try { 176 | Thread.sleep(100); 177 | } catch (InterruptedException e) { 178 | e.printStackTrace(); 179 | } 180 | } 181 | long time2 = System.currentTimeMillis(); 182 | log.e("exitWorkThread cost time:" + (time2 - time1)); 183 | mWorkThread = null; 184 | } 185 | } 186 | 187 | 188 | } 189 | 190 | 191 | 192 | 193 | public class DMRWorkThread extends Thread implements IBaseEngine{ 194 | private static final CommonLog log = LogFactory.createLog(); 195 | 196 | private static final int CHECK_INTERVAL = 30 * 1000; 197 | 198 | private Context mContext = null; 199 | private boolean mStartSuccess = false; 200 | private boolean mExitFlag = false; 201 | 202 | private String mFriendName = ""; 203 | private String mUUID = ""; 204 | private RenderApplication mApplication; 205 | 206 | public DMRWorkThread(Context context){ 207 | mContext = context; 208 | mApplication = RenderApplication.getInstance(); 209 | } 210 | 211 | public void setFlag(boolean flag){ 212 | mStartSuccess = flag; 213 | } 214 | 215 | public void setParam(String friendName, String uuid){ 216 | mFriendName = friendName; 217 | mUUID = uuid; 218 | mApplication.updateDevInfo(mFriendName, mUUID); 219 | } 220 | 221 | public void awakeThread(){ 222 | synchronized (this) { 223 | notifyAll(); 224 | } 225 | } 226 | 227 | public void exit(){ 228 | mExitFlag = true; 229 | awakeThread(); 230 | } 231 | 232 | @Override 233 | public void run() { 234 | 235 | log.e("DMRWorkThread run..."); 236 | 237 | while(true) 238 | { 239 | if (mExitFlag){ 240 | stopEngine(); 241 | break; 242 | } 243 | refreshNotify(); 244 | synchronized(this) 245 | { 246 | try 247 | { 248 | wait(CHECK_INTERVAL); 249 | } 250 | catch(Exception e) 251 | { 252 | e.printStackTrace(); 253 | } 254 | } 255 | if (mExitFlag){ 256 | stopEngine(); 257 | break; 258 | } 259 | } 260 | 261 | log.e("DMRWorkThread over..."); 262 | 263 | } 264 | 265 | public void refreshNotify(){ 266 | if (!CommonUtil.checkNetworkState(mContext)){ 267 | return ; 268 | } 269 | 270 | if (!mStartSuccess){ 271 | stopEngine(); 272 | try { 273 | Thread.sleep(200); 274 | } catch (InterruptedException e) { 275 | e.printStackTrace(); 276 | } 277 | boolean ret = startEngine(); 278 | if (ret){ 279 | mStartSuccess = true; 280 | } 281 | } 282 | 283 | } 284 | 285 | @Override 286 | public boolean startEngine() { 287 | if (mFriendName.length() == 0){ 288 | return false; 289 | } 290 | 291 | int ret = PlatinumJniProxy.startMediaRender(mFriendName, mUUID); 292 | boolean result = (ret == 0 ? true : false); 293 | mApplication.setDevStatus(result); 294 | return result; 295 | } 296 | 297 | @Override 298 | public boolean stopEngine() { 299 | PlatinumJniProxy.stopMediaRender(); 300 | mApplication.setDevStatus(false); 301 | return true; 302 | } 303 | 304 | @Override 305 | public boolean restartEngine() { 306 | setFlag(false); 307 | awakeThread(); 308 | return true; 309 | } 310 | 311 | } 312 | 313 | Run requirements 314 | ------------------------------ 315 | Android OS 2.3x and up
316 | Tested with: Samsung, HTC, HuaWei Phone and so on... 317 | 318 | 319 | Contributing 320 | ------------------------------ 321 | Feel free to drop me pull requests. If you plan to implement something more than a few lines, then open the pull request early so that there aren't any nasty surprises later. 322 | If you want to add something that will require some for of persistence incl. persistent configuration or API keys, etc., then open a pull request/issue especially early! 323 | 324 | 325 | ### Links 326 | csdn blog : [http://blog.csdn.net/geniuseoe2012](http://blog.csdn.net/lancees/article/details/8951679)
327 | cnblog : [http://www.cnblogs.com/lance2016](http://www.cnblogs.com/lance2016/p/5204293.html)
328 | dlna doc: [DLNA Document](http://download.csdn.net/detail/geniuseoe2012/4969961)
329 | Platinum SDK : [Platinum](http://sourceforge.net/projects/platinum/)
330 | 331 | ### Development 332 | If you think this article useful Nepal , please pay attention to me
333 | Your support is my motivation, I will continue to strive to do better 334 | 335 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.geniusgithub.mediarender" 9 | minSdkVersion 19 10 | targetSdkVersion 22 11 | versionCode 2 12 | versionName "2.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.umeng.analytics:analytics:latest.integration' 26 | } 27 | -------------------------------------------------------------------------------- /app/libs/TalkingdataAnalytics.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/libs/TalkingdataAnalytics.jar -------------------------------------------------------------------------------- /app/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/libs/android-support-v4.jar -------------------------------------------------------------------------------- /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 E:\sofeware\android-sdk-L/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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/geniusgithub/mediarender/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | --> 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 67 | 68 | 69 | 70 | 71 | 74 | 75 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 108 | 109 | 110 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | 4 | import android.app.Activity; 5 | import android.os.Bundle; 6 | 7 | public class BaseActivity extends Activity{ 8 | 9 | @Override 10 | protected void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | 13 | RenderApplication.onCatchError(this); 14 | } 15 | 16 | @Override 17 | protected void onDestroy() { 18 | super.onDestroy(); 19 | } 20 | 21 | @Override 22 | protected void onPause() { 23 | super.onPause(); 24 | 25 | RenderApplication.onPause(this); 26 | } 27 | 28 | @Override 29 | protected void onResume() { 30 | super.onResume(); 31 | 32 | RenderApplication.onResume(this); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/DeviceInfo.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | public class DeviceInfo { 4 | 5 | public String dev_name; 6 | public String uuid; 7 | public boolean status; 8 | 9 | public DeviceInfo(){ 10 | dev_name = ""; 11 | uuid = ""; 12 | status = false; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/DeviceUpdateBrocastFactory.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.IntentFilter; 6 | 7 | 8 | public class DeviceUpdateBrocastFactory { 9 | 10 | public static final String PARAM_DEV_UPDATE="com.geniusgithub.PARAM_DEV_UPDATE"; 11 | 12 | public static interface IDevUpdateListener { 13 | public void onUpdate(); 14 | } 15 | 16 | 17 | private DeviceUpdateBrocastReceiver mReceiver; 18 | private Context mContext; 19 | 20 | public DeviceUpdateBrocastFactory(Context context){ 21 | mContext = context; 22 | } 23 | 24 | 25 | public void register(IDevUpdateListener listener){ 26 | if (mReceiver == null){ 27 | mReceiver = new DeviceUpdateBrocastReceiver(); 28 | mReceiver.setListener(listener); 29 | mContext.registerReceiver(mReceiver, new IntentFilter(PARAM_DEV_UPDATE)); 30 | } 31 | } 32 | 33 | public void unregister() 34 | { 35 | if (mReceiver != null){ 36 | mContext.unregisterReceiver(mReceiver); 37 | mReceiver = null; 38 | } 39 | } 40 | 41 | public static void sendDevUpdateBrocast(Context context){ 42 | Intent intent = new Intent(); 43 | intent.setAction(PARAM_DEV_UPDATE); 44 | context.sendBroadcast(intent); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/DeviceUpdateBrocastReceiver.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import com.geniusgithub.mediarender.util.CommonLog; 8 | import com.geniusgithub.mediarender.util.LogFactory; 9 | 10 | public class DeviceUpdateBrocastReceiver extends BroadcastReceiver{ 11 | 12 | private static final CommonLog log = LogFactory.createLog(); 13 | private DeviceUpdateBrocastFactory.IDevUpdateListener mListener; 14 | 15 | public void setListener(DeviceUpdateBrocastFactory.IDevUpdateListener listener){ 16 | mListener = listener; 17 | } 18 | @Override 19 | public void onReceive(Context context, Intent intent) { 20 | String action = intent.getAction(); 21 | if (action == null){ 22 | return ; 23 | } 24 | 25 | if (DeviceUpdateBrocastFactory.PARAM_DEV_UPDATE.equalsIgnoreCase(action)){ 26 | if (mListener != null){ 27 | mListener.onUpdate(); 28 | } 29 | } 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/ItatisticsEvent.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public interface ItatisticsEvent { 7 | 8 | public void onEvent(String eventID); 9 | public void onEvent(String eventID, HashMap map); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.view.View.OnClickListener; 7 | import android.widget.Button; 8 | import android.widget.EditText; 9 | import android.widget.TextView; 10 | 11 | import com.geniusgithub.mediarender.center.MediaRenderProxy; 12 | import com.geniusgithub.mediarender.datastore.LocalConfigSharePreference; 13 | import com.geniusgithub.mediarender.util.CommonLog; 14 | import com.geniusgithub.mediarender.util.DlnaUtils; 15 | import com.geniusgithub.mediarender.util.LogFactory; 16 | 17 | 18 | /** 19 | * @author lance 20 | * @csdn http://blog.csdn.net/geniuseoe2012 21 | * @github https://github.com/geniusgithub 22 | */ 23 | public class MainActivity extends BaseActivity implements OnClickListener, DeviceUpdateBrocastFactory.IDevUpdateListener{ 24 | 25 | private static final CommonLog log = LogFactory.createLog(); 26 | 27 | private Button mBtnStart; 28 | private Button mBtnReset; 29 | private Button mBtnStop; 30 | 31 | private Button mBtnEditName; 32 | private EditText mETName; 33 | private TextView mTVDevInfo; 34 | 35 | 36 | private MediaRenderProxy mRenderProxy; 37 | private RenderApplication mApplication; 38 | private DeviceUpdateBrocastFactory mBrocastFactory; 39 | 40 | @Override 41 | protected void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.activity_main); 44 | 45 | setupView(); 46 | initData(); 47 | } 48 | 49 | 50 | 51 | 52 | @Override 53 | protected void onDestroy() { 54 | unInitData(); 55 | super.onDestroy(); 56 | } 57 | 58 | 59 | 60 | 61 | private void setupView(){ 62 | mBtnStart = (Button) findViewById(R.id.btn_init); 63 | mBtnReset = (Button) findViewById(R.id.btn_reset); 64 | mBtnStop = (Button) findViewById(R.id.btn_exit); 65 | mBtnEditName = (Button) findViewById(R.id.bt_dev_name); 66 | mBtnStart.setOnClickListener(this); 67 | mBtnReset.setOnClickListener(this); 68 | mBtnStop.setOnClickListener(this); 69 | mBtnEditName.setOnClickListener(this); 70 | 71 | mTVDevInfo = (TextView) findViewById(R.id.tv_dev_info); 72 | mETName = (EditText) findViewById(R.id.et_dev_name); 73 | 74 | } 75 | 76 | private void initData(){ 77 | mApplication = RenderApplication.getInstance(); 78 | mRenderProxy = MediaRenderProxy.getInstance(); 79 | mBrocastFactory = new DeviceUpdateBrocastFactory(this); 80 | 81 | String dev_name = DlnaUtils.getDevName(this); 82 | mETName.setText(dev_name); 83 | mETName.setEnabled(false); 84 | 85 | updateDevInfo(mApplication.getDevInfo()); 86 | mBrocastFactory.register(this); 87 | } 88 | 89 | private void unInitData(){ 90 | mBrocastFactory.unregister(); 91 | } 92 | 93 | private void updateDevInfo(DeviceInfo object){ 94 | String status = object.status ? "open" : "close"; 95 | String text = "status: " + status + "\n" + 96 | "friend name: " + object.dev_name + "\n" + 97 | "uuid: " + object.uuid; 98 | mTVDevInfo.setText(text); 99 | } 100 | 101 | @Override 102 | public void onClick(View v) { 103 | switch(v.getId()){ 104 | case R.id.btn_init: 105 | start(); 106 | break; 107 | case R.id.btn_reset: 108 | reset(); 109 | break; 110 | case R.id.btn_exit: 111 | stop(); 112 | finish(); 113 | break; 114 | case R.id.bt_dev_name: 115 | change(); 116 | break; 117 | } 118 | } 119 | 120 | 121 | private void start(){ 122 | mRenderProxy.startEngine(); 123 | } 124 | 125 | private void reset(){ 126 | mRenderProxy.restartEngine(); 127 | } 128 | 129 | private void stop(){ 130 | mRenderProxy.stopEngine(); 131 | } 132 | 133 | private void change(){ 134 | if (mETName.isEnabled()){ 135 | mETName.setEnabled(false); 136 | DlnaUtils.setDevName(this, mETName.getText().toString()); 137 | }else{ 138 | mETName.setEnabled(true); 139 | } 140 | } 141 | 142 | 143 | 144 | @Override 145 | public void onUpdate() { 146 | updateDevInfo(mApplication.getDevInfo()); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/RenderApplication.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender; 2 | 3 | import android.app.Activity; 4 | import android.app.Application; 5 | import android.content.Context; 6 | 7 | import com.geniusgithub.mediarender.util.CommonLog; 8 | import com.geniusgithub.mediarender.util.LogFactory; 9 | import com.tendcloud.tenddata.TCAgent; 10 | import com.umeng.analytics.MobclickAgent; 11 | 12 | import java.util.HashMap; 13 | 14 | public class RenderApplication extends Application implements ItatisticsEvent{ 15 | 16 | private static final CommonLog log = LogFactory.createLog(); 17 | 18 | private static RenderApplication mInstance; 19 | 20 | private DeviceInfo mDeviceInfo; 21 | 22 | 23 | public synchronized static RenderApplication getInstance(){ 24 | return mInstance; 25 | } 26 | @Override 27 | public void onCreate() { 28 | super.onCreate(); 29 | log.e("RenderApplication onCreate"); 30 | 31 | mInstance = this; 32 | mDeviceInfo = new DeviceInfo(); 33 | 34 | TCAgent.init(this); 35 | TCAgent.setReportUncaughtExceptions(true); 36 | 37 | MobclickAgent.setDebugMode(true); 38 | } 39 | 40 | public void updateDevInfo(String name, String uuid){ 41 | mDeviceInfo.dev_name = name; 42 | mDeviceInfo.uuid = uuid; 43 | } 44 | 45 | public void setDevStatus(boolean flag){ 46 | mDeviceInfo.status = flag; 47 | DeviceUpdateBrocastFactory.sendDevUpdateBrocast(this); 48 | } 49 | 50 | public DeviceInfo getDevInfo(){ 51 | return mDeviceInfo; 52 | } 53 | 54 | @Override 55 | public void onEvent(String eventID) { 56 | log.e("eventID = " + eventID); 57 | TCAgent.onEvent(this, eventID); 58 | } 59 | 60 | @Override 61 | public void onEvent(String eventID, HashMap map) { 62 | log.e("eventID = " + eventID); 63 | TCAgent.onEvent(this, eventID, "", map); 64 | } 65 | 66 | public static void onPause(Activity context){ 67 | MobclickAgent.onResume(context); 68 | TCAgent.onPause(context); 69 | } 70 | 71 | public static void onResume(Activity context){ 72 | MobclickAgent.onResume(context); 73 | TCAgent.onResume(context); 74 | } 75 | 76 | public static void onCatchError(Context context){ 77 | TCAgent.setReportUncaughtExceptions(true); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/DLNAGenaEventBrocastFactory.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | 8 | import com.geniusgithub.mediarender.jni.PlatinumReflection; 9 | import com.geniusgithub.mediarender.util.CommonLog; 10 | import com.geniusgithub.mediarender.util.DlnaUtils; 11 | import com.geniusgithub.mediarender.util.LogFactory; 12 | 13 | public class DLNAGenaEventBrocastFactory { 14 | 15 | private static final CommonLog log = LogFactory.createLog(); 16 | 17 | private DLNAGenaEventBrocastReceiver mReceiver; 18 | private Context mContext; 19 | 20 | public DLNAGenaEventBrocastFactory(Context context){ 21 | mContext = context; 22 | } 23 | 24 | public void registerBrocast(){ 25 | if (mReceiver == null){ 26 | mReceiver = new DLNAGenaEventBrocastReceiver(); 27 | mContext.registerReceiver(mReceiver, new IntentFilter(PlatinumReflection.RENDERER_TOCONTRPOINT_CMD_INTENT_NAME)); 28 | } 29 | } 30 | 31 | public void unRegisterBrocast(){ 32 | if (mReceiver != null){ 33 | mContext.unregisterReceiver(mReceiver); 34 | mReceiver = null; 35 | } 36 | } 37 | 38 | 39 | 40 | 41 | public static void sendTranstionEvent(Context context){ 42 | sendGenaPlayState(context, PlatinumReflection.MEDIA_PLAYINGSTATE_TRANSTION); 43 | } 44 | 45 | public static void sendDurationEvent(Context context, int duration){ 46 | if (duration != 0){ 47 | Intent setintent = new Intent(PlatinumReflection.RENDERER_TOCONTRPOINT_CMD_INTENT_NAME); 48 | setintent.putExtra(PlatinumReflection.GET_RENDERER_TOCONTRPOINT_CMD, PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_DURATION); 49 | setintent.putExtra(PlatinumReflection.GET_PARAM_MEDIA_DURATION, DlnaUtils.formatTimeFromMSInt(duration)); 50 | context.sendBroadcast(setintent); 51 | } 52 | } 53 | 54 | public static void sendSeekEvent(Context context, int time){ 55 | if (time != 0){ 56 | 57 | Intent setintent = new Intent(PlatinumReflection.RENDERER_TOCONTRPOINT_CMD_INTENT_NAME); 58 | setintent.putExtra(PlatinumReflection.GET_RENDERER_TOCONTRPOINT_CMD, PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_POSITION); 59 | setintent.putExtra(PlatinumReflection.GET_PARAM_MEDIA_POSITION, DlnaUtils.formatTimeFromMSInt(time)); 60 | context.sendBroadcast(setintent); 61 | } 62 | } 63 | 64 | public static void sendPlayStateEvent(Context context){ 65 | sendGenaPlayState(context, PlatinumReflection.MEDIA_PLAYINGSTATE_PLAYING); 66 | } 67 | 68 | public static void sendPauseStateEvent(Context context){ 69 | sendGenaPlayState(context, PlatinumReflection.MEDIA_PLAYINGSTATE_PAUSE); 70 | } 71 | 72 | 73 | public static void sendStopStateEvent(Context context){ 74 | sendGenaPlayState(context, PlatinumReflection.MEDIA_PLAYINGSTATE_STOP); 75 | } 76 | 77 | 78 | private static void sendGenaPlayState(Context context, String state){ 79 | Intent intent = new Intent(PlatinumReflection.RENDERER_TOCONTRPOINT_CMD_INTENT_NAME); 80 | intent.putExtra(PlatinumReflection.GET_RENDERER_TOCONTRPOINT_CMD, PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_PLAYINGSTATE); 81 | intent.putExtra(PlatinumReflection.GET_PARAM_MEDIA_PLAYINGSTATE, state); 82 | context.sendBroadcast(intent); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/DLNAGenaEventBrocastReceiver.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | 4 | 5 | import android.content.BroadcastReceiver; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | 9 | import com.geniusgithub.mediarender.jni.PlatinumJniProxy; 10 | import com.geniusgithub.mediarender.jni.PlatinumReflection; 11 | import com.geniusgithub.mediarender.util.CommonLog; 12 | import com.geniusgithub.mediarender.util.LogFactory; 13 | 14 | 15 | 16 | public class DLNAGenaEventBrocastReceiver extends BroadcastReceiver{ 17 | 18 | private static final CommonLog log = LogFactory.createLog(); 19 | 20 | @Override 21 | public void onReceive(Context context, Intent intent) { 22 | String action = intent.getAction(); 23 | if (action == null){ 24 | return ; 25 | } 26 | 27 | if (PlatinumReflection.RENDERER_TOCONTRPOINT_CMD_INTENT_NAME.equalsIgnoreCase(action)){ 28 | onTransdelGenaEvent(intent); 29 | } 30 | } 31 | 32 | 33 | private void onTransdelGenaEvent(Intent intent){ 34 | 35 | int cmd = intent.getIntExtra(PlatinumReflection.GET_RENDERER_TOCONTRPOINT_CMD, 0); 36 | 37 | switch(cmd){ 38 | case 0: 39 | break; 40 | case PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_DURATION: 41 | String duration = intent.getStringExtra(PlatinumReflection.GET_PARAM_MEDIA_DURATION); 42 | PlatinumJniProxy.responseGenaEvent(PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_DURATION, duration, null); 43 | break; 44 | case PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_POSITION: 45 | String positionto = intent.getStringExtra(PlatinumReflection.GET_PARAM_MEDIA_POSITION); 46 | PlatinumJniProxy.responseGenaEvent(PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_POSITION, 47 | positionto,null); 48 | break; 49 | case PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_PLAYINGSTATE: 50 | String playingstate = intent.getStringExtra(PlatinumReflection.GET_PARAM_MEDIA_PLAYINGSTATE); 51 | PlatinumJniProxy.responseGenaEvent(PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_PLAYINGSTATE, 52 | playingstate,null); 53 | 54 | 55 | if (playingstate.equalsIgnoreCase(PlatinumReflection.MEDIA_PLAYINGSTATE_STOP)){ 56 | PlatinumJniProxy.responseGenaEvent(PlatinumReflection.MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_POSITION, "00:00:00", null); 57 | } 58 | break; 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/DMRCenter.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Handler; 6 | import android.os.Message; 7 | 8 | import com.geniusgithub.mediarender.image.ImageActivity; 9 | import com.geniusgithub.mediarender.jni.PlatinumReflection; 10 | import com.geniusgithub.mediarender.jni.PlatinumReflection.ActionReflectionListener; 11 | import com.geniusgithub.mediarender.music.MusicActivity; 12 | import com.geniusgithub.mediarender.util.CommonLog; 13 | import com.geniusgithub.mediarender.util.CommonUtil; 14 | import com.geniusgithub.mediarender.util.DlnaUtils; 15 | import com.geniusgithub.mediarender.util.LogFactory; 16 | import com.geniusgithub.mediarender.video.VideoActivity; 17 | 18 | public class DMRCenter implements ActionReflectionListener, IDMRAction{ 19 | 20 | private static final CommonLog log = LogFactory.createLog(); 21 | 22 | private Context mContext; 23 | 24 | private DlnaMediaModel mMusicMediaInfo; 25 | private DlnaMediaModel mVideoMediaInfo; 26 | private DlnaMediaModel mImageMediaInfo; 27 | 28 | private int mCurMediaInfoType = -1; 29 | public static final int CUR_MEDIA_TYPE_MUSCI = 0x0001; 30 | public static final int CUR_MEDIA_TYPE_VIDEO = 0x0002; 31 | public static final int CUR_MEDIA_TYPE_PICTURE = 0x0003; 32 | 33 | public DMRCenter(Context context){ 34 | mContext = context; 35 | } 36 | 37 | @Override 38 | public synchronized void onActionInvoke(int cmd, String value, String data) { 39 | 40 | switch(cmd){ 41 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_SET_AV_URL: 42 | onRenderAvTransport(value, data); 43 | break; 44 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_PLAY: 45 | onRenderPlay(value, data); 46 | break; 47 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_PAUSE: 48 | onRenderPause(value, data); 49 | break; 50 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_STOP: 51 | onRenderStop(value, data); 52 | break; 53 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_SEEK: 54 | onRenderSeek(value, data); 55 | break; 56 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_SETMUTE: 57 | onRenderSetMute(value, data); 58 | break; 59 | case PlatinumReflection.MEDIA_RENDER_CTL_MSG_SETVOLUME: 60 | onRenderSetVolume(value, data); 61 | break; 62 | default: 63 | log.e("unrognized cmd!!!"); 64 | break; 65 | } 66 | } 67 | 68 | @Override 69 | public void onRenderAvTransport(String value, String data) { 70 | if (data == null){ 71 | log.e("meteData = null!!!"); 72 | return ; 73 | } 74 | 75 | if (value == null || value.length() < 2){ 76 | log.e("url = " + value + ", it's invalid..."); 77 | return ; 78 | } 79 | 80 | DlnaMediaModel mediaInfo = DlnaMediaModelFactory.createFromMetaData(data); 81 | mediaInfo.setUrl(value); 82 | if (DlnaUtils.isAudioItem(mediaInfo)){ 83 | mMusicMediaInfo = mediaInfo; 84 | mCurMediaInfoType = CUR_MEDIA_TYPE_MUSCI; 85 | }else if (DlnaUtils.isVideoItem(mediaInfo)){ 86 | mVideoMediaInfo = mediaInfo; 87 | mCurMediaInfoType = CUR_MEDIA_TYPE_VIDEO; 88 | }else if (DlnaUtils.isImageItem(mediaInfo)){ 89 | mImageMediaInfo = mediaInfo; 90 | mCurMediaInfoType = CUR_MEDIA_TYPE_PICTURE; 91 | }else{ 92 | log.e("unknow media type!!! mediainfo.objectclass = \n" + mediaInfo.getObjectClass()); 93 | } 94 | } 95 | 96 | @Override 97 | public void onRenderPlay(String value, String data) { 98 | switch(mCurMediaInfoType){ 99 | case CUR_MEDIA_TYPE_MUSCI: 100 | if (mMusicMediaInfo != null){ 101 | delayToPlayMusic(mMusicMediaInfo); 102 | }else{ 103 | MediaControlBrocastFactory.sendPlayBrocast(mContext); 104 | } 105 | clearState(); 106 | break; 107 | case CUR_MEDIA_TYPE_VIDEO: 108 | if (mVideoMediaInfo != null){ 109 | delayToPlayVideo(mVideoMediaInfo); 110 | }else{ 111 | MediaControlBrocastFactory.sendPlayBrocast(mContext); 112 | } 113 | clearState(); 114 | break; 115 | case CUR_MEDIA_TYPE_PICTURE: 116 | if (mImageMediaInfo != null){ 117 | delayToPlayImage(mImageMediaInfo); 118 | }else{ 119 | MediaControlBrocastFactory.sendPlayBrocast(mContext); 120 | } 121 | clearState(); 122 | break; 123 | } 124 | } 125 | 126 | @Override 127 | public void onRenderPause(String value, String data) { 128 | MediaControlBrocastFactory.sendPauseBrocast(mContext); 129 | } 130 | 131 | @Override 132 | public void onRenderStop(String value, String data) { 133 | delayToStop(); 134 | MediaControlBrocastFactory.sendStopBorocast(mContext); 135 | } 136 | 137 | @Override 138 | public void onRenderSeek(String value, String data) { 139 | int seekPos = 0; 140 | try { 141 | seekPos = DlnaUtils.parseSeekTime(value); 142 | MediaControlBrocastFactory.sendSeekBrocast(mContext, seekPos); 143 | } catch (Exception e) { 144 | e.printStackTrace(); 145 | } 146 | } 147 | 148 | @Override 149 | public void onRenderSetMute(String value, String data) { 150 | 151 | if ("1".equals(value)){ 152 | CommonUtil.setVolumeMute(mContext); 153 | }else if("0".equals(value)){ 154 | CommonUtil.setVolumeUnmute(mContext); 155 | } 156 | } 157 | 158 | @Override 159 | public void onRenderSetVolume(String value, String data) { 160 | try { 161 | int volume = Integer.valueOf(value); 162 | if(volume < 101){ 163 | CommonUtil.setCurrentVolume(volume, mContext); 164 | } 165 | } catch (Exception e) { 166 | e.printStackTrace(); 167 | } 168 | } 169 | 170 | 171 | 172 | 173 | 174 | private void clearState(){ 175 | mMusicMediaInfo = null; 176 | mVideoMediaInfo = null; 177 | mImageMediaInfo = null; 178 | } 179 | 180 | 181 | 182 | private static final int DELAYTIME = 200; 183 | private void delayToPlayMusic(DlnaMediaModel mediaInfo){ 184 | if (mediaInfo != null) 185 | { 186 | clearDelayMsg(); 187 | Message msg = mHandler.obtainMessage(MSG_START_MUSICPLAY, mediaInfo); 188 | mHandler.sendMessageDelayed(msg, DELAYTIME); 189 | } 190 | } 191 | 192 | private void delayToPlayVideo(DlnaMediaModel mediaInfo){ 193 | if (mediaInfo != null) 194 | { 195 | clearDelayMsg(); 196 | Message msg = mHandler.obtainMessage(MSG_START_VIDOPLAY, mediaInfo); 197 | mHandler.sendMessageDelayed(msg, DELAYTIME); 198 | } 199 | } 200 | 201 | private void delayToPlayImage(DlnaMediaModel mediaInfo){ 202 | if (mediaInfo != null){ 203 | clearDelayMsg(); 204 | Message msg = mHandler.obtainMessage(MSG_START_PICPLAY, mediaInfo); 205 | mHandler.sendMessageDelayed(msg, DELAYTIME); 206 | } 207 | } 208 | 209 | private void delayToStop(){ 210 | clearDelayMsg(); 211 | mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SEND_STOPCMD), DELAYTIME); 212 | } 213 | 214 | private void clearDelayMsg(){ 215 | clearDelayMsg(MSG_START_MUSICPLAY); 216 | clearDelayMsg(MSG_START_PICPLAY); 217 | clearDelayMsg(MSG_START_VIDOPLAY); 218 | clearDelayMsg(MSG_SEND_STOPCMD); 219 | } 220 | 221 | private void clearDelayMsg(int num){ 222 | mHandler.removeMessages(num); 223 | } 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | private static final int MSG_START_MUSICPLAY = 0x0001; 237 | private static final int MSG_START_PICPLAY = 0x0002; 238 | private static final int MSG_START_VIDOPLAY = 0x0003; 239 | private static final int MSG_SEND_STOPCMD = 0x0004; 240 | 241 | private Handler mHandler = new Handler(){ 242 | 243 | @Override 244 | public void dispatchMessage(Message msg) { 245 | 246 | try { 247 | switch(msg.what){ 248 | case MSG_START_MUSICPLAY: 249 | DlnaMediaModel mediaInfo1 = (DlnaMediaModel) msg.obj; 250 | startPlayMusic(mediaInfo1); 251 | break; 252 | case MSG_START_PICPLAY: 253 | DlnaMediaModel mediaInfo2 = (DlnaMediaModel) msg.obj; 254 | startPlayPicture(mediaInfo2); 255 | break; 256 | case MSG_START_VIDOPLAY: 257 | DlnaMediaModel mediaInfo3 = (DlnaMediaModel) msg.obj; 258 | startPlayVideo(mediaInfo3); 259 | break; 260 | case MSG_SEND_STOPCMD: 261 | MediaControlBrocastFactory.sendStopBorocast(mContext); 262 | break; 263 | } 264 | } catch (Exception e) { 265 | e.printStackTrace(); 266 | log.e("DMRCenter transdel msg catch Exception!!! msgID = " + msg.what); 267 | } 268 | 269 | } 270 | 271 | }; 272 | 273 | 274 | private void startPlayMusic(DlnaMediaModel mediaInfo){ 275 | log.d("startPlayMusic"); 276 | Intent intent = new Intent(); 277 | intent.setClass(mContext, MusicActivity.class); 278 | DlnaMediaModelFactory.pushMediaModelToIntent(intent, mediaInfo); 279 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP); 280 | mContext.startActivity(intent); 281 | } 282 | 283 | 284 | 285 | private void startPlayVideo(DlnaMediaModel mediaInfo){ 286 | log.d("startPlayVideo"); 287 | Intent intent = new Intent(); 288 | intent.setClass(mContext, VideoActivity.class); 289 | DlnaMediaModelFactory.pushMediaModelToIntent(intent, mediaInfo); 290 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP); 291 | mContext.startActivity(intent); 292 | 293 | } 294 | 295 | private void startPlayPicture(DlnaMediaModel mediaInfo){ 296 | log.d("startPlayPicture"); 297 | Intent intent = new Intent(); 298 | intent.setClass(mContext, ImageActivity.class); 299 | DlnaMediaModelFactory.pushMediaModelToIntent(intent, mediaInfo); 300 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP); 301 | mContext.startActivity(intent); 302 | } 303 | 304 | 305 | 306 | } 307 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/DMRWorkThread.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | import android.content.Context; 4 | 5 | import com.geniusgithub.mediarender.RenderApplication; 6 | import com.geniusgithub.mediarender.jni.PlatinumJniProxy; 7 | import com.geniusgithub.mediarender.util.CommonLog; 8 | import com.geniusgithub.mediarender.util.CommonUtil; 9 | import com.geniusgithub.mediarender.util.LogFactory; 10 | 11 | public class DMRWorkThread extends Thread implements IBaseEngine{ 12 | 13 | 14 | private static final CommonLog log = LogFactory.createLog(); 15 | 16 | private static final int CHECK_INTERVAL = 30 * 1000; 17 | 18 | private Context mContext = null; 19 | private boolean mStartSuccess = false; 20 | private boolean mExitFlag = false; 21 | 22 | private String mFriendName = ""; 23 | private String mUUID = ""; 24 | private RenderApplication mApplication; 25 | 26 | public DMRWorkThread(Context context){ 27 | mContext = context; 28 | mApplication = RenderApplication.getInstance(); 29 | } 30 | 31 | public void setFlag(boolean flag){ 32 | mStartSuccess = flag; 33 | } 34 | 35 | public void setParam(String friendName, String uuid){ 36 | mFriendName = friendName; 37 | mUUID = uuid; 38 | mApplication.updateDevInfo(mFriendName, mUUID); 39 | } 40 | 41 | public void awakeThread(){ 42 | synchronized (this) { 43 | notifyAll(); 44 | } 45 | } 46 | 47 | public void exit(){ 48 | mExitFlag = true; 49 | awakeThread(); 50 | } 51 | 52 | @Override 53 | public void run() { 54 | 55 | log.e("DMRWorkThread run..."); 56 | 57 | while(true) 58 | { 59 | if (mExitFlag){ 60 | stopEngine(); 61 | break; 62 | } 63 | refreshNotify(); 64 | synchronized(this) 65 | { 66 | try 67 | { 68 | wait(CHECK_INTERVAL); 69 | } 70 | catch(Exception e) 71 | { 72 | e.printStackTrace(); 73 | } 74 | } 75 | if (mExitFlag){ 76 | stopEngine(); 77 | break; 78 | } 79 | } 80 | 81 | log.e("DMRWorkThread over..."); 82 | 83 | } 84 | 85 | public void refreshNotify(){ 86 | if (!CommonUtil.checkNetworkState(mContext)){ 87 | return ; 88 | } 89 | 90 | if (!mStartSuccess){ 91 | stopEngine(); 92 | try { 93 | Thread.sleep(200); 94 | } catch (InterruptedException e) { 95 | e.printStackTrace(); 96 | } 97 | boolean ret = startEngine(); 98 | if (ret){ 99 | mStartSuccess = true; 100 | } 101 | } 102 | 103 | } 104 | 105 | @Override 106 | public boolean startEngine() { 107 | if (mFriendName.length() == 0){ 108 | return false; 109 | } 110 | 111 | int ret = PlatinumJniProxy.startMediaRender(mFriendName, mUUID); 112 | boolean result = (ret == 0 ? true : false); 113 | mApplication.setDevStatus(result); 114 | return result; 115 | } 116 | 117 | @Override 118 | public boolean stopEngine() { 119 | PlatinumJniProxy.stopMediaRender(); 120 | mApplication.setDevStatus(false); 121 | return true; 122 | } 123 | 124 | @Override 125 | public boolean restartEngine() { 126 | setFlag(false); 127 | awakeThread(); 128 | return true; 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/DlnaMediaModel.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | public class DlnaMediaModel { 4 | 5 | private String uri = ""; 6 | private String title = ""; 7 | private String artist = ""; 8 | private String album = ""; 9 | private String albumiconuri = ""; 10 | private String objectclass = ""; 11 | 12 | 13 | public String getTitle() { 14 | return title; 15 | } 16 | public void setTitle(String title) { 17 | this.title = (title != null ? title : ""); 18 | } 19 | 20 | public String getArtist() { 21 | return artist; 22 | } 23 | public void setArtist(String artist) { 24 | this.artist = (artist != null ? artist : ""); 25 | } 26 | 27 | public void setAlbum(String album) { 28 | this.album = (album != null ? album : ""); 29 | } 30 | public String getAlbum() { 31 | return album; 32 | } 33 | 34 | public void setObjectClass(String objectClass) { 35 | this.objectclass = (objectClass != null ? objectClass : ""); 36 | } 37 | public String getObjectClass() { 38 | return objectclass; 39 | } 40 | 41 | public void setUrl(String uri) { 42 | this.uri = (uri != null ? uri : ""); 43 | } 44 | public String getUrl() { 45 | return uri; 46 | } 47 | 48 | public String getAlbumUri(){ 49 | return albumiconuri; 50 | } 51 | public void setAlbumUri(String albumiconuri){ 52 | this.albumiconuri = (albumiconuri != null ? albumiconuri : ""); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/DlnaMediaModelFactory.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.InputStream; 5 | 6 | import javax.xml.parsers.DocumentBuilder; 7 | import javax.xml.parsers.DocumentBuilderFactory; 8 | 9 | import org.w3c.dom.Document; 10 | import org.w3c.dom.Node; 11 | import org.w3c.dom.NodeList; 12 | 13 | import android.content.Intent; 14 | 15 | import com.geniusgithub.mediarender.util.CommonLog; 16 | import com.geniusgithub.mediarender.util.LogFactory; 17 | 18 | public class DlnaMediaModelFactory { 19 | 20 | private static final CommonLog log = LogFactory.createLog(); 21 | 22 | public static final String PARAM_GET_URL = "param_metadata__url"; 23 | public static final String PARAM_GET_OBJECT_CLASS = "param_metadata_object_class"; 24 | public static final String PARAM_GET_TITLE = "param_metadata_title"; 25 | public static final String PARAM_GET_ARTIST = "param_metadata_artist"; 26 | public static final String PARAM_GET_ALBUM = "param_metadata_album"; 27 | public static final String PARAM_GET_ALBUMICONURI = "param_metadata_album_uri"; 28 | 29 | 30 | 31 | public static void pushMediaModelToIntent(Intent intent, DlnaMediaModel mediaInfo){ 32 | intent.putExtra(PARAM_GET_URL, mediaInfo.getUrl()); 33 | intent.putExtra(PARAM_GET_OBJECT_CLASS, mediaInfo.getObjectClass()); 34 | intent.putExtra(PARAM_GET_TITLE, mediaInfo.getTitle()); 35 | intent.putExtra(PARAM_GET_ARTIST, mediaInfo.getArtist()); 36 | intent.putExtra(PARAM_GET_ALBUM, mediaInfo.getAlbum()); 37 | intent.putExtra(PARAM_GET_ALBUMICONURI, mediaInfo.getAlbumUri()); 38 | } 39 | 40 | public static DlnaMediaModel createFromIntent(Intent intent){ 41 | DlnaMediaModel mediaInfo = new DlnaMediaModel(); 42 | mediaInfo.setUrl(intent.getStringExtra(PARAM_GET_URL)); 43 | mediaInfo.setObjectClass(intent.getStringExtra(PARAM_GET_OBJECT_CLASS)); 44 | mediaInfo.setTitle(intent.getStringExtra(PARAM_GET_TITLE)); 45 | mediaInfo.setArtist(intent.getStringExtra(PARAM_GET_ARTIST)); 46 | mediaInfo.setAlbum(intent.getStringExtra(PARAM_GET_ALBUM)); 47 | mediaInfo.setAlbumUri(intent.getStringExtra(PARAM_GET_ALBUMICONURI)); 48 | return mediaInfo; 49 | } 50 | 51 | public static DlnaMediaModel createFromMetaData(String metadata){ 52 | DlnaMediaModel mediainfo = new DlnaMediaModel(); 53 | DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 54 | DocumentBuilder documentBuilder; 55 | 56 | if (metadata.contains("&") && !metadata.contains("&")){ 57 | metadata = metadata.replace("&", "&"); 58 | } 59 | 60 | try { 61 | documentBuilder = dfactory.newDocumentBuilder(); 62 | InputStream is = new ByteArrayInputStream(metadata.getBytes("UTF-8")); 63 | Document doc = documentBuilder.parse(is); 64 | mediainfo.setObjectClass(getElementValue(doc,"upnp:class")); 65 | mediainfo.setTitle(getElementValue(doc,"dc:title")); 66 | mediainfo.setAlbum(getElementValue(doc,"upnp:album")); 67 | mediainfo.setArtist(getElementValue(doc,"upnp:artist")); 68 | mediainfo.setAlbumUri(getElementValue(doc,"upnp:albumArtURI")); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | } 72 | return mediainfo; 73 | } 74 | 75 | private static String getElementValue(Document doc , String element){ 76 | NodeList containers = doc.getElementsByTagName(element); 77 | for (int j = 0; j < containers.getLength(); ++j) { 78 | Node container = containers.item(j); 79 | NodeList childNodes = container.getChildNodes(); 80 | if(childNodes.getLength()!=0){ 81 | Node childNode = childNodes.item(0); 82 | return childNode.getNodeValue(); 83 | } 84 | } 85 | return ""; 86 | } 87 | } 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/IBaseEngine.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | public interface IBaseEngine { 4 | 5 | public boolean startEngine(); 6 | public boolean stopEngine(); 7 | public boolean restartEngine(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/IDMRAction.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | 4 | public interface IDMRAction { 5 | public void onRenderAvTransport(String value, String data); 6 | public void onRenderPlay(String value, String data); 7 | public void onRenderPause(String value, String data); 8 | public void onRenderStop(String value, String data); 9 | public void onRenderSeek(String value, String data); 10 | public void onRenderSetMute(String value, String data); 11 | public void onRenderSetVolume(String value, String data); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/MediaControlBrocastFactory.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | 8 | public class MediaControlBrocastFactory { 9 | 10 | public static interface IMediaControlListener { 11 | public void onPlayCommand(); 12 | public void onPauseCommand(); 13 | public void onStopCommand(); 14 | public void onSeekCommand(int time); 15 | } 16 | 17 | 18 | private MediaControlBrocastReceiver mMediaControlReceiver; 19 | private Context mContext; 20 | 21 | public MediaControlBrocastFactory(Context context){ 22 | mContext = context; 23 | } 24 | 25 | 26 | public void register(IMediaControlListener listener){ 27 | if (mMediaControlReceiver == null){ 28 | mMediaControlReceiver = new MediaControlBrocastReceiver(); 29 | mMediaControlReceiver.setMediaControlListener(listener); 30 | 31 | mContext.registerReceiver(mMediaControlReceiver, new IntentFilter(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_PLAY)); 32 | mContext.registerReceiver(mMediaControlReceiver, new IntentFilter(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_PAUSE)); 33 | mContext.registerReceiver(mMediaControlReceiver, new IntentFilter(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_STOP)); 34 | mContext.registerReceiver(mMediaControlReceiver, new IntentFilter(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_SEEKPS)); 35 | 36 | } 37 | } 38 | 39 | public void unregister() 40 | { 41 | if (mMediaControlReceiver != null){ 42 | mContext.unregisterReceiver(mMediaControlReceiver); 43 | mMediaControlReceiver = null; 44 | } 45 | } 46 | 47 | 48 | 49 | public static final String MEDIA_RENDERER_CMD_PLAY="com.geniusgithub.control.play_command"; 50 | public static final String MEDIA_RENDERER_CMD_PAUSE="com.geniusgithub.control.pause_command"; 51 | public static final String MEDIA_RENDERER_CMD_STOP="com.geniusgithub.control.stop_command"; 52 | public static final String MEDIA_RENDERER_CMD_SEEKPS="com.geniusgithub.control.seekps_command"; 53 | 54 | public static final String PARAM_CMD_SEEKPS="get_param_seekps"; 55 | 56 | 57 | 58 | public static void sendPlayBrocast(Context context){ 59 | Intent intent = new Intent(MEDIA_RENDERER_CMD_PLAY); 60 | context.sendBroadcast(intent); 61 | } 62 | 63 | public static void sendPauseBrocast(Context context){ 64 | Intent intent = new Intent(MEDIA_RENDERER_CMD_PAUSE); 65 | context.sendBroadcast(intent); 66 | } 67 | 68 | public static void sendStopBorocast(Context context){ 69 | Intent intent = new Intent(MEDIA_RENDERER_CMD_STOP); 70 | context.sendBroadcast(intent); 71 | } 72 | 73 | public static void sendSeekBrocast(Context context, int seekPos){ 74 | Intent intent = new Intent(MEDIA_RENDERER_CMD_SEEKPS); 75 | intent.putExtra(PARAM_CMD_SEEKPS, seekPos); 76 | context.sendBroadcast(intent); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/MediaControlBrocastReceiver.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | import com.geniusgithub.mediarender.util.CommonLog; 4 | import com.geniusgithub.mediarender.util.LogFactory; 5 | 6 | import android.content.BroadcastReceiver; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | 10 | 11 | 12 | public class MediaControlBrocastReceiver extends BroadcastReceiver{ 13 | 14 | private static final CommonLog log = LogFactory.createLog(); 15 | private MediaControlBrocastFactory.IMediaControlListener mMediaControlListener; 16 | 17 | @Override 18 | public void onReceive(Context context, Intent intent) { 19 | 20 | String action = intent.getAction(); 21 | if (action != null && mMediaControlListener != null){ 22 | TransdelControlCommand(intent); 23 | } 24 | } 25 | 26 | public void setMediaControlListener(MediaControlBrocastFactory.IMediaControlListener listener) 27 | { 28 | mMediaControlListener = listener; 29 | } 30 | 31 | private void TransdelControlCommand(Intent intent){ 32 | int time = 0; 33 | String action = intent.getAction(); 34 | if (action.equalsIgnoreCase(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_PLAY)){ 35 | mMediaControlListener.onPlayCommand(); 36 | }else if (action.equalsIgnoreCase(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_PAUSE)){ 37 | mMediaControlListener.onPauseCommand(); 38 | }else if (action.equalsIgnoreCase(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_STOP)){ 39 | mMediaControlListener.onStopCommand(); 40 | }else if (action.equalsIgnoreCase(MediaControlBrocastFactory.MEDIA_RENDERER_CMD_SEEKPS)){ 41 | time = intent.getIntExtra(MediaControlBrocastFactory.PARAM_CMD_SEEKPS, 0); 42 | mMediaControlListener.onSeekCommand(time); 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/center/MediaRenderProxy.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.center; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.geniusgithub.mediarender.RenderApplication; 7 | import com.geniusgithub.mediarender.service.MediaRenderService; 8 | import com.geniusgithub.mediarender.util.CommonLog; 9 | import com.geniusgithub.mediarender.util.LogFactory; 10 | 11 | public class MediaRenderProxy implements IBaseEngine{ 12 | 13 | private static final CommonLog log = LogFactory.createLog(); 14 | 15 | private static MediaRenderProxy mInstance; 16 | private Context mContext; 17 | 18 | private MediaRenderProxy(Context context) { 19 | mContext = context; 20 | } 21 | 22 | public static synchronized MediaRenderProxy getInstance() { 23 | if (mInstance == null){ 24 | mInstance = new MediaRenderProxy(RenderApplication.getInstance()); 25 | } 26 | return mInstance; 27 | } 28 | 29 | @Override 30 | public boolean startEngine() { 31 | Intent intent = new Intent(MediaRenderService.START_RENDER_ENGINE); 32 | intent.setPackage(mContext.getPackageName()); 33 | mContext.startService(intent); 34 | return true; 35 | } 36 | 37 | @Override 38 | public boolean stopEngine() { 39 | mContext.stopService(new Intent(mContext, MediaRenderService.class)); 40 | return true; 41 | } 42 | 43 | @Override 44 | public boolean restartEngine() { 45 | Intent intent = new Intent(MediaRenderService.RESTART_RENDER_ENGINE); 46 | intent.setPackage(mContext.getPackageName()); 47 | mContext.startService(intent); 48 | return true; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/datastore/LocalConfigSharePreference.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.datastore; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.content.SharedPreferences.Editor; 6 | 7 | public class LocalConfigSharePreference { 8 | 9 | public static final String preference_name = "LocalConfigSharePreference"; 10 | public static final String dev_name = "dev_name"; 11 | 12 | public static boolean commintDevName(Context context, String devName){ 13 | 14 | SharedPreferences sharedPreferences = context.getSharedPreferences(preference_name, 0); 15 | Editor editor = sharedPreferences.edit(); 16 | editor.putString(dev_name, devName); 17 | editor.commit(); 18 | return true; 19 | } 20 | 21 | public static String getDevName(Context context){ 22 | SharedPreferences sharedPreferences = context.getSharedPreferences(preference_name, 0); 23 | String value = sharedPreferences.getString(dev_name, "geniusgithub"); 24 | return value; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/image/DownLoadHelper.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.image; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | import com.geniusgithub.mediarender.util.CommonLog; 7 | import com.geniusgithub.mediarender.util.LogFactory; 8 | 9 | 10 | 11 | public class DownLoadHelper { 12 | 13 | private static final CommonLog log = LogFactory.createLog(); 14 | 15 | private final static int THREAD_COUNT = 1; 16 | private ExecutorService mExecutorService; 17 | 18 | public DownLoadHelper(){ 19 | 20 | } 21 | 22 | public void init(){ 23 | if (mExecutorService == null){ 24 | mExecutorService = Executors.newFixedThreadPool(THREAD_COUNT); 25 | } 26 | } 27 | 28 | 29 | public void unInit(){ 30 | if (mExecutorService != null) 31 | { 32 | mExecutorService.shutdown(); 33 | mExecutorService.shutdownNow(); 34 | mExecutorService = null; 35 | } 36 | } 37 | 38 | 39 | 40 | public static interface IDownLoadCallback{ 41 | public void downLoadResult(final boolean isSuccess,final String savePath); 42 | } 43 | 44 | 45 | public boolean syncDownLoadFile(String requestUrl, String saveUrl, IDownLoadCallback callback){ 46 | if (mExecutorService == null){ 47 | return false; 48 | } 49 | log.d("syncDownLoadFile requestUrl = " + requestUrl); 50 | FileDownTask fTask = new FileDownTask(requestUrl, saveUrl, callback); 51 | mExecutorService.execute(fTask); 52 | 53 | return true; 54 | 55 | } 56 | 57 | 58 | 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/image/FileDownTask.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.image; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.HttpURLConnection; 6 | import java.net.MalformedURLException; 7 | import java.net.URL; 8 | 9 | import com.geniusgithub.mediarender.util.CommonLog; 10 | import com.geniusgithub.mediarender.util.FileHelper; 11 | import com.geniusgithub.mediarender.util.LogFactory; 12 | 13 | 14 | public class FileDownTask implements Runnable{ 15 | 16 | private static final CommonLog log = LogFactory.createLog(); 17 | private final static int MAX_REQUEST_COUNT = 3; 18 | private final static int CONNECT_TIME_OUT = 5000; 19 | 20 | public String requesetMethod = "GET"; 21 | public String requestUrl; 22 | public String saveUri; 23 | public int responsCode = 0; 24 | public boolean isDownloadSuccess = false; 25 | public DownLoadHelper.IDownLoadCallback callback; 26 | 27 | public FileDownTask(String requestUrl, String saveUri, DownLoadHelper.IDownLoadCallback callback){ 28 | this.requestUrl = requestUrl; 29 | this.saveUri = saveUri; 30 | this.callback = callback; 31 | } 32 | 33 | @Override 34 | public void run() { 35 | 36 | boolean isParamValid = isParamValid(); 37 | if(isParamValid){ 38 | boolean ret = false; 39 | int count = 0; 40 | while(true){ 41 | ret = request(); 42 | if (ret || count > 2){ 43 | break; 44 | } 45 | count++; 46 | log.e("request fail,cur count = " + count); 47 | } 48 | }else{ 49 | log.e("isParamValid = false!!!"); 50 | } 51 | 52 | if (callback != null){ 53 | callback.downLoadResult(isDownloadSuccess, saveUri); 54 | } 55 | } 56 | 57 | private boolean request(){ 58 | 59 | InputStream inputStream = null; 60 | try { 61 | URL url = new URL(requestUrl); 62 | HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 63 | conn.setRequestMethod(requesetMethod); 64 | conn.setRequestProperty("Connection", "Keep-Alive"); 65 | conn.setConnectTimeout(CONNECT_TIME_OUT); 66 | responsCode = conn.getResponseCode(); 67 | if (responsCode != 200){ 68 | log.e("responsCode = " + responsCode + ", so Fail!!!"); 69 | return false; 70 | } 71 | 72 | inputStream = conn.getInputStream(); 73 | isDownloadSuccess = FileHelper.writeFile(saveUri, inputStream); 74 | 75 | inputStream.close(); 76 | return isDownloadSuccess; 77 | 78 | } catch (MalformedURLException e) { 79 | e.printStackTrace(); 80 | log.e("catch MalformedURLException e = " + e.getMessage()); 81 | }catch (IOException e) { 82 | e.printStackTrace(); 83 | log.e("catch IOException e = " + e.getMessage() + ", inputStream = " + inputStream); 84 | } 85 | 86 | 87 | return false; 88 | } 89 | 90 | public boolean isParamValid(){ 91 | if (requestUrl == null || saveUri == null){ 92 | return false; 93 | } 94 | 95 | return true; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/image/FileManager.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.image; 2 | 3 | import com.geniusgithub.mediarender.util.CommonUtil; 4 | 5 | 6 | public class FileManager { 7 | 8 | public static String getSaveRootDir() { 9 | if (CommonUtil.hasSDCard()) { 10 | return CommonUtil.getRootFilePath() + "icons/"; 11 | } else { 12 | return CommonUtil.getRootFilePath() + "com.geniusgithub/icons/"; 13 | } 14 | } 15 | 16 | public static String getSaveFullPath(String uri) { 17 | return getSaveRootDir() + getFormatUri(uri); 18 | } 19 | 20 | 21 | public static String getFormatUri(String uri) 22 | { 23 | uri = uri.replace("/", "_"); 24 | uri = uri.replace(":", ""); 25 | uri = uri.replace("?", "_"); 26 | uri = uri.replace("%", "_"); 27 | 28 | int length = uri.length(); 29 | if (length > 150) 30 | { 31 | uri = uri.substring(length - 150); 32 | } 33 | 34 | 35 | return uri; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/image/ImageActivity.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.image; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | 7 | import android.app.Activity; 8 | import android.content.Intent; 9 | import android.graphics.Bitmap; 10 | import android.graphics.BitmapFactory; 11 | import android.os.Bundle; 12 | import android.os.Handler; 13 | import android.os.Message; 14 | import android.view.View; 15 | import android.widget.ImageView; 16 | import android.widget.Toast; 17 | 18 | import com.geniusgithub.mediarender.BaseActivity; 19 | import com.geniusgithub.mediarender.R; 20 | import com.geniusgithub.mediarender.center.DlnaMediaModel; 21 | import com.geniusgithub.mediarender.center.DlnaMediaModelFactory; 22 | import com.geniusgithub.mediarender.center.MediaControlBrocastFactory; 23 | import com.geniusgithub.mediarender.player.AbstractTimer; 24 | import com.geniusgithub.mediarender.player.SingleSecondTimer; 25 | import com.geniusgithub.mediarender.util.CommonLog; 26 | import com.geniusgithub.mediarender.util.CommonUtil; 27 | import com.geniusgithub.mediarender.util.FileHelper; 28 | import com.geniusgithub.mediarender.util.LogFactory; 29 | 30 | public class ImageActivity extends BaseActivity implements MediaControlBrocastFactory.IMediaControlListener, 31 | DownLoadHelper.IDownLoadCallback{ 32 | 33 | private static final CommonLog log = LogFactory.createLog(); 34 | 35 | private int mScreenWidth = 0; 36 | private int mScreenHeight = 0; 37 | 38 | private Handler mHandler; 39 | private UIManager mUIManager; 40 | private DownLoadHelper mDownLoadHelper; 41 | private DelCacheFileManager mDelCacheFileManager; 42 | 43 | private DlnaMediaModel mMediaInfo = new DlnaMediaModel(); 44 | private MediaControlBrocastFactory mMediaControlBorcastFactor; 45 | 46 | @Override 47 | protected void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | log.e("onCreate"); 50 | 51 | setContentView(R.layout.image_player_layout); 52 | 53 | initView(); 54 | initData(); 55 | refreshIntent(getIntent()); 56 | } 57 | 58 | @Override 59 | protected void onDestroy() { 60 | log.e("onDestroy"); 61 | 62 | mMediaControlBorcastFactor.unregister(); 63 | mDownLoadHelper.unInit(); 64 | mDelCacheFileManager.start(FileManager.getSaveRootDir()); 65 | super.onDestroy(); 66 | } 67 | 68 | @Override 69 | protected void onNewIntent(Intent intent) { 70 | refreshIntent(intent); 71 | } 72 | 73 | private void initView(){ 74 | mUIManager = new UIManager(); 75 | } 76 | 77 | 78 | private static final int REFRESH_SPEED= 0x0001; 79 | private static final int EXIT_ACTIVITY = 0x0002; 80 | 81 | private void initData(){ 82 | mScreenWidth = CommonUtil.getScreenWidth(this); 83 | mScreenHeight = CommonUtil.getScreenHeight(this); 84 | 85 | 86 | mMediaControlBorcastFactor = new MediaControlBrocastFactory(this); 87 | mMediaControlBorcastFactor.register(this); 88 | 89 | mDownLoadHelper = new DownLoadHelper(); 90 | mDownLoadHelper.init(); 91 | 92 | mDelCacheFileManager = new DelCacheFileManager(); 93 | 94 | mHandler = new Handler(){ 95 | 96 | @Override 97 | public void handleMessage(Message msg) { 98 | switch(msg.what){ 99 | case EXIT_ACTIVITY: 100 | finish(); 101 | break; 102 | } 103 | } 104 | 105 | }; 106 | 107 | } 108 | 109 | 110 | private void refreshIntent(Intent intent){ 111 | removeExitMessage(); 112 | if (intent != null){ 113 | mMediaInfo = DlnaMediaModelFactory.createFromIntent(intent); 114 | } 115 | 116 | 117 | String requesUrl = mMediaInfo.getUrl(); 118 | String saveUri = FileManager.getSaveFullPath(requesUrl); 119 | if (null == saveUri || saveUri.length() < 1) { 120 | return ; 121 | } 122 | 123 | mUIManager.showProgress(true); 124 | mDownLoadHelper.syncDownLoadFile(mMediaInfo.getUrl(), FileManager.getSaveFullPath(requesUrl), this); 125 | } 126 | 127 | 128 | private void removeExitMessage(){ 129 | mHandler.removeMessages(EXIT_ACTIVITY); 130 | } 131 | 132 | private static final int EXIT_DELAY_TIME = 2000; 133 | private void delayToExit(){ 134 | removeExitMessage(); 135 | mHandler.sendEmptyMessageDelayed(EXIT_ACTIVITY, EXIT_DELAY_TIME); 136 | } 137 | 138 | 139 | 140 | class UIManager{ 141 | public ImageView mImageView; 142 | public View mLoadView; 143 | 144 | public Bitmap recycleBitmap; 145 | public boolean mIsScalBitmap = false; 146 | 147 | public UIManager(){ 148 | initView(); 149 | } 150 | 151 | 152 | private void initView(){ 153 | mImageView = (ImageView) findViewById(R.id.imageview); 154 | mLoadView = findViewById(R.id.show_load_progress); 155 | } 156 | 157 | 158 | public void setBitmap(Bitmap bitmap){ 159 | if (recycleBitmap != null && !recycleBitmap.isRecycled()) { 160 | mImageView.setImageBitmap(null); 161 | recycleBitmap.recycle(); 162 | recycleBitmap = null; 163 | } 164 | 165 | if (mIsScalBitmap) { 166 | mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER); 167 | } else { 168 | mImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 169 | } 170 | 171 | recycleBitmap = bitmap; 172 | mImageView.setImageBitmap(recycleBitmap); 173 | } 174 | 175 | public boolean isLoadViewShow(){ 176 | if (mLoadView.getVisibility() == View.VISIBLE){ 177 | return true; 178 | } 179 | 180 | return false; 181 | } 182 | 183 | public void showProgress(boolean bShow) 184 | { 185 | 186 | if (bShow){ 187 | mLoadView.setVisibility(View.VISIBLE); 188 | } else{ 189 | mLoadView.setVisibility(View.GONE); 190 | } 191 | 192 | } 193 | 194 | public void showLoadFailTip(){ 195 | showToask(R.string.load_image_fail); 196 | } 197 | 198 | public void showParseFailTip(){ 199 | showToask(R.string.parse_image_fail); 200 | } 201 | 202 | private void showToask(int tip) { 203 | Toast.makeText(ImageActivity.this, tip, Toast.LENGTH_SHORT).show(); 204 | } 205 | } 206 | 207 | 208 | 209 | 210 | 211 | @Override 212 | public void downLoadResult(boolean isSuccess, String savePath) { 213 | 214 | onTransDelLoadResult(isSuccess, savePath); 215 | } 216 | 217 | 218 | private void onTransDelLoadResult(final boolean isSuccess,final String savePath){ 219 | 220 | runOnUiThread(new Runnable() { 221 | 222 | @Override 223 | public void run() { 224 | mUIManager.showProgress(false); 225 | 226 | if (!isSuccess){ 227 | mUIManager.showLoadFailTip(); 228 | return ; 229 | } 230 | 231 | Bitmap bitmap = decodeOptionsFile(savePath); 232 | if (bitmap == null){ 233 | mUIManager.showParseFailTip(); 234 | return ; 235 | } 236 | 237 | mUIManager.setBitmap(bitmap); 238 | } 239 | }); 240 | 241 | 242 | } 243 | 244 | 245 | 246 | public Bitmap decodeOptionsFile(String filePath) { 247 | try { 248 | File file = new File(filePath); 249 | BitmapFactory.Options o = new BitmapFactory.Options(); 250 | o.inJustDecodeBounds = true; 251 | BitmapFactory.decodeStream(new FileInputStream(file),null,o); 252 | int width_tmp=o.outWidth, height_tmp=o.outHeight; 253 | int scale = 1; 254 | if (width_tmp <= mScreenWidth && height_tmp <= mScreenHeight) 255 | { 256 | scale = 1; 257 | mUIManager.mIsScalBitmap = false; 258 | }else{ 259 | double widthFit = width_tmp * 1.0 / mScreenWidth; 260 | double heightFit = height_tmp * 1.0 / mScreenHeight; 261 | double fit = widthFit > heightFit ? widthFit : heightFit; 262 | scale = (int) (fit + 0.5); 263 | mUIManager.mIsScalBitmap = true; 264 | } 265 | Bitmap bitmap = null; 266 | if(scale == 1) 267 | { 268 | bitmap = BitmapFactory.decodeStream(new FileInputStream(file)); 269 | if (bitmap != null){ 270 | log.e("scale = 1 bitmap.size = " + bitmap.getRowBytes() * bitmap.getHeight()); 271 | } 272 | }else{ 273 | BitmapFactory.Options o2 = new BitmapFactory.Options(); 274 | o2.inSampleSize = scale; 275 | bitmap = BitmapFactory.decodeStream(new FileInputStream(file), null, o2); 276 | if (bitmap != null){ 277 | log.e("scale = " + o2.inSampleSize + " bitmap.size = " + bitmap.getRowBytes() * bitmap.getHeight()); 278 | } 279 | } 280 | 281 | return bitmap; 282 | 283 | } catch (FileNotFoundException e) { 284 | log.e("fileNotFoundException, e: " + e.toString()); 285 | 286 | } 287 | return null; 288 | } 289 | 290 | 291 | class DelCacheFileManager implements Runnable 292 | { 293 | private Thread mThread; 294 | private String mFilePath; 295 | 296 | public DelCacheFileManager() 297 | { 298 | 299 | } 300 | 301 | @Override 302 | public void run() { 303 | 304 | long time = System.currentTimeMillis(); 305 | log.e("DelCacheFileManager run..."); 306 | try { 307 | FileHelper.deleteDirectory(mFilePath); 308 | } catch (Exception e) { 309 | e.printStackTrace(); 310 | } 311 | long interval = System.currentTimeMillis() - time; 312 | log.e("DelCacheFileManager del over, cost time = " + interval); 313 | } 314 | 315 | public boolean start(String directory) 316 | { 317 | if (mThread != null) 318 | { 319 | if (mThread.isAlive()) 320 | { 321 | return false; 322 | } 323 | } 324 | mFilePath = directory; 325 | mThread = new Thread(this); 326 | mThread.start(); 327 | 328 | return true; 329 | } 330 | 331 | } 332 | 333 | 334 | 335 | 336 | 337 | @Override 338 | public void onPlayCommand() { 339 | // TODO Auto-generated method stub 340 | 341 | } 342 | 343 | @Override 344 | public void onPauseCommand() { 345 | // TODO Auto-generated method stub 346 | 347 | } 348 | 349 | @Override 350 | public void onStopCommand() { 351 | log.e("onStopCommand"); 352 | delayToExit(); 353 | } 354 | 355 | @Override 356 | public void onSeekCommand(int time) { 357 | // TODO Auto-generated method stub 358 | 359 | } 360 | 361 | } 362 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/jni/PlatinumJniProxy.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.jni; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | 5 | public class PlatinumJniProxy { 6 | 7 | static { 8 | System.loadLibrary("git-platinum"); 9 | } 10 | 11 | public static native int startMediaRender(byte[] friendname ,byte[] uuid); 12 | public static native int stopMediaRender(); 13 | public static native boolean responseGenaEvent(int cmd, byte[] value ,byte[] data); 14 | public static native boolean enableLogPrint(boolean flag); 15 | 16 | 17 | public static int startMediaRender(String friendname ,String uuid){ 18 | if (friendname == null)friendname = ""; 19 | if (uuid == null)uuid = ""; 20 | int ret = -1; 21 | try { 22 | ret = startMediaRender(friendname.getBytes("utf-8"), uuid.getBytes("utf-8")); 23 | } catch (UnsupportedEncodingException e) { 24 | e.printStackTrace(); 25 | } 26 | return ret; 27 | } 28 | 29 | public static boolean responseGenaEvent(int cmd, String value, String data){ 30 | if (value == null)value = ""; 31 | if (data == null)data = ""; 32 | boolean ret = false; 33 | try { 34 | ret = responseGenaEvent(cmd, value.getBytes("utf-8"), data.getBytes("utf-8")); 35 | } catch (UnsupportedEncodingException e) { 36 | e.printStackTrace(); 37 | } 38 | return ret; 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/jni/PlatinumReflection.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.jni; 2 | 3 | import com.geniusgithub.mediarender.util.CommonLog; 4 | import com.geniusgithub.mediarender.util.LogFactory; 5 | 6 | 7 | 8 | public class PlatinumReflection { 9 | 10 | private static final CommonLog log = LogFactory.createLog(); 11 | 12 | private static final int MEDIA_RENDER_CTL_MSG_BASE = 0x100; 13 | /*----------------------------------------------------------------*/ 14 | public static final int MEDIA_RENDER_CTL_MSG_SET_AV_URL = (MEDIA_RENDER_CTL_MSG_BASE+0); 15 | public static final int MEDIA_RENDER_CTL_MSG_STOP = (MEDIA_RENDER_CTL_MSG_BASE+1); 16 | public static final int MEDIA_RENDER_CTL_MSG_PLAY = (MEDIA_RENDER_CTL_MSG_BASE+2); 17 | public static final int MEDIA_RENDER_CTL_MSG_PAUSE = (MEDIA_RENDER_CTL_MSG_BASE+3); 18 | public static final int MEDIA_RENDER_CTL_MSG_SEEK = (MEDIA_RENDER_CTL_MSG_BASE+4); 19 | public static final int MEDIA_RENDER_CTL_MSG_SETVOLUME = (MEDIA_RENDER_CTL_MSG_BASE+5); 20 | public static final int MEDIA_RENDER_CTL_MSG_SETMUTE = (MEDIA_RENDER_CTL_MSG_BASE+6); 21 | public static final int MEDIA_RENDER_CTL_MSG_SETPLAYMODE = (MEDIA_RENDER_CTL_MSG_BASE+7); 22 | public static final int MEDIA_RENDER_CTL_MSG_PRE = (MEDIA_RENDER_CTL_MSG_BASE+8); 23 | public static final int MEDIA_RENDER_CTL_MSG_NEXT = (MEDIA_RENDER_CTL_MSG_BASE+9); 24 | /*----------------------------------------------------------------*/ 25 | 26 | 27 | 28 | /*----------------------------------------------------------------*/ 29 | /* 30 | * 31 | * 32 | * */ 33 | public static final int MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_DURATION = (MEDIA_RENDER_CTL_MSG_BASE+0); 34 | public static final int MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_POSITION = (MEDIA_RENDER_CTL_MSG_BASE+1); 35 | public static final int MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_PLAYINGSTATE = (MEDIA_RENDER_CTL_MSG_BASE+2); 36 | /*----------------------------------------------------------------*/ 37 | public static final String RENDERER_TOCONTRPOINT_CMD_INTENT_NAME="com.geniusgithub.platinum.tocontrolpointer.cmd.intent"; 38 | public static final String GET_RENDERER_TOCONTRPOINT_CMD="get_dlna_renderer_tocontrolpointer.cmd"; 39 | public static final String GET_PARAM_MEDIA_DURATION="get_param_media_duration"; 40 | public static final String GET_PARAM_MEDIA_POSITION="get_param_media_position"; 41 | public static final String GET_PARAM_MEDIA_PLAYINGSTATE="get_param_media_playingstate"; 42 | /*----------------------------------------------------------------*/ 43 | 44 | 45 | public static final String MEDIA_PLAYINGSTATE_STOP="STOPPED"; 46 | public static final String MEDIA_PLAYINGSTATE_PAUSE="PAUSED_PLAYBACK"; 47 | public static final String MEDIA_PLAYINGSTATE_PLAYING="PLAYING"; 48 | public static final String MEDIA_PLAYINGSTATE_TRANSTION="TRANSITIONING"; 49 | public static final String MEDIA_PLAYINGSTATE_NOMEDIA="NO_MEDIA_PRESENT"; 50 | 51 | /*----------------------------------------------------------------*/ 52 | public static final String MEDIA_SEEK_TIME_TYPE_REL_TIME="REL_TIME"; 53 | public static final String MEDIA_SEEK_TIME_TYPE_TRACK_NR="TRACK_NR"; 54 | 55 | 56 | public static interface ActionReflectionListener{ 57 | public void onActionInvoke(int cmd,String value,String data); 58 | } 59 | 60 | private static ActionReflectionListener mListener; 61 | 62 | 63 | public static void onActionReflection(int cmd,String value,String data){ 64 | if (mListener != null){ 65 | mListener.onActionInvoke(cmd, value, data); 66 | } 67 | } 68 | 69 | public static void setActionInvokeListener(ActionReflectionListener listener){ 70 | mListener = listener; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/ImageUtils.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Bitmap.Config; 6 | import android.graphics.Camera; 7 | import android.graphics.Canvas; 8 | import android.graphics.LinearGradient; 9 | import android.graphics.Matrix; 10 | import android.graphics.Paint; 11 | import android.graphics.PorterDuff.Mode; 12 | import android.graphics.PorterDuffXfermode; 13 | import android.graphics.Shader.TileMode; 14 | import android.graphics.drawable.BitmapDrawable; 15 | import android.graphics.drawable.Drawable; 16 | 17 | import com.geniusgithub.mediarender.util.CommonLog; 18 | import com.geniusgithub.mediarender.util.LogFactory; 19 | 20 | public class ImageUtils { 21 | private static final CommonLog log = LogFactory.createLog(); 22 | 23 | public static Bitmap createRotateReflectedMap(Bitmap originalBitmap) { 24 | float width = ((float)200) / (originalBitmap.getWidth()); 25 | float height = ((float)200) / (originalBitmap.getHeight()); 26 | Matrix matrix = new Matrix(); 27 | matrix.postScale(width, height); 28 | originalBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), 29 | matrix, true); 30 | Bitmap bitmap = createReflectedImage(originalBitmap); 31 | bitmap = createRotateImage(bitmap); 32 | return bitmap; 33 | } 34 | 35 | public static Bitmap createRotateReflectedMap(Context ctx, Drawable resId) { 36 | 37 | Bitmap bitmap = ((BitmapDrawable)resId).getBitmap(); 38 | if (bitmap != null) { 39 | log.e("bitmap is not null"); 40 | return createRotateReflectedMap(bitmap); 41 | } 42 | return null; 43 | } 44 | 45 | public static Bitmap createRotateImage(Bitmap originalBitmap) { 46 | Camera camera = new Camera(); 47 | camera.save(); 48 | camera.rotateY(10f); 49 | Matrix mMatrix = new Matrix(); 50 | camera.getMatrix(mMatrix); 51 | camera.restore(); 52 | 53 | Bitmap bm = Bitmap.createBitmap(originalBitmap, 0, 0, 54 | originalBitmap.getWidth(), originalBitmap.getHeight(), mMatrix, 55 | true); 56 | //Bitmap bm = Bitmap.createBitmap(originalBitmap, 0, 0,270,270,mMatrix,true); 57 | return bm; 58 | } 59 | 60 | public static Bitmap createReflectedImage(Bitmap originalBitmap) { 61 | final int reflectionGap = 4; 62 | 63 | int width = originalBitmap.getWidth(); 64 | int height = originalBitmap.getHeight(); 65 | 66 | 67 | Matrix matrix = new Matrix(); 68 | 69 | matrix.preScale(1, -1); 70 | Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap, 0, 71 | height / 2, width, height / 2, matrix, false); 72 | Bitmap withReflectionBitmap = Bitmap.createBitmap(width, (height 73 | + height / 2 + reflectionGap), Config.ARGB_8888); 74 | 75 | Canvas canvas = new Canvas(withReflectionBitmap); 76 | canvas.drawBitmap(originalBitmap, 0, 0, null); 77 | 78 | Paint defaultPaint = new Paint(); 79 | canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint); 80 | 81 | canvas.drawBitmap(reflectionBitmap, 0, height + reflectionGap, null); 82 | 83 | Paint paint = new Paint(); 84 | LinearGradient shader = new LinearGradient(0, 85 | originalBitmap.getHeight(), 0, 86 | withReflectionBitmap.getHeight(), 0x70ffffff, 0x00ffffff, 87 | TileMode.MIRROR); 88 | paint.setShader(shader); 89 | paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); 90 | 91 | canvas.drawRect(0, height, width, withReflectionBitmap.getHeight(), 92 | paint); 93 | 94 | return withReflectionBitmap; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/LoaderHelper.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.os.Handler; 5 | import android.os.Message; 6 | 7 | import com.geniusgithub.mediarender.util.CommonLog; 8 | import com.geniusgithub.mediarender.util.LogFactory; 9 | 10 | public class LoaderHelper { 11 | 12 | private static final CommonLog log = LogFactory.createLog(); 13 | 14 | 15 | public LoaderHelper(){ 16 | 17 | } 18 | 19 | public static boolean syncDownLoadDrawable(final String requestUrl,final Handler handler,final int msgID){ 20 | ITaskCompleteCallback callback = new ITaskCompleteCallback(){ 21 | 22 | @Override 23 | public void onTaskComplete(Drawable drawable) { 24 | if (handler != null){ 25 | Message msg = handler.obtainMessage(msgID); 26 | if (drawable != null){ 27 | msg.obj = drawable; 28 | }else{ 29 | msg.obj = null; 30 | } 31 | msg.sendToTarget(); 32 | } 33 | } 34 | 35 | }; 36 | syncDownLoadDrawable(requestUrl, callback); 37 | return true; 38 | } 39 | 40 | public static boolean syncDownLoadDrawable(String requestUrl, ITaskCompleteCallback callback){ 41 | InnerThread thread = new InnerThread(requestUrl, callback); 42 | thread.start(); 43 | return true; 44 | } 45 | 46 | public static interface ITaskCompleteCallback{ 47 | public void onTaskComplete(Drawable drawable); 48 | } 49 | 50 | public static class InnerThread extends Thread{ 51 | 52 | private ITaskCompleteCallback mCallback; 53 | private String mUri; 54 | public InnerThread(String uri, ITaskCompleteCallback callback){ 55 | mCallback = callback; 56 | mUri = uri; 57 | } 58 | 59 | @Override 60 | public void run() { 61 | 62 | Drawable drawable = NetUtils.requestDrawableByUri(mUri); 63 | if (mCallback != null){ 64 | mCallback.onTaskComplete(drawable); 65 | } 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/NetUtils.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music; 2 | 3 | import java.io.InputStream; 4 | import java.net.HttpURLConnection; 5 | import java.net.URL; 6 | 7 | import android.graphics.drawable.Drawable; 8 | 9 | import com.geniusgithub.mediarender.util.CommonLog; 10 | import com.geniusgithub.mediarender.util.LogFactory; 11 | 12 | public class NetUtils { 13 | 14 | private static final CommonLog log = LogFactory.createLog(); 15 | 16 | public static Drawable requestDrawableByUri(String uri){ 17 | if (uri == null || uri.length() == 0){ 18 | return null; 19 | } 20 | 21 | Drawable drawable = null; 22 | int index = 0; 23 | while(true){ 24 | if (index >= 3){ 25 | break; 26 | } 27 | drawable = getDrawableFromUri(uri); 28 | if (drawable != null){ 29 | break; 30 | } 31 | index++; 32 | } 33 | 34 | return drawable; 35 | } 36 | 37 | public static Drawable getDrawableFromUri(String uri){ 38 | if (uri == null || uri.length() < 1){ 39 | return null; 40 | } 41 | Drawable drawable = null; 42 | try { 43 | URL url = new URL(uri); 44 | HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 45 | conn.setRequestMethod("GET"); 46 | InputStream input = conn.getInputStream(); 47 | if (conn.getResponseCode() != 200){ 48 | log.e("getDrawableFromUri.getResponseCode() = " + conn.getResponseCode() + "\n" + 49 | "uri :" + uri + "is invalid!!!"); 50 | input.close(); 51 | return null; 52 | } 53 | drawable = Drawable.createFromStream(input, "src"); 54 | input.close(); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | // log.e("getDrawableFromUri catch exception!!!e = " + e.getMessage()); 58 | } 59 | 60 | return drawable; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/VisualizerView.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music; 2 | 3 | 4 | import com.geniusgithub.mediarender.R; 5 | 6 | import android.content.Context; 7 | import android.graphics.Canvas; 8 | import android.graphics.Paint; 9 | import android.graphics.Rect; 10 | import android.util.AttributeSet; 11 | import android.view.View; 12 | 13 | 14 | 15 | public class VisualizerView extends View { 16 | private byte[] mBytes; 17 | private float[] mPoints; 18 | private Rect mRect = new Rect(); 19 | 20 | private Paint mForePaint = new Paint(); 21 | private int mSpectrumNum = 64; 22 | 23 | public VisualizerView(Context context) { 24 | super(context); 25 | init(); 26 | } 27 | 28 | public VisualizerView(Context context, AttributeSet attrs) { 29 | super(context, attrs); 30 | init(); 31 | } 32 | 33 | private void init() { 34 | mBytes = null; 35 | 36 | mForePaint.setStrokeWidth(3f); 37 | mForePaint.setAntiAlias(true); 38 | mForePaint.setColor(getResources().getColor(R.color.visualize_fx)); 39 | } 40 | 41 | public void updateVisualizer(byte[] fft) { 42 | byte[] model = new byte[fft.length / 2 + 1]; 43 | 44 | model[0] = (byte) Math.abs(fft[0]); 45 | for (int i = 2, j = 1; j < mSpectrumNum;) { 46 | model[j] = (byte) Math.hypot(fft[i], fft[i + 1]); 47 | i += 2; 48 | j++; 49 | } 50 | mBytes = model; 51 | invalidate(); 52 | } 53 | 54 | @Override 55 | protected void onDraw(Canvas canvas) { 56 | super.onDraw(canvas); 57 | 58 | if (mBytes == null) { 59 | return; 60 | } 61 | 62 | if (mPoints == null || mPoints.length < mBytes.length * 4) { 63 | mPoints = new float[mBytes.length * 4]; 64 | } 65 | 66 | mRect.set(0, 0, getWidth(), getHeight()); 67 | 68 | final int baseX = mRect.width() / mSpectrumNum; 69 | final int height = mRect.height(); 70 | 71 | for (int i = 0; i < mSpectrumNum; i++) { 72 | if (mBytes[i] < 0) { 73 | mBytes[i] = 127; 74 | } 75 | 76 | final int xi = baseX * i + baseX / 2; 77 | 78 | mPoints[i * 4] = xi; 79 | mPoints[i * 4 + 1] = height; 80 | 81 | mPoints[i * 4 + 2] = xi; 82 | mPoints[i * 4 + 3] = height - mBytes[i] * 2; 83 | } 84 | 85 | canvas.drawLines(mPoints, mForePaint); 86 | } 87 | } -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/lrc/ErrorThrowable.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music.lrc; 2 | 3 | public class ErrorThrowable extends Throwable { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | private String message; 8 | 9 | public void setMessage(String message) { 10 | this.message = message; 11 | } 12 | 13 | @Override 14 | public String getMessage() { 15 | return message; 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/lrc/HttpManager.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music.lrc; 2 | 3 | import org.apache.http.params.HttpParams; 4 | import org.apache.http.params.BasicHttpParams; 5 | import org.apache.http.params.HttpProtocolParams; 6 | import org.apache.http.params.HttpConnectionParams; 7 | import org.apache.http.HttpEntity; 8 | import org.apache.http.HttpVersion; 9 | import org.apache.http.HttpResponse; 10 | import org.apache.http.HttpHost; 11 | import org.apache.http.client.ClientProtocolException; 12 | import org.apache.http.client.HttpClient; 13 | import org.apache.http.client.methods.HttpHead; 14 | import org.apache.http.client.methods.HttpGet; 15 | import org.apache.http.client.methods.HttpUriRequest; 16 | import org.apache.http.client.params.HttpClientParams; 17 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 18 | import org.apache.http.impl.client.DefaultHttpClient; 19 | import org.apache.http.conn.params.ConnManagerParams; 20 | import org.apache.http.conn.params.ConnRouteParams; 21 | import org.apache.http.conn.scheme.SchemeRegistry; 22 | import org.apache.http.conn.scheme.Scheme; 23 | import org.apache.http.conn.scheme.PlainSocketFactory; 24 | import org.apache.http.conn.ssl.SSLSocketFactory; 25 | import org.apache.http.conn.ClientConnectionManager; 26 | import android.text.TextUtils; 27 | import java.io.BufferedReader; 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | import java.io.InputStreamReader; 31 | import java.net.SocketException; 32 | import java.net.UnknownHostException; 33 | 34 | 35 | public class HttpManager { 36 | private static final DefaultHttpClient sClient; 37 | static { 38 | final HttpParams params = new BasicHttpParams(); 39 | HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 40 | HttpProtocolParams.setContentCharset(params, "UTF-8"); 41 | HttpConnectionParams.setStaleCheckingEnabled(params, false); 42 | HttpConnectionParams.setConnectionTimeout(params, 15 * 1000); 43 | HttpConnectionParams.setSoTimeout(params,15 * 1000); 44 | HttpConnectionParams.setSocketBufferSize(params, 50 * 1024); 45 | HttpClientParams.setRedirecting(params, false); 46 | SchemeRegistry schemeRegistry = new SchemeRegistry(); 47 | schemeRegistry.register(new Scheme("http", PlainSocketFactory 48 | .getSocketFactory(), 80)); 49 | schemeRegistry.register(new Scheme("https", SSLSocketFactory 50 | .getSocketFactory(), 443)); 51 | ClientConnectionManager manager = new ThreadSafeClientConnManager( 52 | params, schemeRegistry); 53 | sClient = new DefaultHttpClient(manager, params); 54 | } 55 | 56 | private HttpManager() { 57 | } 58 | 59 | public static HttpResponse execute(HttpHead head) throws IOException { 60 | return sClient.execute(head); 61 | } 62 | 63 | public static HttpResponse execute(HttpHost host, HttpGet get) 64 | throws IOException { 65 | return sClient.execute(host, get); 66 | } 67 | 68 | public static HttpResponse execute(HttpGet get) throws IOException { 69 | return sClient.execute(get); 70 | } 71 | 72 | public static String doGetReturnString(String url) throws ErrorThrowable { 73 | 74 | String data = null; 75 | 76 | // initialize HTTP GET request objects 77 | HttpGet httpGet = new HttpGet(url); 78 | HttpResponse httpResponse; 79 | 80 | try { 81 | // execute request 82 | try { 83 | httpResponse = sClient.execute(httpGet); 84 | } catch (UnknownHostException e) { 85 | ErrorThrowable wsError = new ErrorThrowable(); 86 | wsError.setMessage(e.getLocalizedMessage()); 87 | throw wsError; 88 | } catch (SocketException e) { 89 | ErrorThrowable wsError = new ErrorThrowable(); 90 | wsError.setMessage(e.getLocalizedMessage()); 91 | throw wsError; 92 | } 93 | 94 | // request data 95 | HttpEntity httpEntity = httpResponse.getEntity(); 96 | 97 | if (httpEntity != null) { 98 | InputStream inputStream = httpEntity.getContent(); 99 | data = convertStreamToString(inputStream); 100 | } 101 | 102 | } catch (ClientProtocolException e) { 103 | e.printStackTrace(); 104 | } catch (IOException e) { 105 | e.printStackTrace(); 106 | } 107 | 108 | return data; 109 | } 110 | 111 | public static InputStream doGetReturnInputStream(String url, Long begin) 112 | throws ErrorThrowable { 113 | if (url == null || TextUtils.isEmpty(url)) { 114 | return null; 115 | } 116 | InputStream data = null; 117 | HttpGet httpGet = new HttpGet(url); 118 | if (begin != null) { 119 | httpGet.setHeader("Range", "bytes=" + begin.intValue() + "-"); 120 | } 121 | HttpResponse httpResponse; 122 | try { 123 | httpResponse = sClient.execute(httpGet); 124 | } catch (UnknownHostException e) { 125 | ErrorThrowable wsError = new ErrorThrowable(); 126 | wsError.setMessage(e.getLocalizedMessage()); 127 | throw wsError; 128 | } catch (Exception e) { 129 | ErrorThrowable wsError = new ErrorThrowable(); 130 | wsError.setMessage(e.getLocalizedMessage()); 131 | throw wsError; 132 | } 133 | if (httpResponse != null) { 134 | HttpEntity httpEntity = httpResponse.getEntity(); 135 | if (httpEntity != null) { 136 | try { 137 | data = httpEntity.getContent(); 138 | } catch (Exception e) { 139 | ErrorThrowable wsError = new ErrorThrowable(); 140 | wsError.setMessage(e.getLocalizedMessage()); 141 | throw wsError; 142 | } 143 | } 144 | } 145 | return data; 146 | } 147 | 148 | public static InputStream executeGet(String url, Long begin, 149 | StringBuffer fileSize) throws Exception { 150 | HttpUriRequest hr = null; 151 | hr = new HttpGet(url); 152 | hr.setHeader("X-Target-Encoding", "UTF-8"); 153 | if (begin != null) { 154 | hr.setHeader("Range", "bytes=" + begin.intValue() + "-"); 155 | } 156 | HttpClient mHttpClient = new DefaultHttpClient(); 157 | try { 158 | HttpParams hcp = mHttpClient.getParams(); 159 | if (null != hcp) { 160 | final int TIMEOUT_MS = 10 * 1000; 161 | ConnManagerParams.setTimeout(hcp, TIMEOUT_MS); 162 | HttpConnectionParams.setSoTimeout(hcp, TIMEOUT_MS); 163 | HttpConnectionParams.setConnectionTimeout(hcp, TIMEOUT_MS); 164 | ConnRouteParams.setDefaultProxy(hcp, null); 165 | } 166 | HttpEntity resEntity = null; 167 | InputStream is = null; 168 | for (int i = 0; i < 3; i++) { 169 | try { 170 | HttpResponse rsp = mHttpClient.execute(hr); 171 | resEntity = rsp.getEntity(); 172 | 173 | is = resEntity.getContent(); 174 | if (fileSize != null) { 175 | fileSize = fileSize 176 | .append(resEntity.getContentLength()); 177 | 178 | } 179 | if (is != null) { 180 | return is; 181 | } 182 | } catch (Exception e) { 183 | e.printStackTrace(); 184 | if (i + 1 == 3) { 185 | return null; 186 | } 187 | } 188 | 189 | } 190 | } catch (Exception ex) { 191 | ex.printStackTrace(); 192 | } 193 | 194 | return null; 195 | } 196 | 197 | private static String convertStreamToString(InputStream is) { 198 | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 199 | StringBuilder sb = new StringBuilder(); 200 | String line = null; 201 | try { 202 | while ((line = reader.readLine()) != null) { 203 | sb.append(line + "\n"); 204 | } 205 | } catch (IOException e) { 206 | e.printStackTrace(); 207 | } finally { 208 | try { 209 | is.close(); 210 | } catch (IOException e) { 211 | e.printStackTrace(); 212 | } 213 | } 214 | return sb.toString(); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/lrc/LrcDownLoadHelper.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music.lrc; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | import com.geniusgithub.mediarender.util.CommonLog; 7 | import com.geniusgithub.mediarender.util.LogFactory; 8 | 9 | 10 | public class LrcDownLoadHelper { 11 | 12 | private static final CommonLog log = LogFactory.createLog(); 13 | 14 | private final static int THREAD_COUNT = 3; 15 | private ExecutorService mExecutorService; 16 | 17 | public LrcDownLoadHelper(){ 18 | 19 | } 20 | 21 | public void init(){ 22 | if (mExecutorService == null){ 23 | mExecutorService = Executors.newFixedThreadPool(THREAD_COUNT); 24 | } 25 | } 26 | 27 | 28 | public void unInit(){ 29 | if (mExecutorService != null) 30 | { 31 | mExecutorService.shutdown(); 32 | mExecutorService.shutdownNow(); 33 | mExecutorService = null; 34 | } 35 | } 36 | 37 | 38 | 39 | public static interface ILRCDownLoadCallback{ 40 | public void lrcDownLoadComplete(final boolean isSuccess,String song, String artist); 41 | } 42 | 43 | 44 | public boolean syncDownLoadLRC(String song, String artist, ILRCDownLoadCallback callback){ 45 | if (mExecutorService == null){ 46 | return false; 47 | } 48 | 49 | InnerRunnable runnable = new InnerRunnable(song, artist, callback); 50 | mExecutorService.execute(runnable); 51 | 52 | return true; 53 | 54 | } 55 | 56 | 57 | class InnerRunnable implements Runnable{ 58 | 59 | private String mSong = ""; 60 | private String mArtist = ""; 61 | private ILRCDownLoadCallback mCallback; 62 | 63 | public InnerRunnable(String song, String artist, ILRCDownLoadCallback callback){ 64 | mSong = song; 65 | mArtist = artist; 66 | mCallback = callback; 67 | } 68 | 69 | @Override 70 | public void run() { 71 | boolean ret = LyricHelper.searchLryics(mSong, mArtist); 72 | log.e(" LyricHelper.searchLryics mSong = " + mSong + ", mArtist = " + mArtist + ", ret = " + ret); 73 | 74 | if (mCallback != null){ 75 | mCallback.lrcDownLoadComplete(ret, mSong, mArtist); 76 | } 77 | 78 | } 79 | 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/lrc/LyricHelper.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music.lrc; 2 | 3 | import java.io.InputStream; 4 | import java.io.UnsupportedEncodingException; 5 | import java.net.URLEncoder; 6 | 7 | import org.apache.http.HttpResponse; 8 | import org.apache.http.HttpStatus; 9 | import org.apache.http.client.methods.HttpGet; 10 | import org.xmlpull.v1.XmlPullParser; 11 | import org.xmlpull.v1.XmlPullParserFactory; 12 | 13 | import android.provider.MediaStore; 14 | import android.util.Log; 15 | 16 | 17 | public class LyricHelper { 18 | private static final String TAG = "LyricHelper"; 19 | private static final String DEFAULT_ENCODING = "gb18030"; 20 | private static final String QQ_SEARCH_BASE_URL = "http://qqmusic.qq.com/fcgi-bin/qm_getLyricId.fcg"; 21 | private static final String QQ_LYRIC_BASE_URL = "http://music.qq.com/miniportal/static/lyric/"; 22 | private static final String BAIDU_SEARCH_BASE_URL = "http://box.zhangmen.baidu.com/x?op=12&count=1"; 23 | private static final String BAIDU_LYRIC_BASE_URL = "http://box.zhangmen.baidu.com/bdlrc/"; 24 | 25 | public static boolean searchLryics(String song, String artist) { 26 | boolean result = false; 27 | String lyricPath = MusicUtils.getLyricFile(song, artist); 28 | if (lyricPath != null) { 29 | String songId = searchLyricFromQQ(song, artist); 30 | if (songId != null) { 31 | String url = buildQQLyricUrl(songId); 32 | Log.d(TAG, "search url:" + url); 33 | try { 34 | HttpResponse response = HttpManager 35 | .execute(new HttpGet(url)); 36 | if (response != null 37 | && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 38 | InputStream is = response.getEntity().getContent(); 39 | XmlPullParserFactory factory = XmlPullParserFactory 40 | .newInstance(); 41 | factory.setNamespaceAware(true); 42 | XmlPullParser xpp = factory.newPullParser(); 43 | xpp.setInput(is, DEFAULT_ENCODING); 44 | int eventType = xpp.getEventType(); 45 | String tag = ""; 46 | while (eventType != XmlPullParser.END_DOCUMENT) { 47 | if (eventType == XmlPullParser.START_TAG) { 48 | tag = xpp.getName(); 49 | if (tag.equals("lyric")) { 50 | xpp.next(); 51 | String lycis = xpp.getText(); 52 | result = MusicUtils.saveFile(lyricPath, 53 | lycis); 54 | break; 55 | } 56 | } 57 | eventType = xpp.next(); 58 | } 59 | } 60 | } catch (Exception e1) { 61 | Log.e(TAG, "Exception", e1); 62 | } 63 | } 64 | if (!result) { // Get lyric failed from QQ 65 | String lyricId = searchLyricFromBaidu(song, artist); 66 | if (lyricId != null) { 67 | String url = buildBaiduLyricUrl(lyricId); 68 | Log.d(TAG, "search url:" + url); 69 | try { 70 | HttpResponse response = HttpManager 71 | .execute(new HttpGet(url)); 72 | if (response != null 73 | && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 74 | InputStream is = response.getEntity().getContent(); 75 | if (is != null) { 76 | result = MusicUtils.saveFile(lyricPath, is); 77 | } 78 | } 79 | } catch (Exception e1) { 80 | Log.e(TAG, "Exception", e1); 81 | } 82 | } 83 | } 84 | } 85 | return result; 86 | } 87 | 88 | private static String searchLyricFromQQ(String song, String artist) { 89 | String lyricID = null; 90 | String url = buildQQSearchUrl(song, artist); 91 | Log.d(TAG, "search url:" + url); 92 | try { 93 | HttpResponse response = HttpManager.execute(new HttpGet(url)); 94 | if (response != null 95 | && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 96 | InputStream is = response.getEntity().getContent(); 97 | XmlPullParserFactory factory = XmlPullParserFactory 98 | .newInstance(); 99 | factory.setNamespaceAware(true); 100 | XmlPullParser xpp = factory.newPullParser(); 101 | xpp.setInput(is, DEFAULT_ENCODING); 102 | int eventType = xpp.getEventType(); 103 | String tag = ""; 104 | while (eventType != XmlPullParser.END_DOCUMENT) { 105 | if (eventType == XmlPullParser.START_TAG) { 106 | tag = xpp.getName(); 107 | if (tag.equals("songcount")) { 108 | xpp.next(); 109 | int count = Integer.parseInt(xpp.getText()); 110 | Log.i(TAG, "search count:" + count); 111 | if (count == 0) { 112 | break; 113 | } 114 | } else if (tag.equals("songinfo")) { 115 | final int attrSize = xpp.getAttributeCount(); 116 | for (int i = 0; i < attrSize; i++) { 117 | String attrName = xpp.getAttributeName(i); 118 | if (attrName.equalsIgnoreCase("id")) { 119 | lyricID = xpp.getAttributeValue(i); 120 | break; 121 | } 122 | } 123 | } 124 | } 125 | eventType = xpp.next(); 126 | } 127 | } 128 | } catch (Exception e1) { 129 | Log.e(TAG, "Exception", e1); 130 | } 131 | 132 | return lyricID; 133 | } 134 | 135 | private static String buildBaiduSearchUrl(String song, String artist) { 136 | if (artist != null && artist.length() > 0 137 | && !artist.equals(MediaStore.UNKNOWN_STRING)) { 138 | StringBuilder sb = new StringBuilder(); 139 | sb.append(BAIDU_SEARCH_BASE_URL); 140 | sb.append("&title="); 141 | try { 142 | sb.append(URLEncoder.encode(song, "gbk")); 143 | sb.append("$$"); 144 | sb.append(URLEncoder.encode(artist, "gbk")); 145 | } catch (UnsupportedEncodingException e) { 146 | Log.e(TAG, "UnsupportedEncodingException", e); 147 | } 148 | sb.append("$$$$"); 149 | return sb.toString(); 150 | } 151 | return null; 152 | 153 | } 154 | 155 | private static String buildBaiduLyricUrl(String lyricId) { 156 | int id = -1; 157 | if (lyricId != null) { 158 | try { 159 | id = Integer.parseInt(lyricId); 160 | } catch (Exception e) { 161 | } 162 | } 163 | if (id > -1) { 164 | StringBuilder sb = new StringBuilder(); 165 | sb.append(BAIDU_LYRIC_BASE_URL); 166 | int tmp = id / 100; 167 | sb.append(tmp); 168 | sb.append("/"); 169 | sb.append(lyricId); 170 | sb.append(".lrc"); 171 | 172 | return sb.toString(); 173 | } 174 | return null; 175 | } 176 | 177 | private static String searchLyricFromBaidu(String song, String artist) { 178 | String lyricID = null; 179 | String url = buildBaiduSearchUrl(song, artist); 180 | Log.d(TAG, "search url:" + url); 181 | if (url != null) { 182 | try { 183 | HttpResponse response = HttpManager.execute(new HttpGet(url)); 184 | if (response != null 185 | && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 186 | InputStream is = response.getEntity().getContent(); 187 | XmlPullParserFactory factory = XmlPullParserFactory 188 | .newInstance(); 189 | factory.setNamespaceAware(true); 190 | XmlPullParser xpp = factory.newPullParser(); 191 | xpp.setInput(is, DEFAULT_ENCODING); 192 | int eventType = xpp.getEventType(); 193 | String tag = ""; 194 | while (eventType != XmlPullParser.END_DOCUMENT) { 195 | if (eventType == XmlPullParser.START_TAG) { 196 | tag = xpp.getName(); 197 | if (tag.equals("count")) { 198 | xpp.next(); 199 | int count = Integer.parseInt(xpp.getText()); 200 | Log.i(TAG, "search count:" + count); 201 | if (count == 0) { 202 | break; 203 | } 204 | } else if (tag.equals("lrcid")) { 205 | xpp.next(); 206 | lyricID = xpp.getText(); 207 | break; 208 | } 209 | } 210 | eventType = xpp.next(); 211 | } 212 | } 213 | } catch (Exception e1) { 214 | Log.e(TAG, "Exception", e1); 215 | } 216 | } 217 | return lyricID; 218 | } 219 | 220 | private static String buildQQSearchUrl(String song, String artist) { 221 | StringBuilder sb = new StringBuilder(); 222 | sb.append(QQ_SEARCH_BASE_URL); 223 | sb.append("?name="); 224 | try { 225 | sb.append(URLEncoder.encode(song, "gb18030")); 226 | if (artist != null && artist.length() > 0 227 | && !artist.equals(MediaStore.UNKNOWN_STRING)) { 228 | sb.append("&singer="); 229 | sb.append(URLEncoder.encode(artist, "gb18030")); 230 | } 231 | } catch (UnsupportedEncodingException e) { 232 | Log.e(TAG, "UnsupportedEncodingException", e); 233 | } 234 | sb.append("&from=qqplayer"); 235 | return sb.toString(); 236 | } 237 | 238 | private static String buildQQLyricUrl(String songId) { 239 | StringBuilder sb = new StringBuilder(); 240 | sb.append(QQ_LYRIC_BASE_URL); 241 | int length = songId.length(); 242 | String tmp = songId.substring(length - 2); 243 | sb.append(tmp); 244 | sb.append("/"); 245 | sb.append(songId); 246 | sb.append(".xml"); 247 | 248 | return sb.toString(); 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/lrc/LyricObject.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.music.lrc; 2 | 3 | public class LyricObject { 4 | public int begintime; // Begin time 5 | public int endtime; // End time 6 | public int timeline; // Time of single line 7 | public String lrc; // Lyrics of single line 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/music/lrc/MusicUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.geniusgithub.mediarender.music.lrc; 18 | 19 | import java.io.File; 20 | import java.io.FileOutputStream; 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | 24 | import android.os.Environment; 25 | import android.provider.MediaStore; 26 | import android.util.Log; 27 | 28 | import com.geniusgithub.mediarender.util.CommonLog; 29 | import com.geniusgithub.mediarender.util.LogFactory; 30 | 31 | 32 | public class MusicUtils { 33 | 34 | private static final CommonLog log = LogFactory.createLog(); 35 | 36 | private static final String TAG = "MusicUtils"; 37 | public static int downprogress; 38 | 39 | // public static boolean isMusicLocal(String url) { 40 | // boolean result = true; 41 | // if (url != null && url.toLowerCase().startsWith("http://")) { 42 | // return false; 43 | // } 44 | // return result; 45 | // } 46 | // 47 | // static protected Uri getContentURIForPath(String path) { 48 | // return Uri.fromFile(new File(path)); 49 | // } 50 | // 51 | // /* 52 | // * Try to use String.format() as little as possible, because it creates a 53 | // * new Formatter every time you call it, which is very inefficient. Reusing 54 | // * an existing Formatter more than tripled the speed of makeTimeString(). 55 | // * This Formatter/StringBuilder are also used by makeAlbumSongsLabel() 56 | // */ 57 | // private static StringBuilder sFormatBuilder = new StringBuilder(); 58 | // private static Formatter sFormatter = new Formatter(sFormatBuilder, 59 | // Locale.getDefault()); 60 | // private static final Object[] sTimeArgs = new Object[5]; 61 | // 62 | // public static String makeTimeString(Context context, long secs) { 63 | // String durationformat = context 64 | // .getString(secs < 3600 ? R.string.durationformatshort 65 | // : R.string.durationformatlong); 66 | // 67 | // /* 68 | // * Provide multiple arguments so the format can be changed easily by 69 | // * modifying the xml. 70 | // */ 71 | // sFormatBuilder.setLength(0); 72 | // 73 | // final Object[] timeArgs = sTimeArgs; 74 | // timeArgs[0] = secs / 3600; 75 | // timeArgs[1] = secs / 60; 76 | // timeArgs[2] = (secs / 60) % 60; 77 | // timeArgs[3] = secs; 78 | // timeArgs[4] = secs % 60; 79 | // 80 | // return sFormatter.format(durationformat, timeArgs).toString(); 81 | // } 82 | // 83 | // 84 | // public static int[] shuffle(int[] input) { 85 | // if (input == null || input.length == 0) 86 | // throw new IllegalArgumentException( 87 | // "input can not be null or zero length"); 88 | // int[] result = new int[input.length]; 89 | // Random r = new Random(); 90 | // int m = input.length; 91 | // int i = 0; 92 | // while (m > 0 && i < result.length) { 93 | // int pos = (r.nextInt() >>> 1) % m; 94 | // result[i] = input[pos]; 95 | // input[pos] = input[--m]; 96 | // i++; 97 | // } 98 | // return result; 99 | // } 100 | // 101 | // public static int[] shuffle(int[] input, int position) { 102 | // int result[] = shuffle(input); 103 | // // find the position and swap it 104 | // for (int j = 0; j < result.length; j++) { 105 | // if (result[j] == position) { 106 | // int tmp = result[position]; 107 | // result[position] = result[j]; 108 | // result[j] = tmp; 109 | // } 110 | // } 111 | // 112 | // return result; 113 | // } 114 | // 115 | // public static int find(int[] source, int s) { 116 | // int pos = 0; 117 | // for (int i = 0; i < source.length; i++) { 118 | // if (source[i] == s) { 119 | // pos = i; 120 | // break; 121 | // } 122 | // } 123 | // // if we can not find the position,pos = 0; 124 | // return pos; 125 | // } 126 | // 127 | // public static boolean isCanPlaying(String path, Context ctx) { 128 | // if (path.startsWith("http://")) { 129 | // return true; 130 | // } 131 | // MediaPlayer m = new MediaPlayer(); 132 | // // m.reset(); 133 | // try { 134 | // if (path.startsWith("content://")) { 135 | // m.setDataSource(ctx, Uri.parse(path)); 136 | // } else { 137 | // m.setDataSource(path); 138 | // } 139 | // m.prepare(); 140 | // return true; 141 | // } catch (IOException e) { 142 | // Log.v(TAG, "is can playing."); 143 | // return false; 144 | // } catch (IllegalArgumentException e) { 145 | // return false; 146 | // } catch (java.lang.RuntimeException e) { 147 | // return false; 148 | // } finally { 149 | // m.release(); 150 | // m = null; 151 | // } 152 | // } 153 | 154 | private static final String LYRICS_DIR = "/geniusgithub/lyrics"; 155 | 156 | public static String getLyricDir() { 157 | File file = Environment.getExternalStorageDirectory(); 158 | if (file == null) { 159 | return null; 160 | } 161 | File f = new File(file.getAbsolutePath() + LYRICS_DIR); 162 | if (!f.exists()) { 163 | f.mkdirs(); 164 | } 165 | 166 | return f.getAbsolutePath(); 167 | } 168 | 169 | public static String createLyricName(String song, String artist) { 170 | StringBuilder sb = new StringBuilder(); 171 | if (artist != null && artist.length() > 0 172 | && !MediaStore.UNKNOWN_STRING.equals(artist)) { 173 | sb.append(artist); 174 | sb.append(" - "); 175 | } 176 | sb.append(song); 177 | sb.append(".lrc"); 178 | return sb.toString(); 179 | } 180 | 181 | public static String getLyricFile(String song, String artist) { 182 | String lyricDir = getLyricDir(); 183 | log.e("getLyricDir = " + getLyricDir()); 184 | if (lyricDir == null) { 185 | return null; 186 | } 187 | return getLyricDir() + "/" + createLyricName(song, artist); 188 | } 189 | 190 | public static boolean saveFile(String filePath, InputStream inputStream) 191 | throws IOException { 192 | boolean result = false; 193 | if (filePath != null && inputStream != null) { 194 | Log.d(TAG, "filePath:" + filePath); 195 | File file = new File(filePath); 196 | if (file.exists()) { 197 | file.delete(); 198 | } 199 | if (file.createNewFile()) { 200 | FileOutputStream fos = new FileOutputStream( 201 | file.getAbsolutePath()); 202 | byte[] buf = new byte[1024]; 203 | int size = 0; 204 | while ((size = inputStream.read(buf, 0, 1024)) != -1) { 205 | fos.write(buf, 0, size); 206 | } 207 | 208 | fos.flush(); 209 | fos.close(); 210 | inputStream.close(); 211 | result = true; 212 | } 213 | } 214 | return result; 215 | } 216 | 217 | public static boolean saveFile(String filePath, String str) 218 | throws IOException { 219 | boolean result = false; 220 | if (filePath != null && str != null) { 221 | Log.d(TAG, "filePath:" + filePath); 222 | File file = new File(filePath); 223 | if (file.exists()) { 224 | file.delete(); 225 | } 226 | if (file.createNewFile()) { 227 | FileOutputStream fos = new FileOutputStream( 228 | file.getAbsolutePath()); 229 | fos.write(str.getBytes("gb18030")); 230 | fos.flush(); 231 | fos.close(); 232 | result = true; 233 | } 234 | } 235 | return result; 236 | } 237 | // 238 | // public static String getExtensionName(String filename) { 239 | // if ((filename != null) && (filename.length() > 0)) { 240 | // int dot = filename.lastIndexOf('.'); 241 | // if ((dot > -1) && (dot < (filename.length() - 1))) { 242 | // return filename.substring(dot + 1); 243 | // } 244 | // } 245 | // return filename; 246 | // } 247 | // 248 | // public static String getFileNameNoEx(String filename) { 249 | // if ((filename != null) && (filename.length() > 0)) { 250 | // int dot = filename.lastIndexOf('.'); 251 | // if ((dot > -1) && (dot < (filename.length()))) { 252 | // return filename.substring(0, dot); 253 | // } 254 | // } 255 | // return filename; 256 | // } 257 | } 258 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/AbstractMediaPlayEngine.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | 4 | import android.content.Context; 5 | import android.media.MediaPlayer; 6 | import android.media.MediaPlayer.OnCompletionListener; 7 | import android.media.MediaPlayer.OnErrorListener; 8 | import android.media.MediaPlayer.OnPreparedListener; 9 | 10 | import com.geniusgithub.mediarender.center.DlnaMediaModel; 11 | import com.geniusgithub.mediarender.util.CommonLog; 12 | import com.geniusgithub.mediarender.util.LogFactory; 13 | 14 | 15 | 16 | public abstract class AbstractMediaPlayEngine implements IBasePlayEngine, OnCompletionListener, 17 | OnPreparedListener, OnErrorListener{ 18 | 19 | private static final CommonLog log = LogFactory.createLog(); 20 | 21 | protected MediaPlayer mMediaPlayer; 22 | protected DlnaMediaModel mMediaInfo; 23 | protected Context mContext; 24 | protected int mPlayState; 25 | 26 | protected PlayerEngineListener mPlayerEngineListener; 27 | 28 | protected abstract boolean prepareSelf(); 29 | protected abstract boolean prepareComplete(MediaPlayer mp); 30 | 31 | 32 | protected void defaultParam() 33 | { 34 | mMediaPlayer = new MediaPlayer(); 35 | mMediaPlayer.setOnCompletionListener(this); 36 | mMediaPlayer.setOnPreparedListener(this); 37 | mMediaInfo = null; 38 | mPlayState = PlayState.MPS_NOFILE; 39 | 40 | 41 | } 42 | 43 | public AbstractMediaPlayEngine(Context context){ 44 | 45 | mContext = context; 46 | defaultParam(); 47 | } 48 | 49 | public void setPlayerListener(PlayerEngineListener listener){ 50 | mPlayerEngineListener = listener; 51 | } 52 | 53 | @Override 54 | public void play() { 55 | 56 | switch (mPlayState) { 57 | case PlayState.MPS_PAUSE: 58 | mMediaPlayer.start(); 59 | mPlayState = PlayState.MPS_PLAYING; 60 | performPlayListener(mPlayState); 61 | break; 62 | case PlayState.MPS_STOP: 63 | prepareSelf(); 64 | break; 65 | default: 66 | break; 67 | } 68 | 69 | } 70 | 71 | @Override 72 | public void pause() { 73 | 74 | switch (mPlayState) { 75 | case PlayState.MPS_PLAYING: 76 | mMediaPlayer.pause(); 77 | mPlayState = PlayState.MPS_PAUSE; 78 | performPlayListener(mPlayState); 79 | break; 80 | default: 81 | break; 82 | } 83 | 84 | } 85 | 86 | @Override 87 | public void stop() { 88 | if (mPlayState != PlayState.MPS_NOFILE){ 89 | mMediaPlayer.reset(); 90 | mPlayState = PlayState.MPS_STOP; 91 | performPlayListener(mPlayState); 92 | } 93 | } 94 | 95 | 96 | @Override 97 | public void skipTo(int time) { 98 | 99 | switch (mPlayState) { 100 | case PlayState.MPS_PLAYING: 101 | case PlayState.MPS_PAUSE: 102 | int time2 = reviceSeekValue(time); 103 | mMediaPlayer.seekTo(time2); 104 | break; 105 | default: 106 | break; 107 | } 108 | 109 | } 110 | 111 | 112 | public void exit(){ 113 | stop(); 114 | mMediaPlayer.release(); 115 | mMediaInfo = null; 116 | mPlayState = PlayState.MPS_NOFILE; 117 | } 118 | 119 | @Override 120 | public void onPrepared(MediaPlayer mp) { 121 | 122 | prepareComplete(mp); 123 | } 124 | 125 | 126 | 127 | @Override 128 | public void onCompletion(MediaPlayer mp) { 129 | log.e("onCompletion..."); 130 | if (mPlayerEngineListener != null){ 131 | mPlayerEngineListener.onTrackPlayComplete(mMediaInfo); 132 | } 133 | 134 | } 135 | 136 | public boolean isPlaying() { 137 | return mPlayState == PlayState.MPS_PLAYING; 138 | } 139 | 140 | public boolean isPause(){ 141 | return mPlayState == PlayState.MPS_PAUSE; 142 | } 143 | 144 | public void playMedia(DlnaMediaModel mediaInfo){ 145 | 146 | if (mediaInfo != null){ 147 | mMediaInfo = mediaInfo; 148 | prepareSelf(); 149 | } 150 | } 151 | 152 | public int getCurPosition() 153 | { 154 | if (mPlayState == PlayState.MPS_PLAYING || mPlayState == PlayState.MPS_PAUSE) 155 | { 156 | return mMediaPlayer.getCurrentPosition(); 157 | } 158 | 159 | return 0; 160 | } 161 | 162 | public int getDuration(){ 163 | 164 | switch(mPlayState){ 165 | case PlayState.MPS_PLAYING: 166 | case PlayState.MPS_PAUSE: 167 | case PlayState.MPS_PARECOMPLETE: 168 | return mMediaPlayer.getDuration(); 169 | } 170 | 171 | return 0; 172 | } 173 | 174 | public int getPlayState() 175 | { 176 | return mPlayState; 177 | } 178 | 179 | protected void performPlayListener(int playState) 180 | { 181 | if (mPlayerEngineListener != null){ 182 | switch(playState){ 183 | case PlayState.MPS_INVALID: 184 | mPlayerEngineListener.onTrackStreamError(mMediaInfo); 185 | break; 186 | case PlayState.MPS_STOP: 187 | mPlayerEngineListener.onTrackStop(mMediaInfo); 188 | break; 189 | case PlayState.MPS_PLAYING: 190 | mPlayerEngineListener.onTrackPlay(mMediaInfo); 191 | break; 192 | case PlayState.MPS_PAUSE: 193 | mPlayerEngineListener.onTrackPause(mMediaInfo); 194 | break; 195 | case PlayState.MPS_PARESYNC: 196 | mPlayerEngineListener.onTrackPrepareSync(mMediaInfo); 197 | break; 198 | } 199 | } 200 | } 201 | 202 | private int reviceSeekValue(int value) 203 | { 204 | if (value < 0) 205 | { 206 | value = 0; 207 | } 208 | 209 | if (value > mMediaPlayer.getDuration()) 210 | { 211 | value = mMediaPlayer.getDuration(); 212 | } 213 | 214 | return value; 215 | } 216 | @Override 217 | public boolean onError(MediaPlayer mp, int what, int extra) { 218 | 219 | 220 | log.e("onError --> what = " + what); 221 | 222 | return false; 223 | } 224 | 225 | 226 | 227 | } 228 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/AbstractTimer.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | import java.util.Timer; 4 | import java.util.TimerTask; 5 | 6 | import android.content.Context; 7 | import android.os.Handler; 8 | import android.os.Message; 9 | 10 | public abstract class AbstractTimer { 11 | 12 | private final static int TIMER_INTERVAL = 1000; 13 | 14 | protected Context mContext; 15 | private Timer mTimer; 16 | protected MyTimeTask mTimeTask; 17 | protected int mTimeInterval = TIMER_INTERVAL; 18 | protected Handler mHandler; 19 | protected int msgID; 20 | 21 | public AbstractTimer(Context context) 22 | { 23 | mContext = context; 24 | mTimer = new Timer(); 25 | } 26 | 27 | public void setHandler( Handler handler, int msgID){ 28 | mHandler = handler; 29 | this.msgID = msgID; 30 | } 31 | 32 | public void setTimeInterval(int interval){ 33 | mTimeInterval = interval; 34 | } 35 | 36 | public void startTimer() 37 | { 38 | if (mTimeTask == null) 39 | { 40 | mTimeTask = new MyTimeTask(); 41 | mTimer.schedule(mTimeTask, 0, mTimeInterval); 42 | } 43 | } 44 | 45 | public void stopTimer() 46 | { 47 | if (mTimeTask != null) 48 | { 49 | mTimeTask.cancel(); 50 | mTimeTask = null; 51 | } 52 | } 53 | 54 | 55 | class MyTimeTask extends TimerTask 56 | { 57 | 58 | @Override 59 | public void run() { 60 | if (mHandler != null){ 61 | Message msg = mHandler.obtainMessage(msgID); 62 | msg.sendToTarget(); 63 | } 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/CheckDelayTimer.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | public class CheckDelayTimer extends AbstractTimer{ 7 | 8 | private int lastPos = 0; 9 | 10 | public CheckDelayTimer(Context context) { 11 | super(context); 12 | 13 | 14 | 15 | } 16 | 17 | 18 | public void setPos(int pos){ 19 | lastPos = pos; 20 | } 21 | 22 | public boolean isDelay(int pos){ 23 | if (pos == 0 || pos != lastPos){ 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/IBasePlayEngine.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | 4 | public interface IBasePlayEngine { 5 | public void play(); 6 | public void pause(); 7 | public void stop(); 8 | public void skipTo(int time); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/MusicPlayEngineImpl.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | import android.content.Context; 4 | import android.media.AudioManager; 5 | import android.media.MediaPlayer; 6 | import android.media.MediaPlayer.OnBufferingUpdateListener; 7 | import android.media.MediaPlayer.OnSeekCompleteListener; 8 | import android.media.audiofx.Visualizer; 9 | import android.media.audiofx.Visualizer.OnDataCaptureListener; 10 | 11 | import com.geniusgithub.mediarender.util.CommonLog; 12 | import com.geniusgithub.mediarender.util.LogFactory; 13 | 14 | 15 | 16 | public class MusicPlayEngineImpl extends AbstractMediaPlayEngine{ 17 | 18 | private final CommonLog log = LogFactory.createLog(); 19 | 20 | private OnBufferingUpdateListener mBufferingUpdateListener; 21 | private OnSeekCompleteListener mSeekCompleteListener; 22 | private OnDataCaptureListener mDataCaptureListener; 23 | 24 | private Visualizer mVisualizer; 25 | 26 | public MusicPlayEngineImpl(Context context) { 27 | super(context); 28 | 29 | } 30 | 31 | public void setOnBuffUpdateListener(OnBufferingUpdateListener listener){ 32 | mBufferingUpdateListener = listener; 33 | } 34 | 35 | public void setOnSeekCompleteListener(OnSeekCompleteListener listener){ 36 | mSeekCompleteListener = listener; 37 | } 38 | 39 | public void setDataCaptureListener(OnDataCaptureListener listener){ 40 | mDataCaptureListener = listener; 41 | } 42 | 43 | public boolean reInitVisualizer(int sID){ 44 | releaseVisualizer(); 45 | 46 | final int maxCR = Visualizer.getMaxCaptureRate(); 47 | mVisualizer = new Visualizer(sID); 48 | mVisualizer.setCaptureSize(256); 49 | if (mDataCaptureListener != null){ 50 | mVisualizer.setDataCaptureListener(mDataCaptureListener, maxCR/2, false, true); 51 | } 52 | 53 | return true; 54 | } 55 | 56 | public void releaseVisualizer(){ 57 | if (mVisualizer != null) { 58 | mVisualizer.setEnabled(false); 59 | mVisualizer.release(); 60 | mVisualizer = null; 61 | } 62 | } 63 | 64 | public void enableVisualizer(boolean flag){ 65 | if (mVisualizer != null){ 66 | mVisualizer.setEnabled(flag); 67 | } 68 | } 69 | 70 | 71 | @Override 72 | public void play() { 73 | super.play(); 74 | enableVisualizer(true); 75 | } 76 | 77 | @Override 78 | public void pause() { 79 | super.pause(); 80 | enableVisualizer(false); 81 | } 82 | 83 | @Override 84 | public void stop() { 85 | super.stop(); 86 | enableVisualizer(false); 87 | } 88 | 89 | @Override 90 | public void exit(){ 91 | super.exit(); 92 | releaseVisualizer(); 93 | } 94 | 95 | 96 | @Override 97 | protected boolean prepareSelf() { 98 | 99 | mMediaPlayer.reset(); 100 | try { 101 | mMediaPlayer.setDataSource(mMediaInfo.getUrl()); 102 | mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 103 | 104 | if (mBufferingUpdateListener != null){ 105 | mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); 106 | } 107 | mMediaPlayer.prepareAsync(); 108 | log.e("mMediaPlayer.prepareAsync path = " + mMediaInfo.getUrl()); 109 | 110 | mPlayState = PlayState.MPS_PARESYNC; 111 | performPlayListener(mPlayState); 112 | enableVisualizer(true); 113 | 114 | } catch (Exception e) { 115 | e.printStackTrace(); 116 | mPlayState = PlayState.MPS_INVALID; 117 | performPlayListener(mPlayState); 118 | return false; 119 | } 120 | 121 | return true; 122 | } 123 | 124 | @Override 125 | protected boolean prepareComplete(MediaPlayer mp) { 126 | log.e("prepareComplete"); 127 | mPlayState = PlayState.MPS_PARECOMPLETE; 128 | if (mPlayerEngineListener != null){ 129 | mPlayerEngineListener.onTrackPrepareComplete(mMediaInfo); 130 | } 131 | 132 | mMediaPlayer.start(); 133 | 134 | mPlayState = PlayState.MPS_PLAYING; 135 | performPlayListener(mPlayState); 136 | reInitVisualizer(mMediaPlayer.getAudioSessionId()); 137 | enableVisualizer(true); 138 | return true; 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/PlayState.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | 4 | 5 | public class PlayState { 6 | 7 | public static final int MPS_NOFILE = -1; // no file 8 | 9 | public static final int MPS_INVALID = 0; // invalid 10 | 11 | public static final int MPS_PLAYING = 1; // play 12 | 13 | public static final int MPS_PAUSE = 2; // pause 14 | 15 | public static final int MPS_STOP = 3; // pause 16 | 17 | public static final int MPS_PARESYNC = 4; // paresync 18 | 19 | public static final int MPS_PARECOMPLETE = 5; // parecomplete 20 | 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/PlayerEngineListener.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | import com.geniusgithub.mediarender.center.DlnaMediaModel; 4 | 5 | 6 | 7 | public interface PlayerEngineListener { 8 | 9 | public void onTrackPlay(DlnaMediaModel itemInfo); 10 | 11 | public void onTrackStop(DlnaMediaModel itemInfo); 12 | 13 | public void onTrackPause(DlnaMediaModel itemInfo); 14 | 15 | public void onTrackPrepareSync(DlnaMediaModel itemInfo); 16 | 17 | public void onTrackPrepareComplete(DlnaMediaModel itemInfo); 18 | 19 | public void onTrackStreamError(DlnaMediaModel itemInfo); 20 | 21 | public void onTrackPlayComplete(DlnaMediaModel itemInfo); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/SingleSecondTimer.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | import android.content.Context; 4 | 5 | public class SingleSecondTimer extends AbstractTimer{ 6 | 7 | public SingleSecondTimer(Context context) { 8 | super(context); 9 | setTimeInterval(1000); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/player/VideoPlayEngineImpl.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.player; 2 | 3 | 4 | import android.content.Context; 5 | import android.media.AudioManager; 6 | import android.media.MediaPlayer; 7 | import android.media.MediaPlayer.OnBufferingUpdateListener; 8 | import android.media.MediaPlayer.OnErrorListener; 9 | import android.media.MediaPlayer.OnSeekCompleteListener; 10 | import android.view.SurfaceHolder; 11 | 12 | import com.geniusgithub.mediarender.util.CommonLog; 13 | import com.geniusgithub.mediarender.util.CommonUtil; 14 | import com.geniusgithub.mediarender.util.LogFactory; 15 | 16 | 17 | public class VideoPlayEngineImpl extends AbstractMediaPlayEngine{ 18 | 19 | private final CommonLog log = LogFactory.createLog(); 20 | private SurfaceHolder mHolder = null; 21 | private OnBufferingUpdateListener mBufferingUpdateListener; 22 | private OnSeekCompleteListener mSeekCompleteListener; 23 | private OnErrorListener mOnErrorListener; 24 | 25 | public VideoPlayEngineImpl(Context context, SurfaceHolder holder) { 26 | super(context); 27 | 28 | setHolder(holder); 29 | } 30 | 31 | public void setHolder(SurfaceHolder holder){ 32 | mHolder = holder; 33 | } 34 | 35 | public void setOnBuffUpdateListener(OnBufferingUpdateListener listener){ 36 | mBufferingUpdateListener = listener; 37 | } 38 | 39 | public void setOnSeekCompleteListener(OnSeekCompleteListener listener){ 40 | mSeekCompleteListener = listener; 41 | } 42 | 43 | public void setOnErrorListener(OnErrorListener listener){ 44 | mOnErrorListener = listener; 45 | } 46 | 47 | @Override 48 | protected boolean prepareSelf() { 49 | 50 | mMediaPlayer.reset(); 51 | try { 52 | mMediaPlayer.setDataSource(mMediaInfo.getUrl()); 53 | mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 54 | if (mHolder != null){ 55 | mMediaPlayer.setDisplay(mHolder); 56 | } 57 | if (mBufferingUpdateListener != null){ 58 | mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); 59 | } 60 | if (mSeekCompleteListener != null){ 61 | mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener); 62 | } 63 | if (mOnErrorListener != null){ 64 | mMediaPlayer.setOnErrorListener(mOnErrorListener); 65 | } 66 | mMediaPlayer.prepareAsync(); 67 | log.e("mMediaPlayer.prepareAsync path = " + mMediaInfo.getUrl()); 68 | mPlayState = PlayState.MPS_PARESYNC; 69 | performPlayListener(mPlayState); 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | mPlayState = PlayState.MPS_INVALID; 73 | performPlayListener(mPlayState); 74 | return false; 75 | } 76 | 77 | return true; 78 | } 79 | 80 | @Override 81 | protected boolean prepareComplete(MediaPlayer mp) { 82 | 83 | mPlayState = PlayState.MPS_PARECOMPLETE; 84 | if (mPlayerEngineListener != null){ 85 | mPlayerEngineListener.onTrackPrepareComplete(mMediaInfo); 86 | } 87 | 88 | if (mHolder != null){ 89 | CommonUtil.ViewSize viewSize = CommonUtil.getFitSize(mContext, mp); 90 | mHolder.setFixedSize(viewSize.width, viewSize.height); 91 | } 92 | 93 | 94 | mMediaPlayer.start(); 95 | 96 | mPlayState = PlayState.MPS_PLAYING; 97 | performPlayListener(mPlayState); 98 | 99 | return true; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/service/MediaRenderService.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.service; 2 | 3 | import com.geniusgithub.mediarender.RenderApplication; 4 | import com.geniusgithub.mediarender.center.DMRCenter; 5 | import com.geniusgithub.mediarender.center.DMRWorkThread; 6 | import com.geniusgithub.mediarender.center.IBaseEngine; 7 | import com.geniusgithub.mediarender.center.DLNAGenaEventBrocastFactory; 8 | import com.geniusgithub.mediarender.jni.PlatinumJniProxy; 9 | import com.geniusgithub.mediarender.jni.PlatinumReflection; 10 | import com.geniusgithub.mediarender.jni.PlatinumReflection.ActionReflectionListener; 11 | import com.geniusgithub.mediarender.util.CommonLog; 12 | import com.geniusgithub.mediarender.util.CommonUtil; 13 | import com.geniusgithub.mediarender.util.DlnaUtils; 14 | import com.geniusgithub.mediarender.util.LogFactory; 15 | 16 | 17 | 18 | import android.app.Service; 19 | import android.content.Intent; 20 | import android.net.wifi.WifiManager.MulticastLock; 21 | import android.os.Handler; 22 | import android.os.IBinder; 23 | import android.os.Message; 24 | 25 | public class MediaRenderService extends Service implements IBaseEngine{ 26 | 27 | private static final CommonLog log = LogFactory.createLog(); 28 | 29 | public static final String START_RENDER_ENGINE = "com.geniusgithub.start.engine"; 30 | public static final String RESTART_RENDER_ENGINE = "com.geniusgithub.restart.engine"; 31 | 32 | 33 | private DMRWorkThread mWorkThread; 34 | 35 | private ActionReflectionListener mListener; 36 | private DLNAGenaEventBrocastFactory mMediaGenaBrocastFactory; 37 | 38 | private Handler mHandler; 39 | private static final int START_ENGINE_MSG_ID = 0x0001; 40 | private static final int RESTART_ENGINE_MSG_ID = 0x0002; 41 | 42 | private static final int DELAY_TIME = 1000; 43 | 44 | private MulticastLock mMulticastLock; 45 | 46 | @Override 47 | public IBinder onBind(Intent intent) { 48 | return null; 49 | } 50 | 51 | @Override 52 | public void onCreate() { 53 | super.onCreate(); 54 | initRenderService(); 55 | log.e("MediaRenderService onCreate"); 56 | } 57 | 58 | @Override 59 | public void onDestroy() { 60 | unInitRenderService(); 61 | log.e("MediaRenderService onDestroy"); 62 | super.onDestroy(); 63 | 64 | } 65 | 66 | @Override 67 | public int onStartCommand(Intent intent, int flags, int startId) { 68 | 69 | if (intent != null){ 70 | String actionString = intent.getAction(); 71 | if (actionString != null){ 72 | if (actionString.equalsIgnoreCase(START_RENDER_ENGINE)){ 73 | delayToSendStartMsg(); 74 | }else if (actionString.equalsIgnoreCase(RESTART_RENDER_ENGINE)){ 75 | delayToSendRestartMsg(); 76 | } 77 | } 78 | } 79 | 80 | return super.onStartCommand(intent, flags, startId); 81 | 82 | } 83 | 84 | 85 | private void initRenderService(){ 86 | 87 | mListener = new DMRCenter(this); 88 | PlatinumReflection.setActionInvokeListener(mListener); 89 | mMediaGenaBrocastFactory = new DLNAGenaEventBrocastFactory(this); 90 | mMediaGenaBrocastFactory.registerBrocast(); 91 | mWorkThread = new DMRWorkThread(this); 92 | 93 | mHandler = new Handler(){ 94 | @Override 95 | public void handleMessage(Message msg) { 96 | switch(msg.what){ 97 | case START_ENGINE_MSG_ID: 98 | startEngine(); 99 | break; 100 | case RESTART_ENGINE_MSG_ID: 101 | restartEngine(); 102 | break; 103 | } 104 | } 105 | 106 | }; 107 | 108 | mMulticastLock = CommonUtil.openWifiBrocast(this); 109 | log.e("openWifiBrocast = " + mMulticastLock != null ? true : false); 110 | } 111 | 112 | 113 | private void unInitRenderService(){ 114 | stopEngine(); 115 | removeStartMsg(); 116 | removeRestartMsg(); 117 | mMediaGenaBrocastFactory.unRegisterBrocast(); 118 | if (mMulticastLock != null){ 119 | mMulticastLock.release(); 120 | mMulticastLock = null; 121 | log.e("closeWifiBrocast"); 122 | } 123 | } 124 | 125 | private void delayToSendStartMsg(){ 126 | removeStartMsg(); 127 | mHandler.sendEmptyMessageDelayed(START_ENGINE_MSG_ID, DELAY_TIME); 128 | } 129 | 130 | private void delayToSendRestartMsg(){ 131 | removeStartMsg(); 132 | removeRestartMsg(); 133 | mHandler.sendEmptyMessageDelayed(RESTART_ENGINE_MSG_ID, DELAY_TIME); 134 | } 135 | 136 | private void removeStartMsg(){ 137 | mHandler.removeMessages(START_ENGINE_MSG_ID); 138 | } 139 | 140 | private void removeRestartMsg(){ 141 | mHandler.removeMessages(RESTART_ENGINE_MSG_ID); 142 | } 143 | 144 | 145 | @Override 146 | public boolean startEngine() { 147 | awakeWorkThread(); 148 | return true; 149 | } 150 | 151 | @Override 152 | public boolean stopEngine() { 153 | mWorkThread.setParam("", ""); 154 | exitWorkThread(); 155 | return true; 156 | } 157 | 158 | @Override 159 | public boolean restartEngine() { 160 | String friendName = DlnaUtils.getDevName(this); 161 | String uuid = DlnaUtils.creat12BitUUID(this); 162 | mWorkThread.setParam(friendName, uuid); 163 | if (mWorkThread.isAlive()){ 164 | mWorkThread.restartEngine(); 165 | }else{ 166 | mWorkThread.start(); 167 | } 168 | return true; 169 | } 170 | 171 | private void awakeWorkThread(){ 172 | String friendName = DlnaUtils.getDevName(this); 173 | String uuid = DlnaUtils.creat12BitUUID(this); 174 | mWorkThread.setParam(friendName, uuid); 175 | 176 | 177 | if (mWorkThread.isAlive()){ 178 | mWorkThread.awakeThread(); 179 | }else{ 180 | mWorkThread.start(); 181 | } 182 | } 183 | 184 | private void exitWorkThread(){ 185 | if (mWorkThread != null && mWorkThread.isAlive()){ 186 | mWorkThread.exit(); 187 | long time1 = System.currentTimeMillis(); 188 | while(mWorkThread.isAlive()){ 189 | try { 190 | Thread.sleep(100); 191 | } catch (InterruptedException e) { 192 | e.printStackTrace(); 193 | } 194 | } 195 | long time2 = System.currentTimeMillis(); 196 | log.e("exitWorkThread cost time:" + (time2 - time1)); 197 | mWorkThread = null; 198 | } 199 | } 200 | 201 | 202 | } 203 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/util/CommonLog.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.util; 2 | 3 | import android.util.Log; 4 | 5 | public class CommonLog { 6 | private String tag = "CommonLog"; 7 | public static int logLevel = Log.VERBOSE; 8 | public static boolean isDebug = true; 9 | 10 | public CommonLog() { } 11 | 12 | public CommonLog(String tag) { 13 | this.tag = tag; 14 | } 15 | 16 | public void setTag(String tag) { 17 | this.tag = tag; 18 | } 19 | 20 | private String getFunctionName() { 21 | StackTraceElement[] sts = Thread.currentThread().getStackTrace(); 22 | 23 | if (sts == null) { 24 | return null; 25 | } 26 | 27 | 28 | for (StackTraceElement st:sts) { 29 | if (st.isNativeMethod()) { 30 | continue; 31 | } 32 | 33 | if (st.getClassName().equals(Thread.class.getName())) { 34 | continue; 35 | } 36 | 37 | if (st.getClassName().equals(this.getClass().getName())) { 38 | continue; 39 | } 40 | 41 | return "["+Thread.currentThread().getId()+": "+st.getFileName()+":"+st.getLineNumber()+"]"; 42 | } 43 | 44 | return null; 45 | } 46 | 47 | public void info(Object str) { 48 | if (logLevel <= Log.INFO) { 49 | String name = getFunctionName(); 50 | String ls=(name==null?str.toString():(name+" - "+str)); 51 | Log.i(tag, ls); 52 | } 53 | } 54 | 55 | public void i(Object str) { 56 | if (isDebug) { 57 | info(str); 58 | } 59 | } 60 | 61 | public void verbose(Object str) { 62 | if (logLevel <= Log.VERBOSE) { 63 | String name = getFunctionName(); 64 | String ls=(name==null?str.toString():(name+" - "+str)); 65 | Log.v(tag, ls); 66 | } 67 | } 68 | 69 | public void v(Object str) { 70 | if (isDebug) { 71 | verbose(str); 72 | } 73 | } 74 | 75 | public void warn(Object str) { 76 | if (logLevel <= Log.WARN) { 77 | String name = getFunctionName(); 78 | String ls=(name==null?str.toString():(name+" - "+str)); 79 | Log.w(tag, ls); 80 | } 81 | } 82 | 83 | public void w(Object str) { 84 | if (isDebug) { 85 | warn(str); 86 | } 87 | } 88 | 89 | public void error(Object str) { 90 | if (logLevel <= Log.ERROR) { 91 | String name = getFunctionName(); 92 | String ls=(name==null?str.toString():(name+" - "+str)); 93 | Log.e(tag, ls); 94 | } 95 | } 96 | 97 | public void error(Exception ex) { 98 | if (logLevel <= Log.ERROR) { 99 | StringBuffer sb = new StringBuffer(); 100 | String name = getFunctionName(); 101 | StackTraceElement[] sts = ex.getStackTrace(); 102 | 103 | if (name != null) { 104 | sb.append(name+" - "+ex+"\r\n"); 105 | } else { 106 | sb.append(ex+"\r\n"); 107 | } 108 | 109 | if (sts != null && sts.length > 0) { 110 | for (StackTraceElement st:sts) { 111 | if (st != null) { 112 | sb.append("[ "+st.getFileName()+":"+st.getLineNumber()+" ]\r\n"); 113 | } 114 | } 115 | } 116 | 117 | Log.e(tag, sb.toString()); 118 | } 119 | } 120 | 121 | public void e(Object str) { 122 | if (isDebug) { 123 | error(str); 124 | } 125 | } 126 | 127 | public void e(Exception ex) { 128 | if (isDebug) { 129 | error(ex); 130 | } 131 | } 132 | 133 | public void debug(Object str) { 134 | if (logLevel <= Log.DEBUG) { 135 | String name = getFunctionName(); 136 | String ls = (name == null?str.toString():(name+" - "+str)); 137 | Log.d(tag, ls); 138 | } 139 | } 140 | 141 | public void d(Object str) { 142 | if (isDebug) { 143 | debug(str); 144 | } 145 | } 146 | } -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/util/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.util; 2 | 3 | 4 | 5 | import java.io.InputStream; 6 | import java.net.InetAddress; 7 | import java.net.NetworkInterface; 8 | import java.net.SocketException; 9 | import java.util.Enumeration; 10 | 11 | 12 | import android.content.Context; 13 | import android.content.pm.PackageInfo; 14 | import android.content.pm.PackageManager; 15 | import android.media.AudioManager; 16 | import android.media.MediaPlayer; 17 | import android.net.ConnectivityManager; 18 | import android.net.NetworkInfo; 19 | import android.net.NetworkInfo.State; 20 | import android.net.TrafficStats; 21 | import android.net.wifi.WifiInfo; 22 | import android.net.wifi.WifiManager; 23 | import android.net.wifi.WifiManager.MulticastLock; 24 | import android.os.Environment; 25 | import android.view.Display; 26 | import android.view.WindowManager; 27 | import android.widget.Toast; 28 | 29 | public class CommonUtil { 30 | 31 | private static final CommonLog log = LogFactory.createLog(); 32 | 33 | public static boolean hasSDCard() { 34 | String status = Environment.getExternalStorageState(); 35 | if (!status.equals(Environment.MEDIA_MOUNTED)) { 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | public static String getRootFilePath() { 42 | if (hasSDCard()) { 43 | return Environment.getExternalStorageDirectory().getAbsolutePath() + "/";// filePath:/sdcard/ 44 | } else { 45 | return Environment.getDataDirectory().getAbsolutePath() + "/data/"; // filePath: /data/data/ 46 | } 47 | } 48 | 49 | public static boolean checkNetworkState(Context context){ 50 | boolean netstate = false; 51 | ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 52 | if(connectivity != null) 53 | { 54 | NetworkInfo[] info = connectivity.getAllNetworkInfo(); 55 | if (info != null) { 56 | for (int i = 0; i < info.length; i++) 57 | { 58 | if (info[i].getState() == NetworkInfo.State.CONNECTED) 59 | { 60 | netstate = true; 61 | break; 62 | } 63 | } 64 | } 65 | } 66 | return netstate; 67 | } 68 | 69 | public static String getLocalMacAddress(Context mc){ 70 | String defmac = "00:00:00:00:00:00"; 71 | InputStream input = null; 72 | String wifimac = getWifiMacAddress(mc); 73 | if(null != wifimac){ 74 | if(!wifimac.equals(defmac)) 75 | return wifimac; 76 | } 77 | try{ 78 | 79 | ProcessBuilder builder = new ProcessBuilder( "busybox","ifconfig"); 80 | Process process = builder.start(); 81 | input = process.getInputStream(); 82 | 83 | 84 | 85 | byte[] b = new byte[1024]; 86 | StringBuffer buffer = new StringBuffer(); 87 | while(input.read(b)>0){ 88 | buffer.append(new String(b)); 89 | } 90 | String value = buffer.substring(0); 91 | String systemFlag ="HWaddr "; 92 | int index = value.indexOf(systemFlag); 93 | //List address = new ArrayList (); 94 | if(0 fit2) 166 | { 167 | fit = width2 * 1.0 / videoWidth; 168 | }else{ 169 | fit = height2 * 1.0 / videoHeight; 170 | } 171 | 172 | ViewSize viewSize = new ViewSize(); 173 | viewSize.width = (int) (fit * videoWidth); 174 | viewSize.height = (int) (fit * videoHeight); 175 | 176 | return viewSize; 177 | } 178 | 179 | public static class ViewSize 180 | { 181 | public int width = 0; 182 | public int height = 0; 183 | } 184 | 185 | public static boolean getWifiState(Context context){ 186 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 187 | State wifistate = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); 188 | if (wifistate != State.CONNECTED){ 189 | return false; 190 | } 191 | 192 | State mobileState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); 193 | boolean ret = State.CONNECTED != mobileState; 194 | return ret; 195 | } 196 | 197 | 198 | public static boolean getMobileState(Context context){ 199 | ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 200 | State wifistate = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); 201 | if (wifistate != State.CONNECTED){ 202 | return false; 203 | } 204 | 205 | State mobileState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); 206 | boolean ret = State.CONNECTED == mobileState; 207 | return ret; 208 | } 209 | 210 | 211 | 212 | private static long m_lSysNetworkSpeedLastTs = 0; 213 | private static long m_lSystNetworkLastBytes = 0; 214 | private static float m_fSysNetowrkLastSpeed = 0.0f; 215 | public static float getSysNetworkDownloadSpeed() { 216 | long nowMS = System.currentTimeMillis(); 217 | long nowBytes = TrafficStats.getTotalRxBytes(); 218 | 219 | long timeinterval = nowMS - m_lSysNetworkSpeedLastTs; 220 | long bytes = nowBytes - m_lSystNetworkLastBytes; 221 | 222 | if(timeinterval > 0) m_fSysNetowrkLastSpeed = (float)bytes * 1.0f / (float)timeinterval; 223 | 224 | m_lSysNetworkSpeedLastTs = nowMS; 225 | m_lSystNetworkLastBytes = nowBytes; 226 | 227 | return m_fSysNetowrkLastSpeed; 228 | } 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/util/DlnaUtils.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.util; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | import android.content.Context; 7 | 8 | import com.geniusgithub.mediarender.center.DlnaMediaModel; 9 | import com.geniusgithub.mediarender.datastore.LocalConfigSharePreference; 10 | import com.geniusgithub.mediarender.jni.PlatinumReflection; 11 | 12 | 13 | public class DlnaUtils { 14 | 15 | private static final CommonLog log = LogFactory.createLog(); 16 | 17 | public static boolean setDevName(Context context, String friendName){ 18 | return LocalConfigSharePreference.commintDevName(context, friendName); 19 | } 20 | 21 | public static String getDevName(Context context){ 22 | return LocalConfigSharePreference.getDevName(context); 23 | } 24 | 25 | 26 | public static String creat12BitUUID(Context context){ 27 | String defaultUUID = "123456789abc"; 28 | 29 | String mac = CommonUtil.getLocalMacAddress(context); 30 | 31 | mac = mac.replace(":",""); 32 | mac = mac.replace(".",""); 33 | 34 | if (mac.length() != 12){ 35 | mac = defaultUUID; 36 | } 37 | 38 | mac += "-dmr"; 39 | return mac; 40 | } 41 | 42 | 43 | 44 | public static int parseSeekTime(String data) throws Exception{ 45 | 46 | int seekPos = 0; 47 | 48 | String[] seektime = data.split("="); 49 | if(2 != seektime.length){ 50 | return seekPos; 51 | } 52 | String timetype = seektime[0]; 53 | String position = seektime[1]; 54 | if (PlatinumReflection.MEDIA_SEEK_TIME_TYPE_REL_TIME.equals(timetype)){ 55 | seekPos = convertSeekRelTimeToMs(position); 56 | }else{ 57 | log.e("timetype = " + timetype + ", position = " + position); 58 | } 59 | 60 | 61 | return seekPos; 62 | } 63 | 64 | public static int convertSeekRelTimeToMs(String reltime){ 65 | int sec=0; 66 | int ms=0; 67 | String[] times=reltime.split(":"); 68 | if(3!=times.length) 69 | return 0; 70 | if(!isNumeric(times[0])) 71 | return 0; 72 | int hour=Integer.parseInt(times[0]); 73 | if(!isNumeric(times[1])) 74 | return 0; 75 | int min=Integer.parseInt(times[1]); 76 | String[] times2=times[2].split("\\."); 77 | if(2==times2.length){//00:00:00.000 78 | if(!isNumeric(times2[0])) 79 | return 0; 80 | sec=Integer.parseInt(times2[0]); 81 | if(!isNumeric(times2[1])) 82 | return 0; 83 | ms=Integer.parseInt(times2[1]); 84 | }else if(1==times2.length){//00:00:00 85 | if(!isNumeric(times2[0])) 86 | return 0; 87 | sec=Integer.parseInt(times2[0]); 88 | } 89 | return (hour*3600000+min*60000+sec*1000+ms); 90 | } 91 | 92 | public static boolean isNumeric(String str){ 93 | if("".equals(str)) 94 | return false; 95 | Pattern pattern = Pattern.compile("[0-9]*"); 96 | Matcher isNum = pattern.matcher(str); 97 | if( !isNum.matches() ){ 98 | return false; 99 | } 100 | return true; 101 | } 102 | 103 | public static String formatTimeFromMSInt(int time){ 104 | String hour="00"; 105 | String min="00"; 106 | String sec="00"; 107 | String split=":"; 108 | int tmptime=time; 109 | int tmp=0; 110 | if(tmptime>=3600000){ 111 | tmp=tmptime/3600000; 112 | hour=formatHunToStr(tmp); 113 | tmptime-=tmp*3600000; 114 | } 115 | if(tmptime>=60000){ 116 | tmp=tmptime/60000; 117 | min=formatHunToStr(tmp); 118 | tmptime-=tmp*60000; 119 | } 120 | if(tmptime>=1000){ 121 | tmp=tmptime/1000; 122 | sec=formatHunToStr(tmp); 123 | tmptime-=tmp*1000; 124 | } 125 | 126 | String ret=hour+split+min+split+sec; 127 | return ret; 128 | } 129 | 130 | private static String formatHunToStr(int hun){ 131 | hun=hun%100; 132 | if(hun>9) 133 | return (""+hun); 134 | else 135 | return ("0"+hun); 136 | } 137 | 138 | 139 | public static String formateTime(long millis) 140 | { 141 | String str = ""; 142 | int hour = 0; 143 | int time = (int) (millis / 1000); 144 | int second = time % 60; 145 | int minute = time / 60; 146 | if (minute >= 60){ 147 | hour = minute / 60; 148 | minute %= 60; 149 | str = String.format("%02d:%02d:%02d", hour, minute, second); 150 | }else{ 151 | str = String.format("%02d:%02d", minute, second); 152 | } 153 | 154 | 155 | return str; 156 | 157 | } 158 | 159 | public final static String DLNA_OBJECTCLASS_MUSICID = "object.item.audioItem"; 160 | public final static String DLNA_OBJECTCLASS_VIDEOID = "object.item.videoItem"; 161 | public final static String DLNA_OBJECTCLASS_PHOTOID = "object.item.imageItem"; 162 | 163 | public static boolean isAudioItem(DlnaMediaModel item){ 164 | String objectClass = item.getObjectClass(); 165 | if (objectClass.contains(DLNA_OBJECTCLASS_MUSICID)){ 166 | return true; 167 | } 168 | 169 | return false; 170 | } 171 | 172 | public static boolean isVideoItem(DlnaMediaModel item){ 173 | String objectClass = item.getObjectClass(); 174 | if (objectClass.contains(DLNA_OBJECTCLASS_VIDEOID)){ 175 | return true; 176 | } 177 | return false; 178 | } 179 | 180 | public static boolean isImageItem(DlnaMediaModel item){ 181 | String objectClass = item.getObjectClass(); 182 | if (objectClass.contains(DLNA_OBJECTCLASS_PHOTOID)){ 183 | return true; 184 | } 185 | return false; 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /app/src/main/java/com/geniusgithub/mediarender/util/LogFactory.java: -------------------------------------------------------------------------------- 1 | package com.geniusgithub.mediarender.util; 2 | 3 | 4 | public class LogFactory { 5 | private static final String TAG = "MediaRender"; 6 | private static CommonLog log = null; 7 | 8 | public static CommonLog createLog() { 9 | if (log == null) { 10 | log = new CommonLog(); 11 | } 12 | 13 | log.setTag(TAG); 14 | return log; 15 | } 16 | 17 | public static CommonLog createLog(String tag) { 18 | if (log == null) { 19 | log = new CommonLog(); 20 | } 21 | 22 | if (tag == null || tag.length() < 1) { 23 | log.setTag(TAG); 24 | } else { 25 | log.setTag(tag); 26 | } 27 | return log; 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libgit-platinum.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/jniLibs/armeabi/libgit-platinum.so -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_pause_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/btn_pause_n.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_pause_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/btn_pause_p.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_play_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/btn_play_n.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_play_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/btn_play_p.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/button_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/button_pressed.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cm_progress_anim.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/input_disabled.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/input_disabled.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/input_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/input_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/input_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/input_pressed.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/main_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/main_bg.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/media_bacground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/media_bacground.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/media_prepare_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/media_prepare_startup.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/media_progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/media_progress.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/media_tool_bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/media_tool_bg1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/media_tool_bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/media_tool_bg2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mp_music_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/mp_music_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_blue.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/progress_bottom.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/progress_first.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/progress_second.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_thumb_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/progress_thumb_n.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_thumb_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geniusgithub/MediaRender/4c91ea99ae34caeab5f036c3bf8c6e8691ea9e49/app/src/main/res/drawable/progress_thumb_p.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progressbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seekbar_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seekbar_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn_pause.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn_play.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 |