|
1 | 1 | package com.atomjack.vcfp;
|
2 | 2 |
|
| 3 | +import java.io.IOException; |
3 | 4 | import java.io.InputStream;
|
4 | 5 | import java.lang.reflect.Type;
|
5 | 6 | import java.math.BigInteger;
|
6 |
| -import java.net.InetAddress; |
7 |
| -import java.net.InterfaceAddress; |
8 |
| -import java.net.NetworkInterface; |
9 | 7 | import java.security.MessageDigest;
|
10 | 8 | import java.security.SecureRandom;
|
11 | 9 | import java.util.ArrayList;
|
12 | 10 | import java.util.Arrays;
|
13 |
| -import java.util.Enumeration; |
14 | 11 | import java.util.HashMap;
|
15 | 12 | import java.util.Locale;
|
16 | 13 | import java.util.Map;
|
@@ -81,6 +78,16 @@ public class VoiceControlForPlexApplication extends Application
|
81 | 78 | .registerTypeAdapter(Uri.class, new UriSerializer())
|
82 | 79 | .create();
|
83 | 80 |
|
| 81 | + private NOTIFICATION_STATUS notificationStatus = NOTIFICATION_STATUS.off; |
| 82 | + public static enum NOTIFICATION_STATUS { |
| 83 | + off, |
| 84 | + on, |
| 85 | + initializing |
| 86 | + } |
| 87 | + |
| 88 | + private NotificationManager mNotifyMgr; |
| 89 | + private Bitmap notificationBitmap = null; |
| 90 | + |
84 | 91 | public final static class Intent {
|
85 | 92 | public final static String GDMRECEIVE = "com.atomjack.vcfp.intent.gdmreceive";
|
86 | 93 |
|
@@ -148,6 +155,8 @@ public void onCreate() {
|
148 | 155 | if(!mHasChromecast)
|
149 | 156 | setupInAppPurchasing();
|
150 | 157 |
|
| 158 | + mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); |
| 159 | + |
151 | 160 | // Load saved clients and servers
|
152 | 161 | Type clientType = new TypeToken<HashMap<String, PlexClient>>(){}.getType();
|
153 | 162 | VoiceControlForPlexApplication.castClients = gsonRead.fromJson(Preferences.get(Preferences.SAVED_CAST_CLIENTS, "{}"), clientType);
|
@@ -336,81 +345,118 @@ public static String generateRandomString() {
|
336 | 345 | }
|
337 | 346 |
|
338 | 347 | public void setNotification(final PlexClient client, final PlayerState currentState, final PlexMedia media) {
|
| 348 | + setNotification(client, currentState, media, false); |
| 349 | + } |
| 350 | + |
| 351 | + public void setNotification(final PlexClient client, final PlayerState currentState, final PlexMedia media, boolean skipThumb) { |
339 | 352 | Logger.d("Setting notification, client: %s, media: %s", client, media);
|
340 |
| - new AsyncTask() { |
341 |
| - @Override |
342 |
| - protected Object doInBackground(Object[] objects) { |
343 |
| - if(client != null && media != null) { |
344 |
| - InputStream inputStream = null; |
345 |
| - try { |
346 |
| - SimpleDiskCache.InputStreamEntry inputStreamEntry = mSimpleDiskCache.getInputStream(media.getImageKey(PlexMedia.IMAGE_KEY.NOTIFICATION_THUMB)); |
347 |
| - if(inputStreamEntry != null) { |
348 |
| - inputStream = inputStreamEntry.getInputStream(); |
349 |
| -// inputStream.reset(); |
350 |
| - } |
351 |
| - } catch (Exception ex) { |
352 |
| - ex.printStackTrace(); |
353 |
| - } |
354 |
| - if(inputStream == null) { |
355 |
| - inputStream = media.getThumb(64, 64); |
356 |
| - } |
357 |
| - Bitmap thumb = BitmapFactory.decodeStream(inputStream); |
358 |
| - NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); |
359 |
| - android.content.Intent rewindIntent = new android.content.Intent(VoiceControlForPlexApplication.this, PlexControlService.class); |
360 |
| - rewindIntent.setAction(PlexControlService.ACTION_REWIND); |
361 |
| - rewindIntent.putExtra(PlexControlService.CLIENT, client); |
362 |
| - rewindIntent.putExtra(PlexControlService.MEDIA, media); |
363 |
| - PendingIntent piRewind = PendingIntent.getService(VoiceControlForPlexApplication.this, 0, rewindIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
364 |
| - |
365 |
| - android.content.Intent playIntent = new android.content.Intent(VoiceControlForPlexApplication.this, PlexControlService.class); |
366 |
| - playIntent.setAction(PlexControlService.ACTION_PLAY); |
367 |
| - playIntent.putExtra(PlexControlService.CLIENT, client); |
368 |
| - playIntent.putExtra(PlexControlService.MEDIA, media); |
369 |
| - PendingIntent playPendingIntent = PendingIntent.getService(VoiceControlForPlexApplication.this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
370 |
| - |
371 |
| - android.content.Intent pauseIntent = new android.content.Intent(VoiceControlForPlexApplication.this, PlexControlService.class); |
372 |
| - pauseIntent.setAction(PlexControlService.ACTION_PAUSE); |
373 |
| - pauseIntent.putExtra(PlexControlService.CLIENT, client); |
374 |
| - pauseIntent.putExtra(PlexControlService.MEDIA, media); |
375 |
| - PendingIntent pausePendingIntent = PendingIntent.getService(VoiceControlForPlexApplication.this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
376 |
| - |
377 |
| - android.content.Intent nowPlayingIntent; |
378 |
| - if(client.isCastClient) { |
379 |
| - nowPlayingIntent = new android.content.Intent(VoiceControlForPlexApplication.this, CastActivity.class); |
380 |
| -// nowPlayingIntent.setAction(Intent.CAST_MEDIA); |
381 |
| - } else |
382 |
| - nowPlayingIntent = new android.content.Intent(VoiceControlForPlexApplication.this, NowPlayingActivity.class); |
383 |
| - nowPlayingIntent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK | |
384 |
| - android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK); |
385 |
| - nowPlayingIntent.putExtra(Intent.EXTRA_MEDIA, media); |
386 |
| - nowPlayingIntent.putExtra(Intent.EXTRA_CLIENT, client); |
387 |
| - PendingIntent piNowPlaying = PendingIntent.getActivity(VoiceControlForPlexApplication.this, 0, nowPlayingIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
388 |
| - |
389 |
| - try { |
390 |
| - NotificationCompat.Builder mBuilder = |
391 |
| - new NotificationCompat.Builder(VoiceControlForPlexApplication.this) |
392 |
| - .setSmallIcon(R.drawable.ic_launcher) |
393 |
| - .setAutoCancel(false) |
394 |
| - .setOngoing(true) |
395 |
| - .setOnlyAlertOnce(true) |
396 |
| - .setContentIntent(piNowPlaying) |
397 |
| - .setContent(getNotificationView(R.layout.now_playing_notification, thumb, media, client, playPendingIntent, pausePendingIntent, piRewind, currentState == PlayerState.PLAYING)) |
398 |
| - .setDefaults(Notification.DEFAULT_ALL); |
399 |
| - Notification n = mBuilder.build(); |
400 |
| - if (Build.VERSION.SDK_INT >= 16) |
401 |
| - n.bigContentView = getNotificationView(R.layout.now_playing_notification_big, thumb, media, client, playPendingIntent, pausePendingIntent, piRewind, currentState == PlayerState.PLAYING); |
402 |
| - |
403 |
| - // Disable notification sound |
404 |
| - n.defaults = 0; |
405 |
| - mNotifyMgr.notify(nowPlayingNotificationId, n); |
406 |
| - } catch (Exception ex) { |
407 |
| - ex.printStackTrace(); |
| 353 | + if(notificationStatus == NOTIFICATION_STATUS.off) { |
| 354 | + notificationStatus = NOTIFICATION_STATUS.initializing; |
| 355 | + notificationBitmap = null; |
| 356 | + } |
| 357 | + |
| 358 | + try { |
| 359 | + Logger.d("Trying to get cached thumb: %s", media.getImageKey(PlexMedia.IMAGE_KEY.NOTIFICATION_THUMB)); |
| 360 | + SimpleDiskCache.BitmapEntry bitmapEntry = mSimpleDiskCache.getBitmap(media.getImageKey(PlexMedia.IMAGE_KEY.NOTIFICATION_THUMB)); |
| 361 | + Logger.d("bitmapEntry: %s", bitmapEntry); |
| 362 | + if(bitmapEntry != null) { |
| 363 | + notificationBitmap = bitmapEntry.getBitmap(); |
| 364 | + } |
| 365 | + } catch (Exception ex) { |
| 366 | + ex.printStackTrace(); |
| 367 | + } |
| 368 | + |
| 369 | + if(notificationBitmap == null && notificationStatus == NOTIFICATION_STATUS.initializing && !skipThumb) { |
| 370 | + Logger.d("Thumb not found in cache. Downloading."); |
| 371 | + new AsyncTask() { |
| 372 | + @Override |
| 373 | + protected Object doInBackground(Object[] objects) { |
| 374 | + if (client != null && media != null) { |
| 375 | + InputStream inputStream = media.getNotificationThumb(); |
| 376 | + Logger.d("Got input stream: %s", inputStream); |
| 377 | + notificationBitmap = BitmapFactory.decodeStream(inputStream); |
| 378 | + try { |
| 379 | + inputStream.reset(); |
| 380 | + } catch (IOException e) {} |
| 381 | + Logger.d("notificationBitmap: %s", notificationBitmap); |
| 382 | + try { |
| 383 | + Logger.d("image key: %s", media.getImageKey(PlexMedia.IMAGE_KEY.NOTIFICATION_THUMB)); |
| 384 | + mSimpleDiskCache.put(media.getImageKey(PlexMedia.IMAGE_KEY.NOTIFICATION_THUMB), inputStream); |
| 385 | + inputStream.close(); |
| 386 | + Logger.d("Downloaded thumb. Redoing notification."); |
| 387 | + setNotification(client, currentState, media, true); |
| 388 | + } catch (Exception e) {} |
408 | 389 | }
|
| 390 | + return null; |
409 | 391 | }
|
410 |
| - return null; |
411 |
| - } |
412 |
| - }.execute(); |
| 392 | + }.execute(); |
| 393 | + } |
| 394 | + |
| 395 | + Logger.d("Setting up notification"); |
| 396 | + // notificationBitmap |
| 397 | + android.content.Intent rewindIntent = new android.content.Intent(VoiceControlForPlexApplication.this, PlexControlService.class); |
| 398 | + rewindIntent.setAction(PlexControlService.ACTION_REWIND); |
| 399 | + rewindIntent.putExtra(PlexControlService.CLIENT, client); |
| 400 | + rewindIntent.putExtra(PlexControlService.MEDIA, media); |
| 401 | + PendingIntent piRewind = PendingIntent.getService(VoiceControlForPlexApplication.this, 0, rewindIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
| 402 | + |
| 403 | + android.content.Intent playIntent = new android.content.Intent(VoiceControlForPlexApplication.this, PlexControlService.class); |
| 404 | + playIntent.setAction(PlexControlService.ACTION_PLAY); |
| 405 | + playIntent.putExtra(PlexControlService.CLIENT, client); |
| 406 | + playIntent.putExtra(PlexControlService.MEDIA, media); |
| 407 | + PendingIntent playPendingIntent = PendingIntent.getService(VoiceControlForPlexApplication.this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
| 408 | + |
| 409 | + android.content.Intent pauseIntent = new android.content.Intent(VoiceControlForPlexApplication.this, PlexControlService.class); |
| 410 | + pauseIntent.setAction(PlexControlService.ACTION_PAUSE); |
| 411 | + pauseIntent.putExtra(PlexControlService.CLIENT, client); |
| 412 | + pauseIntent.putExtra(PlexControlService.MEDIA, media); |
| 413 | + PendingIntent pausePendingIntent = PendingIntent.getService(VoiceControlForPlexApplication.this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
| 414 | + |
| 415 | + android.content.Intent nowPlayingIntent; |
| 416 | + if(client.isCastClient) { |
| 417 | + nowPlayingIntent = new android.content.Intent(VoiceControlForPlexApplication.this, CastActivity.class); |
| 418 | +// nowPlayingIntent.setAction(Intent.CAST_MEDIA); |
| 419 | + } else |
| 420 | + nowPlayingIntent = new android.content.Intent(VoiceControlForPlexApplication.this, NowPlayingActivity.class); |
| 421 | + nowPlayingIntent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK | |
| 422 | + android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK); |
| 423 | + nowPlayingIntent.putExtra(Intent.EXTRA_MEDIA, media); |
| 424 | + nowPlayingIntent.putExtra(Intent.EXTRA_CLIENT, client); |
| 425 | + PendingIntent piNowPlaying = PendingIntent.getActivity(VoiceControlForPlexApplication.this, 0, nowPlayingIntent, PendingIntent.FLAG_UPDATE_CURRENT); |
| 426 | + |
| 427 | + try { |
| 428 | + NotificationCompat.Builder mBuilder = |
| 429 | + new NotificationCompat.Builder(VoiceControlForPlexApplication.this) |
| 430 | + .setSmallIcon(R.drawable.ic_launcher) |
| 431 | + .setAutoCancel(false) |
| 432 | + .setOngoing(true) |
| 433 | + .setOnlyAlertOnce(true) |
| 434 | + .setContentIntent(piNowPlaying) |
| 435 | + .setContent(getNotificationView(R.layout.now_playing_notification, notificationBitmap, media, client, playPendingIntent, pausePendingIntent, piRewind, currentState == PlayerState.PLAYING)) |
| 436 | + .setDefaults(Notification.DEFAULT_ALL); |
| 437 | + Notification n = mBuilder.build(); |
| 438 | + if (Build.VERSION.SDK_INT >= 16) |
| 439 | + n.bigContentView = getNotificationView(media.isMusic() ? R.layout.now_playing_notification_big_music : R.layout.now_playing_notification_big, notificationBitmap, media, client, playPendingIntent, pausePendingIntent, piRewind, currentState == PlayerState.PLAYING); |
| 440 | + |
| 441 | + // Disable notification sound |
| 442 | + n.defaults = 0; |
| 443 | + mNotifyMgr.notify(nowPlayingNotificationId, n); |
| 444 | + notificationStatus = NOTIFICATION_STATUS.on; |
| 445 | + Logger.d("Notification set"); |
| 446 | + } catch (Exception ex) { |
| 447 | + ex.printStackTrace(); |
| 448 | + } |
| 449 | + |
| 450 | + |
| 451 | + } |
| 452 | + |
| 453 | + public void cancelNotification() { |
| 454 | + mNotifyMgr.cancel(nowPlayingNotificationId); |
| 455 | + notificationStatus = NOTIFICATION_STATUS.off; |
| 456 | + } |
413 | 457 |
|
| 458 | + public NOTIFICATION_STATUS getNotificationStatus() { |
| 459 | + return notificationStatus; |
414 | 460 | }
|
415 | 461 |
|
416 | 462 | private RemoteViews getNotificationView(int layoutId, Bitmap thumb, PlexMedia media, PlexClient client,
|
|
0 commit comments