diff options
author | lado <herrlado@gmail.com> | 2017-11-03 00:25:44 +0100 |
---|---|---|
committer | lado <herrlado@gmail.com> | 2017-11-03 00:25:44 +0100 |
commit | 2692564bfe18978ceb2b5fa4e9237113ae300176 (patch) | |
tree | 77e010a23721481ee51143a7bf7393dd74d4a7d6 /vdrmanager/de.bjusystems.vdrmanager/src/main/java/de | |
parent | e044aed11d8982398fa556eacde9af1003af1c5a (diff) | |
download | vdr-manager-2692564bfe18978ceb2b5fa4e9237113ae300176.tar.gz vdr-manager-2692564bfe18978ceb2b5fa4e9237113ae300176.tar.bz2 |
curretnlado
Diffstat (limited to 'vdrmanager/de.bjusystems.vdrmanager/src/main/java/de')
7 files changed, 1373 insertions, 1148 deletions
diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/app/VdrManagerApp.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/app/VdrManagerApp.java index 0d4f54c..ac0ff44 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/app/VdrManagerApp.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/app/VdrManagerApp.java @@ -2,6 +2,12 @@ package de.bjusystems.vdrmanager.app; import android.app.Activity; import android.app.Application; + +import java.security.KeyStore; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.EpgSearchParams; import de.bjusystems.vdrmanager.data.Event; @@ -9,11 +15,6 @@ import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.data.Timer; import de.bjusystems.vdrmanager.data.Vdr; -import java.security.KeyStore; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - public class VdrManagerApp extends Application { diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupActivity.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupActivity.java index ed0da12..4358010 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupActivity.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupActivity.java @@ -21,69 +21,72 @@ import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.widget.Toast; + import de.bjusystems.vdrmanager.R; /** * Activity to backup data to the SD card. - * + * * @author Jimmy Shih */ public class BackupActivity extends Activity { - private static final int DIALOG_PROGRESS_ID = 0; + private static final int DIALOG_PROGRESS_ID = 0; + + + private BackupAsyncTask backupAsyncTask; - private BackupAsyncTask backupAsyncTask; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - Object retained = getLastNonConfigurationInstance(); - if (retained instanceof BackupAsyncTask) { - backupAsyncTask = (BackupAsyncTask) retained; - backupAsyncTask.setActivity(this); - } else { - backupAsyncTask = new BackupAsyncTask(this); - backupAsyncTask.execute(); + Object retained = getLastNonConfigurationInstance(); + if (retained instanceof BackupAsyncTask) { + backupAsyncTask = (BackupAsyncTask) retained; + backupAsyncTask.setActivity(this); + } else { + backupAsyncTask = new BackupAsyncTask(this); + backupAsyncTask.execute(); + } } - } - @Override - public Object onRetainNonConfigurationInstance() { - backupAsyncTask.setActivity(null); - return backupAsyncTask; - } + @Override + public Object onRetainNonConfigurationInstance() { + backupAsyncTask.setActivity(null); + return backupAsyncTask; + } - @Override - protected Dialog onCreateDialog(int id) { - if (id != DIALOG_PROGRESS_ID) { - return null; + @Override + protected Dialog onCreateDialog(int id) { + if (id != DIALOG_PROGRESS_ID) { + return null; + } + return DialogUtils.createSpinnerProgressDialog( + this, R.string.settings_backup_now_progress_message, new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + finish(); + } + }); } - return DialogUtils.createSpinnerProgressDialog( - this, R.string.settings_backup_now_progress_message, new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - finish(); - } - }); - } - /** - * Invokes when the associated AsyncTask completes. - * - * @param success true if the AsyncTask is successful - * @param messageId message id to display to user - */ - public void onAsyncTaskCompleted(boolean success, int messageId) { - removeDialog(DIALOG_PROGRESS_ID); - Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show(); - finish(); - } + /** + * Invokes when the associated AsyncTask completes. + * + * @param success true if the AsyncTask is successful + * @param messageId message id to display to user + */ + public void onAsyncTaskCompleted(boolean success, int messageId) { + removeDialog(DIALOG_PROGRESS_ID); + Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show(); + finish(); + } - /** - * Shows the progress dialog. - */ - public void showProgressDialog() { - showDialog(DIALOG_PROGRESS_ID); - } + /** + * Shows the progress dialog. + */ + public void showProgressDialog() { + showDialog(DIALOG_PROGRESS_ID); + } } diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupSettingsActivity.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupSettingsActivity.java index e906a20..680e58a 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupSettingsActivity.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/backup/BackupSettingsActivity.java @@ -17,93 +17,119 @@ package de.bjusystems.vdrmanager.backup; +import android.Manifest; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceManager; +import android.support.v4.content.ContextCompat; +import android.widget.Toast; + import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.gui.Utils; /** * An activity for accessing the backup settings. - * + * * @author Jimmy Shih */ public class BackupSettingsActivity extends AbstractSettingsActivity { - private static final int DIALOG_CONFIRM_RESTORE_ID = 0; + private static final int DIALOG_CONFIRM_RESTORE_ID = 0; + - Preference backupPreference; - Preference restorePreference; + /** + * The Backup preference. + */ + Preference backupPreference; + /** + * The Restore preference. + */ + Preference restorePreference; - /* - * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class. - * Anonymous inner class will get garbage collected. - */ - private final OnSharedPreferenceChangeListener - sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() { + /* + * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class. + * Anonymous inner class will get garbage collected. + */ + private final OnSharedPreferenceChangeListener + sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - // Note that key can be null - //if (PreferencesUtils.getKey(BackupSettingsActivity.this, R.string.recording_track_id_key) + // Note that key can be null + //if (PreferencesUtils.getKey(BackupSettingsActivity.this, R.string.recording_track_id_key) // .equals(key)) { //updateUi(); - //} + //} } - }; - - @SuppressWarnings("deprecation") - @Override - protected void onCreate(Bundle bundle) { - super.onCreate(bundle); - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); - - addPreferencesFromResource(R.xml.backup_settings); - backupPreference = findPreference(getString(R.string.settings_backup_now_key)); - backupPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = IntentUtils.newIntent(BackupSettingsActivity.this, BackupActivity.class); - startActivity(intent); - return true; - } - }); - restorePreference = findPreference(getString(R.string.settings_backup_restore_key)); - restorePreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showDialog(DIALOG_CONFIRM_RESTORE_ID); - return true; - } - }); - } - - @Override - protected Dialog onCreateDialog(int id) { - if (id != DIALOG_CONFIRM_RESTORE_ID) { - return null; - } - return DialogUtils.createConfirmationDialog(this, - R.string.settings_backup_restore_confirm_message, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = IntentUtils.newIntent( - BackupSettingsActivity.this, RestoreChooserActivity.class); - startActivity(intent); - } + }; + + @SuppressWarnings("deprecation") + @Override + protected void onCreate(Bundle bundle) { + super.onCreate(bundle); + + final boolean permissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + + PreferenceManager.getDefaultSharedPreferences(this) + .registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); + + addPreferencesFromResource(R.xml.backup_settings); + backupPreference = findPreference(getString(R.string.settings_backup_now_key)); + backupPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (permissionGranted == false) { + Utils.say(getApplication(), R.string.permission_rationale, Toast.LENGTH_LONG); + return false; + } + Intent intent = IntentUtils.newIntent(BackupSettingsActivity.this, BackupActivity.class); + startActivity(intent); + return true; + } + }); + restorePreference = findPreference(getString(R.string.settings_backup_restore_key)); + restorePreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if (permissionGranted == false) { + Utils.say(getApplication(), R.string.permission_rationale, Toast.LENGTH_LONG); + return false; + } + showDialog(DIALOG_CONFIRM_RESTORE_ID); + return true; + } }); - } - @Override - protected void onResume() { - super.onResume(); - //updateUi(); - } + + } + + @Override + protected Dialog onCreateDialog(int id) { + if (id != DIALOG_CONFIRM_RESTORE_ID) { + return null; + } + return DialogUtils.createConfirmationDialog(this, + R.string.settings_backup_restore_confirm_message, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = IntentUtils.newIntent( + BackupSettingsActivity.this, RestoreChooserActivity.class); + startActivity(intent); + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + //updateUi(); + } // /** // * Updates the UI based on the recording state. diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/PreferencesActivity.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/PreferencesActivity.java index e8ae690..4dce431 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/PreferencesActivity.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/PreferencesActivity.java @@ -10,7 +10,6 @@ import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceManager; import de.bjusystems.vdrmanager.R; -import de.bjusystems.vdrmanager.app.VdrManagerApp; import de.bjusystems.vdrmanager.backup.BackupSettingsActivity; import de.bjusystems.vdrmanager.data.Preferences; diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/Utils.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/Utils.java index d7e262b..a880fcf 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/Utils.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/Utils.java @@ -26,6 +26,7 @@ import android.util.Log; import android.util.Pair; import android.view.Gravity; import android.widget.Toast; + import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.StringUtils; import de.bjusystems.vdrmanager.app.C; @@ -46,731 +47,733 @@ import de.bjusystems.vdrmanager.utils.svdrp.SwitchChannelClient; public class Utils { - public static final String TAG = Utils.class.getName(); - - public static final List EMPTY_LIST = new ArrayList(0); - public static final String[] EMPTY = new String[] {}; - public static final ForegroundColorSpan HIGHLIGHT_TEXT = new ForegroundColorSpan( - - Color.RED); - - public static CharSequence highlight(final String where, String what) { - if (TextUtils.isEmpty(what)) { - return where; - } - - final String str = where.toLowerCase(); - what = what.toLowerCase(); - final int idx = str.indexOf(what); - if (idx == -1) { - return where; - } - final SpannableString ss = new SpannableString(where); - ss.setSpan(HIGHLIGHT_TEXT, idx, idx + what.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - return ss; - } - - public static Pair<Boolean, CharSequence> highlight2(final String where, - String what) { - if (TextUtils.isEmpty(what)) { - return Pair.create(Boolean.FALSE, (CharSequence) where); - } - - final String str = where.toLowerCase(); - what = what.toLowerCase(); - final int idx = str.indexOf(what); - if (idx == -1) { - return Pair.create(Boolean.FALSE, (CharSequence) where); - } - final SpannableString ss = new SpannableString(where); - ss.setSpan(HIGHLIGHT_TEXT, idx, idx + what.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - return Pair.create(Boolean.TRUE, (CharSequence) ss); - } - - public static int getProgress(final Date start, final Date stop) { - final long now = System.currentTimeMillis(); - return getProgress(now, start.getTime(), stop.getTime()); - } - - public static int getProgress(final Event e) { - if (e instanceof Recording == false) { - return getProgress(e.getStart(), e.getStop()); - } - final Recording r = ((Recording) e); - if (r.getTimerStopTime() == null) { - return getProgress(e.getStart(), e.getStop()); - } - return getProgress(r.getStart(), r.getTimerStopTime()); - - } - - /** - * @param now - * @param time - * @param time2 - * @return -1, is not not between start stop, - */ - private static int getProgress(final long now, final long start, - final long stop) { - if (now >= start && now <= stop) { - final long dura = stop - start; - final long prog = now - start; - return (int) (prog * 100 / dura); - } - return -1; - } - - public static boolean isLive(final Event event) { - final long now = System.currentTimeMillis(); - return now >= event.getStart().getTime() - && now <= event.getStop().getTime(); - } - - private static String trimToEmpty(final String str) { - if (str == null) { - return ""; - } - if (TextUtils.isEmpty(str)) { - return ""; - } - return str; - } - - private static String getBaseUrl() { - final StringBuilder sb = new StringBuilder(); - final Preferences p = Preferences.get(); - String auth = trimToEmpty(p.getStreamingUsername()) + ":" - + trimToEmpty(p.getStreamingPassword()); - if (auth.length() == 1) { - auth = ""; - } else { - auth += "@"; - } - - sb.append("http://").append(auth).append(p.getHost()).append(":") - .append(p.getStreamPort()); - return sb.toString(); - } - - private static String getStreamUrl(final String chn) { - // "http://192.168.1.119:3000/TS/" - final Preferences p = Preferences.get(); - final StringBuilder sb = new StringBuilder(); - sb.append(getBaseUrl()).append("/").append(p.getStreamFormat()) - .append("/").append(chn); - - return sb.toString(); - } - - private static String getRemuxStreamUrl(final String chn) { - // "http://192.168.1.119:3000/TS/" - final StringBuilder sb = new StringBuilder(); - final Preferences p = Preferences.get(); - sb.append(getBaseUrl()).append("/").append(p.getRemuxCommand()) - .append(";").append(p.getRemuxParameter()).append("/") - .append(chn); - return sb.toString(); - } - - public static void stream(final Activity activity, final Event event) { - stream(activity, event.getStreamId()); - } - - public static void stream(final Activity activity, final Channel channel) { - stream(activity, channel.getId()); - } - - public static void stream(final Activity activity, final String idornr) { - - if (Preferences.get().isEnableRemux() == false) { - final String url = getStreamUrl(idornr); - startStream(activity, url); - return; - } - - final String sf = Preferences.get().getStreamFormat(); - final String ext = activity.getString(R.string.remux_title); - new AlertDialog.Builder(activity) - .setTitle(R.string.stream_via_as) - // - .setItems( - new String[] { - activity.getString(R.string.stream_as, sf), - activity.getString(R.string.stream_via, ext) },// TODO - // add - // here - // what - // will - // be - // used - new DialogInterface.OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, - final int which) { - String url = null; - switch (which) { - case 0: - url = getStreamUrl(idornr); - break; - case 1: - url = getRemuxStreamUrl(idornr); - break; - } - startStream(activity, url); - } - }).create().show(); - } - - public static void startStream(final Activity activity, final String url) { - try { - final Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(Uri.parse(url.toString()), "video/*"); - activity.startActivityForResult(intent, 1); - } catch (final ActivityNotFoundException anfe) { - Log.w(TAG, anfe); - Toast.makeText(activity, anfe.getLocalizedMessage(), - Toast.LENGTH_SHORT).show(); - } - } - - public static final String md5(final String s) { - try { - // Create MD5 Hash - final MessageDigest digest = java.security.MessageDigest - .getInstance("MD5"); - digest.update(s.getBytes()); - final byte messageDigest[] = digest.digest(); - - // Create Hex String - final StringBuffer hexString = new StringBuffer(); - for (int i = 0; i < messageDigest.length; i++) { - String h = Integer.toHexString(0xFF & messageDigest[i]); - while (h.length() < 2) { - h = "0" + h; - } - hexString.append(h); - } - return hexString.toString(); - - } catch (final NoSuchAlgorithmException e) { - Log.w(TAG, e); - } - return ""; - } - - public static int getDuration(final Event event) { - final long millis = event.getDuration(); - final int minuts = (int) (millis / 1000 / 60); - return minuts; - } - - public static void shareEvent(final Activity activity, final Event event) { - final Intent share = new Intent(android.content.Intent.ACTION_SEND); - share.setType("text/plain"); - StringBuilder sb = new StringBuilder(); - sb.append(event.getTitle()); - sb.append("\n"); - final EventFormatter ef = new EventFormatter(event, false); - sb.append(ef.getDate()).append(" ").append(ef.getTime()); - final String title = sb.toString(); - share.putExtra(android.content.Intent.EXTRA_SUBJECT, sb.toString()); - sb = new StringBuilder(); - sb.append(title).append("\n\n"); - sb.append(event.getChannelNumber() + " " + event.getChannelName()); - sb.append("\n\n"); - sb.append(ef.getShortText()); - sb.append("\n\n"); - sb.append(ef.getDescription()); - sb.append("\n"); - share.putExtra(android.content.Intent.EXTRA_TEXT, sb.toString()); - activity.startActivity(Intent.createChooser(share, - activity.getString(R.string.share_chooser))); - } - - public static void addCalendarEvent(final Activity activity, - final Event event) { - final Intent intent = new Intent(Intent.ACTION_EDIT); - intent.setType("vnd.android.cursor.item/event"); - intent.putExtra("title", event.getTitle()); - intent.putExtra("description", event.getShortText()); - intent.putExtra("beginTime", event.getStart().getTime()); - intent.putExtra("endTime", event.getStop().getTime()); - activity.startActivity(intent); - } - - public static String mapSpecialChars(final String src) { - if (src == null) { - return ""; - } - return src.replace("|##", C.DATA_SEPARATOR).replace("||#", "\n"); - } - - public static String unMapSpecialChars(final String src) { - if (src == null) { - return ""; - } - return src.replace(C.DATA_SEPARATOR, "|##").replace("\n", "||#"); - } - - public static PackageInfo getPackageInfo(final Context ctx) { - PackageInfo pi = null; - try { - pi = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), - PackageManager.GET_ACTIVITIES); - } catch (final PackageManager.NameNotFoundException e) { - e.printStackTrace(); - } - return pi; - } - - public static boolean checkInternetConnection(final Context ctx) { - final ConnectivityManager cm = (ConnectivityManager) ctx - .getSystemService(Context.CONNECTIVITY_SERVICE); - // test for connection - if (cm.getActiveNetworkInfo() != null - && cm.getActiveNetworkInfo().isConnectedOrConnecting()) { - return true; - } - return false; - } - - private static String getRecordingStream(final Activity ctx, - final Recording rec) { - - - Preferences prefs = Preferences.get(); - - final String m = prefs.getRecStreamMethod(); - - final StringBuilder url = new StringBuilder(); - - if (StringUtils.equals(m, "vdr-live")) { - url.append("http://") - .append(prefs.getHost()) - // - .append(":") - .append(Integer.valueOf(prefs.getLivePort())) - // - .append("/recstream.html?recid=recording_") - .append(Utils.md5(rec.getFileName())); - // http://192.168.1.119:8008/b0cdedeed2d36508dfd924f0876a851b - final String urlstring = url.toString(); - return urlstring; - } else if (StringUtils.equals(m, "vdr-streamdev")) { - url.append("http://").append(prefs.getHost()) - // - .append(":") - .append(Integer.valueOf( - prefs.getStreamPort())) - // - .append("/").append(rec.getDevInode()); - } else if (StringUtils.equals(m, "vdr-smarttvweb")) { - - String type = prefs.getSmarttvewebType(); - - url.append("http://") - .append(prefs.getHost()) - // - .append(":") - .append(Integer.valueOf(prefs - .getSmarttvewebPort())) - // - .append(Utils.encodeUrlPath(rec.getFileName())); - if (StringUtils.equals(type, "has") == true) { - url.append("/manifest-seg.mpd"); - } else if (StringUtils.equals(type, "hls")) { - url.append("/manifest-seg.m3u8"); - } - } - return url.toString(); - } - - public static void streamRecording(final Activity ctx, final Recording rec) { - final String urlstring = getRecordingStream(ctx, rec); - Log.d(TAG, "try stream: " + urlstring); - Utils.startStream(ctx, urlstring); - } - - public static void switchTo(final Activity activity, final Channel channel) { - switchTo(activity, channel.getId(), channel.getName()); - } - - /** - * @param ctx - * @param id - * @param name - * Optional für die Anzeige - */ - public static void switchTo(final Activity activity, final String id, - final String name) { - - final SwitchChannelClient scc = new SwitchChannelClient(id, - new CertificateProblemDialog(activity)); - final SvdrpAsyncTask<String, SwitchChannelClient> task = new SvdrpAsyncTask<String, SwitchChannelClient>( - scc); - task.addSvdrpListener(new SvdrpListener() { - @Override - public void svdrpEvent(final SvdrpEvent event) { - if (event == SvdrpEvent.FINISHED_SUCCESS) { - Utils.say(activity, activity.getString( - R.string.switching_success, (name != null ? name - : id))); - } else if (event == SvdrpEvent.CONNECT_ERROR - || event == SvdrpEvent.FINISHED_ABNORMALY - || event == SvdrpEvent.ABORTED - || event == SvdrpEvent.ERROR - || event == SvdrpEvent.CACHE_HIT) { - Utils.say(activity, activity.getString( - R.string.switching_failed, (name != null ? name - : id), event.name())); - } - } - - public void svdrpException(final SvdrpException e) { - Log.w(TAG, e.getMessage(), e); - Utils.say(activity, e.getMessage()); - } - }); - task.run(); - } - - public static void say(final Context ctx, final String msg) { - final Toast t = Toast.makeText(ctx, msg, Toast.LENGTH_SHORT); - t.setGravity(Gravity.CENTER, 0, 0); - t.show(); - } - public static String encodeUrlPath(String path){ - return path.replaceAll("%", "%25"); - } - - public static void say(final Context ctx, final int msg) { - final Toast t = Toast.makeText(ctx, msg, Toast.LENGTH_SHORT); - t.setGravity(Gravity.CENTER, 0, 0); - t.show(); - } - - /** - * Formats the date and time based on user's phone date/time preferences. - * - * @param context - * the context - * @param time - * the time in milliseconds - */ - - public static String formatDateTime(final Context context, final long time) { - return android.text.format.DateFormat.getDateFormat(context).format( - time) - + " " - + DateUtils.formatDateTime(context, time, - DateUtils.FORMAT_SHOW_TIME).toString(); - } - - public static int getTimerStateDrawable(final TimerMatch match, - final int full, final int begin, final int end, final int conflict) { - - switch (match) { - case Begin: - return begin; - case End: - return end; - case Conflict: - return conflict; - default: - return full; - } - } - - public static String formatAudio(final Context context, - final List<AudioTrack> tracks) { - - final StringBuilder sb = new StringBuilder(); - - String sep = ""; - for (final AudioTrack a : tracks) { - sb.append(sep).append(a.display); - if (a.type.equals("d")) { - sb.append(" (") - .append(context.getString(R.string.audio_track_dolby)) - .append(")"); - } - sep = ", "; - } - return sb.toString(); - - } - - public static TimerMatch getTimerMatch(Event event, Timer timer) { - if (timer == null) { - return null; - } - TimerMatch timerMatch = null; - Date start = event.getStart(); - Date stop = event.getStop(); - if (start.before(timer.getStart())) { - timerMatch = TimerMatch.End; - } else if (stop.after(timer.getStop())) { - timerMatch = TimerMatch.Begin; - } else { - timerMatch = TimerMatch.Full; - } - return timerMatch; - } - - public static int contentToString(int c) { - ; - switch (c & 0xF0) { - case EventContentGroup.MovieDrama: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Movie__Drama; - case 0x01: - return R.string.Content_Detective__Thriller; - case 0x02: - return R.string.Content_Adventure__Western__War; - case 0x03: - return R.string.Content_Science_Fiction__Fantasy__Horror; - case 0x04: - return R.string.Content_Comedy; - case 0x05: - return R.string.Content_Soap__Melodrama__Folkloric; - case 0x06: - return R.string.Content_Romance; - case 0x07: - return R.string.Content_Serious__Classical__Religious__Historical_Movie__Drama; - case 0x08: - return R.string.Content_Adult_Movie__Drama; - } - case EventContentGroup.NewsCurrentAffairs: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_News__Current_Affairs; - case 0x01: - return R.string.Content_News__Weather_Report; - case 0x02: - return R.string.Content_News_Magazine; - case 0x03: - return R.string.Content_Documentary; - case 0x04: - return R.string.Content_Discussion__Inverview__Debate; - } - - case EventContentGroup.Show: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Show__Game_Show; - case 0x01: - return R.string.Content_Game_Show__Quiz__Contest; - case 0x02: - return R.string.Content_Variety_Show; - case 0x03: - return R.string.Content_Talk_Show; - } - - case EventContentGroup.Sports: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Sports; - case 0x01: - return R.string.Content_Special_Event; - case 0x02: - return R.string.Content_Sport_Magazine; - case 0x03: - return R.string.Content_Football__Soccer; - case 0x04: - return R.string.Content_Tennis__Squash; - case 0x05: - return R.string.Content_Team_Sports; - case 0x06: - return R.string.Content_Athletics; - case 0x07: - return R.string.Content_Motor_Sport; - case 0x08: - return R.string.Content_Water_Sport; - case 0x09: - return R.string.Content_Winter_Sports; - case 0x0A: - return R.string.Content_Equestrian; - case 0x0B: - return R.string.Content_Martial_Sports; - } - - case EventContentGroup.ChildrenYouth: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Childrens__Youth_Programme; - case 0x01: - return R.string.Content_Preschool_Childrens_Programme; - case 0x02: - return R.string.Content_Entertainment_Programme_for_6_to_14; - case 0x03: - return R.string.Content_Entertainment_Programme_for_10_to_16; - case 0x04: - return R.string.Content_Informational__Educational__School_Programme; - case 0x05: - return R.string.Content_Cartoons__Puppets; - } - - case EventContentGroup.MusicBalletDance: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Music__Ballet__Dance; - case 0x01: - return R.string.Content_Rock__Pop; - case 0x02: - return R.string.Content_Serious__Classical_Music; - case 0x03: - return R.string.Content_Folk__Tradional_Music; - case 0x04: - return R.string.Content_Jazz; - case 0x05: - return R.string.Content_Musical__Opera; - case 0x06: - return R.string.Content_Ballet; - } - - case EventContentGroup.ArtsCulture: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Arts__Culture; - case 0x01: - return R.string.Content_Performing_Arts; - case 0x02: - return R.string.Content_Fine_Arts; - case 0x03: - return R.string.Content_Religion; - case 0x04: - return R.string.Content_Popular_Culture__Traditional_Arts; - case 0x05: - return R.string.Content_Literature; - case 0x06: - return R.string.Content_Film__Cinema; - case 0x07: - return R.string.Content_Experimental_Film__Video; - case 0x08: - return R.string.Content_Broadcasting__Press; - case 0x09: - return R.string.Content_New_Media; - case 0x0A: - return R.string.Content_Arts__Culture_Magazine; - case 0x0B: - return R.string.Content_Fashion; - } - - case EventContentGroup.SocialPoliticalEconomics: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Social__Political__Economics; - case 0x01: - return R.string.Content_Magazine__Report__Documentary; - case 0x02: - return R.string.Content_Economics__Social_Advisory; - case 0x03: - return R.string.Content_Remarkable_People; - } - - case EventContentGroup.EducationalScience: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Education__Science__Factual; - case 0x01: - return R.string.Content_Nature__Animals__Environment; - case 0x02: - return R.string.Content_Technology__Natural_Sciences; - case 0x03: - return R.string.Content_Medicine__Physiology__Psychology; - case 0x04: - return R.string.Content_Foreign_Countries__Expeditions; - case 0x05: - return R.string.Content_Social__Spiritual_Sciences; - case 0x06: - return R.string.Content_Further_Education; - case 0x07: - return R.string.Content_Languages; - } - - case EventContentGroup.LeisureHobbies: - switch (c & 0x0F) { - default: - case 0x00: - return R.string.Content_Leisure__Hobbies; - case 0x01: - return R.string.Content_Tourism__Travel; - case 0x02: - return R.string.Content_Handicraft; - case 0x03: - return R.string.Content_Motoring; - case 0x04: - return R.string.Content_Fitness_and_Health; - case 0x05: - return R.string.Content_Cooking; - case 0x06: - return R.string.Content_Advertisement__Shopping; - case 0x07: - return R.string.Content_Gardening; - } - case EventContentGroup.Special: - switch (c & 0x0F) { - case 0x00: - return R.string.Content_Original_Language; - case 0x01: - return R.string.Content_Black_and_White; - case 0x02: - return R.string.Content_Unpublished; - case 0x03: - return R.string.Content_Live_Broadcast; - default: - ; - } - break; - default: - ; - } - return R.string.Content_Unknown; - } - - public static String getContenString(Context ctx, int[] contents) { - - if (contents.length == 0) { - return ""; - } - - StringBuilder sb = new StringBuilder(); - - String sep = ""; - - for (int content : contents) { - - sb.append(sep).append(ctx.getString(contentToString(content))); - sep = ", "; - } - - return sb.toString(); - } - - public static boolean isSerie(int[] contents) { - if (contents.length == 0) { - return false; - } - - for (int c : contents) { - if (c == 21) { - return true; - - } - } - - return false; - } + public static final String TAG = Utils.class.getName(); + + public static final List EMPTY_LIST = new ArrayList(0); + public static final String[] EMPTY = new String[]{}; + public static final ForegroundColorSpan HIGHLIGHT_TEXT = new ForegroundColorSpan( + + Color.RED); + + public static CharSequence highlight(final String where, String what) { + if (TextUtils.isEmpty(what)) { + return where; + } + + final String str = where.toLowerCase(); + what = what.toLowerCase(); + final int idx = str.indexOf(what); + if (idx == -1) { + return where; + } + final SpannableString ss = new SpannableString(where); + ss.setSpan(HIGHLIGHT_TEXT, idx, idx + what.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return ss; + } + + public static Pair<Boolean, CharSequence> highlight2(final String where, + String what) { + if (TextUtils.isEmpty(what)) { + return Pair.create(Boolean.FALSE, (CharSequence) where); + } + + final String str = where.toLowerCase(); + what = what.toLowerCase(); + final int idx = str.indexOf(what); + if (idx == -1) { + return Pair.create(Boolean.FALSE, (CharSequence) where); + } + final SpannableString ss = new SpannableString(where); + ss.setSpan(HIGHLIGHT_TEXT, idx, idx + what.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return Pair.create(Boolean.TRUE, (CharSequence) ss); + } + + public static int getProgress(final Date start, final Date stop) { + final long now = System.currentTimeMillis(); + return getProgress(now, start.getTime(), stop.getTime()); + } + + public static int getProgress(final Event e) { + if (e instanceof Recording == false) { + return getProgress(e.getStart(), e.getStop()); + } + final Recording r = ((Recording) e); + if (r.getTimerStopTime() == null) { + return getProgress(e.getStart(), e.getStop()); + } + return getProgress(r.getStart(), r.getTimerStopTime()); + + } + + /** + * @param now + * @param time + * @param time2 + * @return -1, is not not between start stop, + */ + private static int getProgress(final long now, final long start, + final long stop) { + if (now >= start && now <= stop) { + final long dura = stop - start; + final long prog = now - start; + return (int) (prog * 100 / dura); + } + return -1; + } + + public static boolean isLive(final Event event) { + final long now = System.currentTimeMillis(); + return now >= event.getStart().getTime() + && now <= event.getStop().getTime(); + } + + private static String trimToEmpty(final String str) { + if (str == null) { + return ""; + } + if (TextUtils.isEmpty(str)) { + return ""; + } + return str; + } + + private static String getBaseUrl() { + final StringBuilder sb = new StringBuilder(); + final Preferences p = Preferences.get(); + String auth = trimToEmpty(p.getStreamingUsername()) + ":" + + trimToEmpty(p.getStreamingPassword()); + if (auth.length() == 1) { + auth = ""; + } else { + auth += "@"; + } + + sb.append("http://").append(auth).append(p.getHost()).append(":") + .append(p.getStreamPort()); + return sb.toString(); + } + + private static String getStreamUrl(final String chn) { + // "http://192.168.1.119:3000/TS/" + final Preferences p = Preferences.get(); + final StringBuilder sb = new StringBuilder(); + sb.append(getBaseUrl()).append("/").append(p.getStreamFormat()) + .append("/").append(chn); + + return sb.toString(); + } + + private static String getRemuxStreamUrl(final String chn) { + // "http://192.168.1.119:3000/TS/" + final StringBuilder sb = new StringBuilder(); + final Preferences p = Preferences.get(); + sb.append(getBaseUrl()).append("/").append(p.getRemuxCommand()) + .append(";").append(p.getRemuxParameter()).append("/") + .append(chn); + return sb.toString(); + } + + public static void stream(final Activity activity, final Event event) { + stream(activity, event.getStreamId()); + } + + public static void stream(final Activity activity, final Channel channel) { + stream(activity, channel.getId()); + } + + public static void stream(final Activity activity, final String idornr) { + + if (Preferences.get().isEnableRemux() == false) { + final String url = getStreamUrl(idornr); + startStream(activity, url); + return; + } + + final String sf = Preferences.get().getStreamFormat(); + final String ext = activity.getString(R.string.remux_title); + new AlertDialog.Builder(activity) + .setTitle(R.string.stream_via_as) + // + .setItems( + new String[]{ + activity.getString(R.string.stream_as, sf), + activity.getString(R.string.stream_via, ext)},// TODO + // add + // here + // what + // will + // be + // used + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, + final int which) { + String url = null; + switch (which) { + case 0: + url = getStreamUrl(idornr); + break; + case 1: + url = getRemuxStreamUrl(idornr); + break; + } + startStream(activity, url); + } + }).create().show(); + } + + public static void startStream(final Activity activity, final String url) { + try { + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.parse(url.toString()), "video/*"); + activity.startActivityForResult(intent, 1); + } catch (final ActivityNotFoundException anfe) { + Log.w(TAG, anfe); + Toast.makeText(activity, anfe.getLocalizedMessage(), + Toast.LENGTH_SHORT).show(); + } + } + + public static final String md5(final String s) { + try { + // Create MD5 Hash + final MessageDigest digest = java.security.MessageDigest + .getInstance("MD5"); + digest.update(s.getBytes()); + final byte messageDigest[] = digest.digest(); + + // Create Hex String + final StringBuffer hexString = new StringBuffer(); + for (int i = 0; i < messageDigest.length; i++) { + String h = Integer.toHexString(0xFF & messageDigest[i]); + while (h.length() < 2) { + h = "0" + h; + } + hexString.append(h); + } + return hexString.toString(); + + } catch (final NoSuchAlgorithmException e) { + Log.w(TAG, e); + } + return ""; + } + + public static int getDuration(final Event event) { + final long millis = event.getDuration(); + final int minuts = (int) (millis / 1000 / 60); + return minuts; + } + + public static void shareEvent(final Activity activity, final Event event) { + final Intent share = new Intent(android.content.Intent.ACTION_SEND); + share.setType("text/plain"); + StringBuilder sb = new StringBuilder(); + sb.append(event.getTitle()); + sb.append("\n"); + final EventFormatter ef = new EventFormatter(event, false); + sb.append(ef.getDate()).append(" ").append(ef.getTime()); + final String title = sb.toString(); + share.putExtra(android.content.Intent.EXTRA_SUBJECT, sb.toString()); + sb = new StringBuilder(); + sb.append(title).append("\n\n"); + sb.append(event.getChannelNumber() + " " + event.getChannelName()); + sb.append("\n\n"); + sb.append(ef.getShortText()); + sb.append("\n\n"); + sb.append(ef.getDescription()); + sb.append("\n"); + share.putExtra(android.content.Intent.EXTRA_TEXT, sb.toString()); + activity.startActivity(Intent.createChooser(share, + activity.getString(R.string.share_chooser))); + } + + public static void addCalendarEvent(final Activity activity, + final Event event) { + final Intent intent = new Intent(Intent.ACTION_EDIT); + intent.setType("vnd.android.cursor.item/event"); + intent.putExtra("title", event.getTitle()); + intent.putExtra("description", event.getShortText()); + intent.putExtra("beginTime", event.getStart().getTime()); + intent.putExtra("endTime", event.getStop().getTime()); + activity.startActivity(intent); + } + + public static String mapSpecialChars(final String src) { + if (src == null) { + return ""; + } + return src.replace("|##", C.DATA_SEPARATOR).replace("||#", "\n"); + } + + public static String unMapSpecialChars(final String src) { + if (src == null) { + return ""; + } + return src.replace(C.DATA_SEPARATOR, "|##").replace("\n", "||#"); + } + + public static PackageInfo getPackageInfo(final Context ctx) { + PackageInfo pi = null; + try { + pi = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), + PackageManager.GET_ACTIVITIES); + } catch (final PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return pi; + } + + public static boolean checkInternetConnection(final Context ctx) { + final ConnectivityManager cm = (ConnectivityManager) ctx + .getSystemService(Context.CONNECTIVITY_SERVICE); + // test for connection + if (cm.getActiveNetworkInfo() != null + && cm.getActiveNetworkInfo().isConnectedOrConnecting()) { + return true; + } + return false; + } + + private static String getRecordingStream(final Activity ctx, + final Recording rec) { + + + Preferences prefs = Preferences.get(); + + final String m = prefs.getRecStreamMethod(); + + final StringBuilder url = new StringBuilder(); + + if (StringUtils.equals(m, "vdr-live")) { + url.append("http://") + .append(prefs.getHost()) + // + .append(":") + .append(Integer.valueOf(prefs.getLivePort())) + // + .append("/recstream.html?recid=recording_") + .append(Utils.md5(rec.getFileName())); + // http://192.168.1.119:8008/b0cdedeed2d36508dfd924f0876a851b + final String urlstring = url.toString(); + return urlstring; + } else if (StringUtils.equals(m, "vdr-streamdev")) { + url.append("http://").append(prefs.getHost()) + // + .append(":") + .append(Integer.valueOf( + prefs.getStreamPort())) + // + .append("/").append(rec.getDevInode()); + } else if (StringUtils.equals(m, "vdr-smarttvweb")) { + + String type = prefs.getSmarttvewebType(); + + url.append("http://") + .append(prefs.getHost()) + // + .append(":") + .append(Integer.valueOf(prefs + .getSmarttvewebPort())) + // + .append(Utils.encodeUrlPath(rec.getFileName())); + if (StringUtils.equals(type, "has") == true) { + url.append("/manifest-seg.mpd"); + } else if (StringUtils.equals(type, "hls")) { + url.append("/manifest-seg.m3u8"); + } + } + return url.toString(); + } + + public static void streamRecording(final Activity ctx, final Recording rec) { + final String urlstring = getRecordingStream(ctx, rec); + Log.d(TAG, "try stream: " + urlstring); + Utils.startStream(ctx, urlstring); + } + + public static void switchTo(final Activity activity, final Channel channel) { + switchTo(activity, channel.getId(), channel.getName()); + } + + /** + * @param ctx + * @param id + * @param name Optional für die Anzeige + */ + public static void switchTo(final Activity activity, final String id, + final String name) { + + final SwitchChannelClient scc = new SwitchChannelClient(id, + new CertificateProblemDialog(activity)); + final SvdrpAsyncTask<String, SwitchChannelClient> task = new SvdrpAsyncTask<String, SwitchChannelClient>( + scc); + task.addSvdrpListener(new SvdrpListener() { + @Override + public void svdrpEvent(final SvdrpEvent event) { + if (event == SvdrpEvent.FINISHED_SUCCESS) { + Utils.say(activity, activity.getString( + R.string.switching_success, (name != null ? name + : id))); + } else if (event == SvdrpEvent.CONNECT_ERROR + || event == SvdrpEvent.FINISHED_ABNORMALY + || event == SvdrpEvent.ABORTED + || event == SvdrpEvent.ERROR + || event == SvdrpEvent.CACHE_HIT) { + Utils.say(activity, activity.getString( + R.string.switching_failed, (name != null ? name + : id), event.name())); + } + } + + public void svdrpException(final SvdrpException e) { + Log.w(TAG, e.getMessage(), e); + Utils.say(activity, e.getMessage()); + } + }); + task.run(); + } + + public static void say(final Context ctx, final String msg) { + final Toast t = Toast.makeText(ctx, msg, Toast.LENGTH_SHORT); + t.setGravity(Gravity.CENTER, 0, 0); + t.show(); + } + + public static String encodeUrlPath(String path) { + return path.replaceAll("%", "%25"); + } + + public static void say(final Context ctx, final int msg) { + say(ctx, msg, Toast.LENGTH_SHORT); + } + + public static void say(final Context ctx, final int msg, final int duration) { + final Toast t = Toast.makeText(ctx, msg, duration); + t.setGravity(Gravity.CENTER, 0, 0); + t.show(); + } + + /** + * Formats the date and time based on user's phone date/time preferences. + * + * @param context the context + * @param time the time in milliseconds + */ + + public static String formatDateTime(final Context context, final long time) { + return android.text.format.DateFormat.getDateFormat(context).format( + time) + + " " + + DateUtils.formatDateTime(context, time, + DateUtils.FORMAT_SHOW_TIME).toString(); + } + + public static int getTimerStateDrawable(final TimerMatch match, + final int full, final int begin, final int end, final int conflict) { + + switch (match) { + case Begin: + return begin; + case End: + return end; + case Conflict: + return conflict; + default: + return full; + } + } + + public static String formatAudio(final Context context, + final List<AudioTrack> tracks) { + + final StringBuilder sb = new StringBuilder(); + + String sep = ""; + for (final AudioTrack a : tracks) { + sb.append(sep).append(a.display); + if (a.type.equals("d")) { + sb.append(" (") + .append(context.getString(R.string.audio_track_dolby)) + .append(")"); + } + sep = ", "; + } + return sb.toString(); + + } + + public static TimerMatch getTimerMatch(Event event, Timer timer) { + if (timer == null) { + return null; + } + TimerMatch timerMatch = null; + Date start = event.getStart(); + Date stop = event.getStop(); + if (start.before(timer.getStart())) { + timerMatch = TimerMatch.End; + } else if (stop.after(timer.getStop())) { + timerMatch = TimerMatch.Begin; + } else { + timerMatch = TimerMatch.Full; + } + return timerMatch; + } + + public static int contentToString(int c) { + ; + switch (c & 0xF0) { + case EventContentGroup.MovieDrama: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Movie__Drama; + case 0x01: + return R.string.Content_Detective__Thriller; + case 0x02: + return R.string.Content_Adventure__Western__War; + case 0x03: + return R.string.Content_Science_Fiction__Fantasy__Horror; + case 0x04: + return R.string.Content_Comedy; + case 0x05: + return R.string.Content_Soap__Melodrama__Folkloric; + case 0x06: + return R.string.Content_Romance; + case 0x07: + return R.string.Content_Serious__Classical__Religious__Historical_Movie__Drama; + case 0x08: + return R.string.Content_Adult_Movie__Drama; + } + case EventContentGroup.NewsCurrentAffairs: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_News__Current_Affairs; + case 0x01: + return R.string.Content_News__Weather_Report; + case 0x02: + return R.string.Content_News_Magazine; + case 0x03: + return R.string.Content_Documentary; + case 0x04: + return R.string.Content_Discussion__Inverview__Debate; + } + + case EventContentGroup.Show: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Show__Game_Show; + case 0x01: + return R.string.Content_Game_Show__Quiz__Contest; + case 0x02: + return R.string.Content_Variety_Show; + case 0x03: + return R.string.Content_Talk_Show; + } + + case EventContentGroup.Sports: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Sports; + case 0x01: + return R.string.Content_Special_Event; + case 0x02: + return R.string.Content_Sport_Magazine; + case 0x03: + return R.string.Content_Football__Soccer; + case 0x04: + return R.string.Content_Tennis__Squash; + case 0x05: + return R.string.Content_Team_Sports; + case 0x06: + return R.string.Content_Athletics; + case 0x07: + return R.string.Content_Motor_Sport; + case 0x08: + return R.string.Content_Water_Sport; + case 0x09: + return R.string.Content_Winter_Sports; + case 0x0A: + return R.string.Content_Equestrian; + case 0x0B: + return R.string.Content_Martial_Sports; + } + + case EventContentGroup.ChildrenYouth: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Childrens__Youth_Programme; + case 0x01: + return R.string.Content_Preschool_Childrens_Programme; + case 0x02: + return R.string.Content_Entertainment_Programme_for_6_to_14; + case 0x03: + return R.string.Content_Entertainment_Programme_for_10_to_16; + case 0x04: + return R.string.Content_Informational__Educational__School_Programme; + case 0x05: + return R.string.Content_Cartoons__Puppets; + } + + case EventContentGroup.MusicBalletDance: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Music__Ballet__Dance; + case 0x01: + return R.string.Content_Rock__Pop; + case 0x02: + return R.string.Content_Serious__Classical_Music; + case 0x03: + return R.string.Content_Folk__Tradional_Music; + case 0x04: + return R.string.Content_Jazz; + case 0x05: + return R.string.Content_Musical__Opera; + case 0x06: + return R.string.Content_Ballet; + } + + case EventContentGroup.ArtsCulture: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Arts__Culture; + case 0x01: + return R.string.Content_Performing_Arts; + case 0x02: + return R.string.Content_Fine_Arts; + case 0x03: + return R.string.Content_Religion; + case 0x04: + return R.string.Content_Popular_Culture__Traditional_Arts; + case 0x05: + return R.string.Content_Literature; + case 0x06: + return R.string.Content_Film__Cinema; + case 0x07: + return R.string.Content_Experimental_Film__Video; + case 0x08: + return R.string.Content_Broadcasting__Press; + case 0x09: + return R.string.Content_New_Media; + case 0x0A: + return R.string.Content_Arts__Culture_Magazine; + case 0x0B: + return R.string.Content_Fashion; + } + + case EventContentGroup.SocialPoliticalEconomics: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Social__Political__Economics; + case 0x01: + return R.string.Content_Magazine__Report__Documentary; + case 0x02: + return R.string.Content_Economics__Social_Advisory; + case 0x03: + return R.string.Content_Remarkable_People; + } + + case EventContentGroup.EducationalScience: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Education__Science__Factual; + case 0x01: + return R.string.Content_Nature__Animals__Environment; + case 0x02: + return R.string.Content_Technology__Natural_Sciences; + case 0x03: + return R.string.Content_Medicine__Physiology__Psychology; + case 0x04: + return R.string.Content_Foreign_Countries__Expeditions; + case 0x05: + return R.string.Content_Social__Spiritual_Sciences; + case 0x06: + return R.string.Content_Further_Education; + case 0x07: + return R.string.Content_Languages; + } + + case EventContentGroup.LeisureHobbies: + switch (c & 0x0F) { + default: + case 0x00: + return R.string.Content_Leisure__Hobbies; + case 0x01: + return R.string.Content_Tourism__Travel; + case 0x02: + return R.string.Content_Handicraft; + case 0x03: + return R.string.Content_Motoring; + case 0x04: + return R.string.Content_Fitness_and_Health; + case 0x05: + return R.string.Content_Cooking; + case 0x06: + return R.string.Content_Advertisement__Shopping; + case 0x07: + return R.string.Content_Gardening; + } + case EventContentGroup.Special: + switch (c & 0x0F) { + case 0x00: + return R.string.Content_Original_Language; + case 0x01: + return R.string.Content_Black_and_White; + case 0x02: + return R.string.Content_Unpublished; + case 0x03: + return R.string.Content_Live_Broadcast; + default: + ; + } + break; + default: + ; + } + return R.string.Content_Unknown; + } + + public static String getContenString(Context ctx, int[] contents) { + + if (contents.length == 0) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + + String sep = ""; + + for (int content : contents) { + + sb.append(sep).append(ctx.getString(contentToString(content))); + sep = ", "; + } + + return sb.toString(); + } + + public static boolean isSerie(int[] contents) { + if (contents.length == 0) { + return false; + } + + for (int c : contents) { + if (c == 21) { + return true; + + } + } + + return false; + } } diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java index 729d75c..8f3c68c 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java @@ -1,16 +1,22 @@ package de.bjusystems.vdrmanager.gui; +import android.Manifest; +import android.annotation.TargetApi; import android.app.AlertDialog; import android.app.SearchManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.provider.SearchRecentSuggestions; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v4.view.MenuItemCompat; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView.OnQueryTextListener; import android.util.Log; @@ -33,309 +39,350 @@ import de.bjusystems.vdrmanager.data.db.EPGSearchSuggestionsProvider; import de.bjusystems.vdrmanager.remote.RemoteActivity; import de.bjusystems.vdrmanager.utils.wakeup.AsyncWakeupTask; -public class VdrManagerActivity extends ActionBarActivity implements - OnClickListener, OnQueryTextListener { +public class VdrManagerActivity extends AppCompatActivity implements + OnClickListener, OnQueryTextListener { - public static final String TAG = "VdrManagerActivity"; + public static final String TAG = "VdrManagerActivity"; - public static final String VDR_PORTAL = "http://www.vdr-portal.de"; + public static final String VDR_PORTAL = "http://www.vdr-portal.de"; - private SearchView search; + private SearchView search; - private View actionMenuWakup; - private View actionMenuRemote; + private View actionMenuWakup; + private View actionMenuRemote; - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + private static final int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 13; - // Preferences.initVDR(this); - // if(Preferences.get().getCurrentVdr() == null){ - // finish(); - // return; - // } android.support.v7.appcompat.R + @TargetApi(Build.VERSION_CODES.M) + private void checkAndRequestPermission() { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + Utils.say(getApplication(), R.string.permission_rationale, Toast.LENGTH_LONG); + } else { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, + MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE); + } + } + } + + + @Override + public void onRequestPermissionsResult(int requestCode, + String permissions[], int[] grantResults) { + switch (requestCode) { + case MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE: { + // If request is cancelled, the result arrays are empty. + if (grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // permission was granted, yay! Do the + } else { + // permission denied, boo! Disable the + // functionality that depends on this permission. + } + return; + } + + // other 'case' lines to check for other + // permissions this app might request + } + } + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - if (Preferences.initVDR(this) == false) { - final Intent intent = new Intent(); - intent.setClass(this, VdrListActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Intents.EMPTY_CONFIG, Boolean.TRUE); - startActivity(intent); - Toast.makeText(this, R.string.no_vdr, Toast.LENGTH_SHORT).show(); - finish(); - return; - } + // Preferences.initVDR(this); - Preferences.setLocale(this); + // if(Preferences.get().getCurrentVdr() == null){ + // finish(); + // return; + // } android.support.v7.appcompat.R - // this.getActionBar().setDisplayShowCustomEnabled(true); - // this.getActionBar().setDisplayShowTitleEnabled(false); - // setTitle(getString(R.string.app_name)); - // attach view - setContentView(R.layout.vdrmanager); - // Preferences.loadPreferences(this); + if (Preferences.initVDR(this) == false) { + final Intent intent = new Intent(); + intent.setClass(this, VdrListActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(Intents.EMPTY_CONFIG, Boolean.TRUE); + startActivity(intent); + Toast.makeText(this, R.string.no_vdr, Toast.LENGTH_SHORT).show(); + finish(); + return; + } - findViewById(R.id.action_menu_channels).setOnClickListener(this); - findViewById(R.id.action_menu_recordings).setOnClickListener(this); - findViewById(R.id.action_menu_timers).setOnClickListener(this); - findViewById(R.id.action_menu_epg).setOnClickListener(this); - findViewById(R.id.action_menu_remote).setOnClickListener(this); + Preferences.setLocale(this); + + // this.getActionBar().setDisplayShowCustomEnabled(true); + // this.getActionBar().setDisplayShowTitleEnabled(false); + // setTitle(getString(R.string.app_name)); + // attach view + setContentView(R.layout.vdrmanager); + + // Preferences.loadPreferences(this); + + findViewById(R.id.action_menu_channels).setOnClickListener(this); + findViewById(R.id.action_menu_recordings).setOnClickListener(this); + findViewById(R.id.action_menu_timers).setOnClickListener(this); + findViewById(R.id.action_menu_epg).setOnClickListener(this); + findViewById(R.id.action_menu_remote).setOnClickListener(this); // View v = findViewById(R.id.action_menu_search); // if (v != null) { // v.setOnClickListener(this); // } - //findViewById(R.id.main_logo).setOnClickListener(this); - actionMenuWakup = findViewById(R.id.action_menu_wakeup); - actionMenuRemote = findViewById(R.id.action_menu_remote); - // add and register buttons - // createButtons(); - } - - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - - // search = new SearchView(getSupportActionBar().getThemedContext()); - search = (SearchView) MenuItemCompat.getActionView( menu.findItem(R.id.menu_search)); - - // search = (SearchView) - // .getActionView(); - // - // Object o = menu.findItem(R.id.menu_search); - - SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); - search.setSearchableInfo(searchManager - .getSearchableInfo(getComponentName())); - - //search.setOnQueryTextListener(this); - return true; - } - - @Override - protected void onResume() { - Preferences.setLocale(this); - if (Preferences.get().isWakeupEnabled() == false) { - actionMenuWakup.setVisibility(View.GONE); - actionMenuWakup.setOnClickListener(null); - } else { - actionMenuWakup.setVisibility(View.VISIBLE); - actionMenuWakup.setOnClickListener(this); - } - - if(Preferences.get().isRemoteEnabled() == false){ - actionMenuRemote.setVisibility(View.GONE); - actionMenuRemote.setOnClickListener(null); - } else { - actionMenuRemote.setVisibility(View.VISIBLE); - actionMenuRemote.setOnClickListener(this); - } - - - super.onResume(); - } - - @Override - public boolean onOptionsItemSelected( - final MenuItem item) { - - switch (item.getItemId()) { - case R.id.main_menu_preferences: { - Intent intent = new Intent(this, PreferencesActivity.class); - int flags = Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_SINGLE_TOP - | Intent.FLAG_ACTIVITY_CLEAR_TOP; - intent.setFlags(flags); - startActivity(intent); - finish(); - break; - } - case R.id.main_menu_info: { - if(isFinishing()){ - break; - } - About.show(this); - break; - } - case R.id.main_menu_exit: { - finish(); - break; - } - - case R.id.main_menu_clear_search: { - SearchRecentSuggestions suggestions = new SearchRecentSuggestions( - this, EPGSearchSuggestionsProvider.AUTHORITY, - EPGSearchSuggestionsProvider.MODE); - suggestions.clearHistory(); - break; - } - - // case R.id.menu_search: { - // if(Build.VERSION.SDK_INT <11){ - // onSearchRequested(); - // } - // break; - // } - case R.id.main_menu_goto: { - try { - final Cursor cursor = ((AndroidDatabaseResults) DBAccess - .get(this).getVdrDAO().iterator().getRawResults()) - .getRawCursor(); - startManagingCursor(cursor); - final AlertDialog ad = new AlertDialog.Builder(this) - .setSingleChoiceItems(cursor, findVdrCursor(cursor), - "name", new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, - int which) { - cursor.moveToPosition(which); - int id = cursor.getInt(cursor - .getColumnIndex("_id")); - Vdr vdr = DBAccess - .get(VdrManagerActivity.this) - .getVdrDAO().queryForId(id); - if (vdr == null) { - Toast.makeText( - VdrManagerActivity.this, - R.string.main_menu_goto_no_vdr, - Toast.LENGTH_SHORT).show(); - } else { - Preferences.setCurrentVdr( - VdrManagerActivity.this, - vdr); - Toast.makeText( - VdrManagerActivity.this, - getString( - R.string.main_menu_switched_to, - vdr.getName()), - Toast.LENGTH_SHORT).show(); - Intent intent = getIntent(); - overridePendingTransition(0, 0); - intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - finish(); - - overridePendingTransition(0, 0); - startActivity(intent); - } - dialog.dismiss(); - } - })// - .setTitle(R.string.main_menu_goto_title)// - .create(); - ad.show(); - - } catch (Exception ex) { - Log.w(TAG, ex); - } - - break; - } - } - return true; - } - - private int findVdrCursor(Cursor c) { - if (Preferences.get().getCurrentVdr() == null) { - return -1; - } - - int cid = Preferences.get().getCurrentVdr().getId(); - - int position = 0; - c.moveToPosition(-1); - while (c.moveToNext()) { - if (c.getInt(c.getColumnIndex("_id")) == cid) { - break; - } - position++; - } - return position; - } - - @Override - public void onBackPressed() { - if (Preferences.get().isQuiteOnBackButton()) { - finish(); - } else { - super.onBackPressed(); - } - - try { - // reassign a new and empty key store - ((VdrManagerApp)getApplication()).initSessionKeyStore(); - } catch (final Exception e) { - Log.e(getClass().getName(), "Can't clear session key store"); + //findViewById(R.id.main_logo).setOnClickListener(this); + actionMenuWakup = findViewById(R.id.action_menu_wakeup); + actionMenuRemote = findViewById(R.id.action_menu_remote); + // add and register buttons + // createButtons(); + checkAndRequestPermission(); + + } + + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_menu, menu); + + // search = new SearchView(getSupportActionBar().getThemedContext()); + search = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search)); + + // search = (SearchView) + // .getActionView(); + // + // Object o = menu.findItem(R.id.menu_search); + + SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); + search.setSearchableInfo(searchManager + .getSearchableInfo(getComponentName())); + + //search.setOnQueryTextListener(this); + return true; + } + + @Override + protected void onResume() { + Preferences.setLocale(this); + if (Preferences.get().isWakeupEnabled() == false) { + actionMenuWakup.setVisibility(View.GONE); + actionMenuWakup.setOnClickListener(null); + } else { + actionMenuWakup.setVisibility(View.VISIBLE); + actionMenuWakup.setOnClickListener(this); + } + + if (Preferences.get().isRemoteEnabled() == false) { + actionMenuRemote.setVisibility(View.GONE); + actionMenuRemote.setOnClickListener(null); + } else { + actionMenuRemote.setVisibility(View.VISIBLE); + actionMenuRemote.setOnClickListener(this); + } + + + super.onResume(); + } + + @Override + public boolean onOptionsItemSelected( + final MenuItem item) { + + switch (item.getItemId()) { + case R.id.main_menu_preferences: { + Intent intent = new Intent(this, PreferencesActivity.class); + int flags = Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_SINGLE_TOP + | Intent.FLAG_ACTIVITY_CLEAR_TOP; + intent.setFlags(flags); + startActivity(intent); + finish(); + break; + } + case R.id.main_menu_info: { + if (isFinishing()) { + break; + } + About.show(this); + break; + } + case R.id.main_menu_exit: { + finish(); + break; + } + + case R.id.main_menu_clear_search: { + SearchRecentSuggestions suggestions = new SearchRecentSuggestions( + this, EPGSearchSuggestionsProvider.AUTHORITY, + EPGSearchSuggestionsProvider.MODE); + suggestions.clearHistory(); + break; + } + + // case R.id.menu_search: { + // if(Build.VERSION.SDK_INT <11){ + // onSearchRequested(); + // } + // break; + // } + case R.id.main_menu_goto: { + try { + final Cursor cursor = ((AndroidDatabaseResults) DBAccess + .get(this).getVdrDAO().iterator().getRawResults()) + .getRawCursor(); + startManagingCursor(cursor); + final AlertDialog ad = new AlertDialog.Builder(this) + .setSingleChoiceItems(cursor, findVdrCursor(cursor), + "name", new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, + int which) { + cursor.moveToPosition(which); + int id = cursor.getInt(cursor + .getColumnIndex("_id")); + Vdr vdr = DBAccess + .get(VdrManagerActivity.this) + .getVdrDAO().queryForId(id); + if (vdr == null) { + Toast.makeText( + VdrManagerActivity.this, + R.string.main_menu_goto_no_vdr, + Toast.LENGTH_SHORT).show(); + } else { + Preferences.setCurrentVdr( + VdrManagerActivity.this, + vdr); + Toast.makeText( + VdrManagerActivity.this, + getString( + R.string.main_menu_switched_to, + vdr.getName()), + Toast.LENGTH_SHORT).show(); + Intent intent = getIntent(); + overridePendingTransition(0, 0); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + finish(); + + overridePendingTransition(0, 0); + startActivity(intent); + } + dialog.dismiss(); + } + })// + .setTitle(R.string.main_menu_goto_title)// + .create(); + ad.show(); + + } catch (Exception ex) { + Log.w(TAG, ex); + } + + break; + } + } + return true; + } + + private int findVdrCursor(Cursor c) { + if (Preferences.get().getCurrentVdr() == null) { + return -1; + } + + int cid = Preferences.get().getCurrentVdr().getId(); + + int position = 0; + c.moveToPosition(-1); + while (c.moveToNext()) { + if (c.getInt(c.getColumnIndex("_id")) == cid) { + break; + } + position++; + } + return position; } - } - - public void startActivity(Class<?> clazz) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setClass(this, clazz); - startActivity(intent); - } - - public void onClick(View v) { - int id = v.getId(); - - switch (id) { - case R.id.action_menu_channels: - startActivity(ChannelListActivity.class); - break; - case R.id.action_menu_recordings: - startActivity(RecordingListActivity.class); - break; - case R.id.action_menu_timers: - startActivity(TimerListActivity.class); - break; - case R.id.action_menu_epg: - startActivity(TimeEpgListActivity.class); - break; + @Override + public void onBackPressed() { + if (Preferences.get().isQuiteOnBackButton()) { + finish(); + } else { + super.onBackPressed(); + } + + try { + // reassign a new and empty key store + ((VdrManagerApp) getApplication()).initSessionKeyStore(); + } catch (final Exception e) { + Log.e(getClass().getName(), "Can't clear session key store"); + } + + } + + public void startActivity(Class<?> clazz) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setClass(this, clazz); + startActivity(intent); + } + + public void onClick(View v) { + int id = v.getId(); + + switch (id) { + case R.id.action_menu_channels: + startActivity(ChannelListActivity.class); + break; + case R.id.action_menu_recordings: + startActivity(RecordingListActivity.class); + break; + case R.id.action_menu_timers: + startActivity(TimerListActivity.class); + break; + case R.id.action_menu_epg: + startActivity(TimeEpgListActivity.class); + break; // case R.id.action_menu_search: // onSearchRequested(); // break; - case R.id.action_menu_wakeup: - final AsyncWakeupTask wakeupTask = new AsyncWakeupTask(this); - wakeupTask.execute(); - break; - case R.id.main_logo: - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(VDR_PORTAL)); - startActivity(i); - break; - - case R.id.action_menu_remote: - startActivity(RemoteActivity.class); - break; - - } - - } - - protected void startSearchManager() { - Bundle appData = new Bundle(); - startSearch(null, false, appData, false); - } - - @Override - public boolean onSearchRequested() { - search.setVisibility(View.VISIBLE); - // Bundle appData = new Bundle(); - // appData.putBoolean(SearchableActivity.JARGON, true); - // startSearch(null, false, appData, false); - return true; - } - - @Override - public boolean onQueryTextSubmit(String query) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - // TODO Auto-generated method stub - return false; - } + case R.id.action_menu_wakeup: + final AsyncWakeupTask wakeupTask = new AsyncWakeupTask(this); + wakeupTask.execute(); + break; + case R.id.main_logo: + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(VDR_PORTAL)); + startActivity(i); + break; + + case R.id.action_menu_remote: + startActivity(RemoteActivity.class); + break; + + } + + } + + protected void startSearchManager() { + Bundle appData = new Bundle(); + startSearch(null, false, appData, false); + } + + @Override + public boolean onSearchRequested() { + search.setVisibility(View.VISIBLE); + // Bundle appData = new Bundle(); + // appData.putBoolean(SearchableActivity.JARGON, true); + // startSearch(null, false, appData, false); + return true; + } + + @Override + public boolean onQueryTextSubmit(String query) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + // TODO Auto-generated method stub + return false; + } } diff --git a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/remote/RemoteActivity.java b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/remote/RemoteActivity.java index efd3cec..254150e 100644 --- a/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/remote/RemoteActivity.java +++ b/vdrmanager/de.bjusystems.vdrmanager/src/main/java/de/bjusystems/vdrmanager/remote/RemoteActivity.java @@ -7,9 +7,12 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.os.Environment; +import android.util.Log; import android.util.Pair; import android.view.ContextMenu; import android.view.KeyEvent; @@ -35,11 +38,21 @@ import org.hampelratte.svdrp.commands.HITK; import org.json.JSONException; import org.json.JSONObject; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; import de.androvdr.widget.AnimatedTextView; import de.androvdr.widget.FontAwesome; import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.backup.IOUtils; import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.gui.ColoredButton; import de.bjusystems.vdrmanager.gui.Utils; @@ -52,6 +65,10 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On private static final int TAG_KEY = -100; + private static final String TAG = RemoteActivity.class.getSimpleName(); + + private static final int READ_REQUEST_CODE = 19; + private Connection connection; private AnimatedTextView result; @@ -60,12 +77,15 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On private View dummyContextMenuView; + private ViewGroup remoteroot; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); + //Remove notification bar this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); View view = getLayoutInflater().inflate(R.layout.remote, null); @@ -77,12 +97,12 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On view.setOnLongClickListener(this); - ViewGroup viewGroup = (ViewGroup) view.findViewById(R.id.remoteroot); + remoteroot = (ViewGroup) view.findViewById(R.id.remoteroot); //Button button = (Button) viewGroup.findViewById(R.id.red); //button.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY); - setAllButtonListener(viewGroup); + setAllButtonListener(remoteroot); result = (AnimatedTextView) findViewById(R.id.result); //Animation in = AnimationUtils.loadAnimation(this,android.R.anim.fade_in); @@ -95,9 +115,14 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On in = new AlphaAnimation(0.0f, 1.0f); in.setDuration(100); - - //SearchableSpinner spinner2 = (SearchableSpinner) findViewById(R.id.search2); - //spinner2.setList(getResources().getStringArray(R.array.font)); + Bundle bundle = getIntent().getExtras(); + if (bundle != null) { + Uri uri = (Uri) bundle.get(Intent.EXTRA_STREAM); + if (uri != null) { + importFromUri(uri); + return; + } + } } @@ -162,46 +187,83 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On public void export() { SharedPreferences sharedPref = getSharedPreferences("remote_" + Preferences.get().getCurrentVdr().getId(), Context.MODE_PRIVATE); ViewGroup viewGroup = (ViewGroup) findViewById(R.id.remoteroot); - ArrayList<Pair<String, String>> list = new ArrayList<>(); - gather(viewGroup, list, sharedPref); + HashMap<String, Pair<String, String>> map = new HashMap<>(); + collect(viewGroup, map, sharedPref); + + if(map.isEmpty()){ + Utils.say(this, R.string.remote_nothing_to_import); + return; + } JSONObject root = new JSONObject(); try { - for (Pair<String, String> stringStringPair : list) { - root.put(stringStringPair.first, stringStringPair.second); + for (Map.Entry<String, Pair<String, String>> e : map.entrySet()) { + JSONObject pair = new JSONObject(); + Pair<String, String> stringStringPair = e.getValue(); + pair.put("key", stringStringPair.first); + pair.put("label", stringStringPair.second); + root.put(e.getKey(), pair); } } catch (JSONException jse) { Utils.say(this, jse.getLocalizedMessage()); } - Intent i = new Intent(android.content.Intent.ACTION_SEND); - i.setType("application/json"); - i.putExtra(android.content.Intent.EXTRA_TEXT, root.toString()); - startActivity(Intent.createChooser(i, getResources().getString(R.string.export_custom_key_mapping))); + Intent intentShareFile = new Intent(Intent.ACTION_SEND); + String content = root.toString(); + File outputFile = null; + try { + outputFile = File.createTempFile("vdr_remote_keys_", ".json", Environment.getExternalStorageDirectory()); + final FileOutputStream fileOutputStream = new FileOutputStream(outputFile); + fileOutputStream.write(content.getBytes("utf-8")); + IOUtils.closeQuietly(fileOutputStream); + } catch (IOException iox) { + Log.d(TAG, iox.getMessage(), iox); + Utils.say(this, iox.getLocalizedMessage()); + return; + } + intentShareFile.setType("text/plain"); + intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + outputFile.getAbsolutePath())); + + intentShareFile.putExtra(Intent.EXTRA_SUBJECT, + getString(R.string.export_custom_key_mapping)); + + intentShareFile.putExtra(Intent.EXTRA_TEXT, content); + + startActivity(Intent.createChooser(intentShareFile, getString(R.string.export_custom_key_mapping))); } + //Intent i = new Intent(android.content.Intent.ACTION_SEND); + // i.setType("application/json"); +// i.putExtra(android.content.Intent.EXTRA_TEXT,root.toString()); + + // startActivity(Intent.createChooser(i, getResources(). + + //getString())); +//} + /** * Gather. * * @param viewGroup the view group - * @param pair the pair + * @param map the map * @param sharedPref the shared pref */ - public void gather(ViewGroup viewGroup, ArrayList<Pair<String, String>> pair, SharedPreferences sharedPref) { + public void collect(ViewGroup viewGroup, HashMap<String, Pair<String, String>> map, SharedPreferences sharedPref) { for (int i = 0; i < viewGroup.getChildCount(); i++) { View v = viewGroup.getChildAt(i); if (v instanceof ViewGroup) { - gather((ViewGroup) v, pair, sharedPref); + collect((ViewGroup) v, map, sharedPref); } else if (v instanceof Button) { if (v.getTag() == null) { continue; } - String hitk = sharedPref.getString("key_" + String.valueOf(v.getTag()), null); - String label = sharedPref.getString("label_" + String.valueOf(v.getTag()), null); + String tagKey = String.valueOf(v.getTag()); + String hitk = sharedPref.getString("key_" + tagKey, null); + String label = sharedPref.getString("label_" + tagKey, null); if (hitk == null && label == null) { continue; } - pair.add(Pair.create(hitk, label)); + map.put(tagKey, Pair.create(hitk, label)); } } } @@ -272,7 +334,9 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On private void restart() { - + if(getIntent() != null) { + getIntent().removeExtra(Intent.EXTRA_STREAM); + } if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { recreate(); } else { @@ -299,7 +363,18 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On return true; } case R.id.imprt: { - Utils.say(this, R.string.not_yet_implemented); + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + + // Filter to only show results that can be "opened", such as a + // file (as opposed to a list of contacts or timezones) + intent.addCategory(Intent.CATEGORY_OPENABLE); + + // Filter to show only images, using the image MIME data type. + // If one wanted to search for ogg vorbis files, the type would be "audio/ogg". + // To search for all documents available via installed storage providers, + // it would be "*/*". + intent.setType("*/*"); + startActivityForResult(intent, READ_REQUEST_CODE); return true; } case R.id.remapback: { @@ -322,6 +397,13 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On ; + /** + * On create context menu. + * + * @param menu the menu + * @param v the v + * @param menuInfo the menu info + */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { @@ -417,6 +499,70 @@ public class RemoteActivity extends Activity implements OnClickListener, View.On return false; } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // The ACTION_OPEN_DOCUMENT intent was sent with the request code + // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the + // response to some other intent, and the code below shouldn't run at all. + + if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + // The document selected by the user won't be returned in the intent. + // Instead, a URI to that document will be contained in the return intent + // provided to this method as a parameter. + // Pull that URI using resultData.getData(). + Uri uri = null; + if (data != null) { + uri = data.getData(); + importFromUri(uri); + } + } + } + + private void importFromUri(Uri uri) { + try { + Log.i(TAG, "Uri: " + uri.toString()); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(getContentResolver().openInputStream(uri), bos); + JSONObject object = new JSONObject(new String(bos.toByteArray(), "utf-8" + )); + IOUtils.closeQuietly(bos); + final Iterator<String> keys = object.keys(); + Set<String> all = new HashSet<String>(); + for (de.bjusystems.vdrmanager.remote.HITK hitk : de.bjusystems.vdrmanager.remote.HITK.values()) { + all.add(hitk.getValue()); + } + SharedPreferences sharedPref = getSharedPreferences("remote_" + Preferences.get().getCurrentVdr().getId(), Context.MODE_PRIVATE); + SharedPreferences.Editor edit = sharedPref.edit(); + int counter = 0; + while (keys.hasNext()) { + final String next = keys.next(); + if (all.contains(next) == false) { + continue; + } + JSONObject pair = object.getJSONObject(next); + String key = pair.getString("key"); + if (all.contains(key) == false) { + continue; + } + String value = pair.getString("label"); + edit.putString("key_" + next, key); + edit.putString("label_" + next, value); + counter++; + } + edit.commit(); + Utils.say(this, getString(R.string.remote_keys_imported, String.valueOf(counter))); + if (counter > 0) { + setAllButtonListener(remoteroot); + } + } catch (Exception iox) + + { + Log.w(TAG, iox.getMessage(), iox); + Utils.say(this, iox.getMessage()); + } + } + + private void putVdrKey(String key, CharSequence value) { SharedPreferences sharedPref = getSharedPreferences("remote_" + Preferences.get().getCurrentVdr().getId(), Context.MODE_PRIVATE); SharedPreferences.Editor edit = sharedPref.edit(); |