package de.qspool.clementineremote.utils; import com.afollestad.materialdialogs.MaterialDialog; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Dialog; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkInfo; import android.os.Build; import android.os.Environment; import android.os.StatFs; import android.support.v4.app.TaskStackBuilder; import android.text.Html; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Enumeration; import java.util.Locale; import de.qspool.clementineremote.App; import de.qspool.clementineremote.R; import de.qspool.clementineremote.backend.mediasession.ClementineMediaSessionNotification; import de.qspool.clementineremote.ui.MainActivity; public class Utilities { @SuppressLint("DefaultLocale") public static String PrettyTime(int seconds) { // last.fm sometimes gets the track length wrong, so you end up with // negative times. seconds = Math.abs(seconds); int hours = seconds / (60 * 60); int minutes = (seconds / 60) % 60; seconds %= 60; String ret = ""; if (hours > 0) { ret = String.format("%d:%02d:%02d", hours, minutes, seconds); } else { ret = String.format("%d:%02d", minutes, seconds); } return ret; } /** * Show a simple designed message dialog * * @param context In which context will the dialog be displayed? * @param title The resource id of the message dialog title. * @param message The resource id of the message * @return The Dialog object */ public static Dialog ShowMessageDialog(Context context, int title, int message) { return ShowMessageDialog(context, context.getString(title), context.getString(message), false); } /** * Show a simple designed message dialog * * @param context In which context will the dialog be displayed? * @param title The resource id of the message dialog title. * @param message The resource id of the message * @return The Dialog object */ public static Dialog ShowHtmlMessageDialog(Context context, int title, int message) { return ShowMessageDialog(context, context.getString(title), context.getString(message), true); } /** * Show a simple designed message dialog * * @param context In which context will the dialog be displayed? * @param title The message string dialog title. * @param message The string of the message * @return The Dialog object */ public static Dialog ShowMessageDialog(Context context, String title, String message, boolean hasHtml) { String content; if (hasHtml) { content = Html.fromHtml(message).toString(); } else { content = message; } return new MaterialDialog.Builder(context) .title(title) .content(content) .negativeText(R.string.dialog_close) .show(); } public static byte[] ToIPByteArray(int addr) { return new byte[]{(byte) addr, (byte) (addr >>> 8), (byte) (addr >>> 16), (byte) (addr >>> 24)}; } public static InetAddress ToInetAddress(int addr) { try { return InetAddress.getByAddress(ToIPByteArray(addr)); } catch (UnknownHostException e) { return null; } } /** * Get the free space on the external storage device (like sd card) * * @return The free space in byte */ @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public static double getFreeSpaceExternal() { StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { return (double) stat.getAvailableBlocks() * (double) stat.getBlockSize(); } else { return (double) stat.getAvailableBlocksLong() * (double) stat.getBlockSizeLong(); } } /** * Get the free space on the internal storage device * * @return The free space in byte */ @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public static double getFreeSpaceInternal() { StatFs stat = new StatFs(App.getApp().getFilesDir().getPath()); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { return (double) stat.getAvailableBlocks() * (double) stat.getBlockSize(); } else { return (double) stat.getAvailableBlocksLong() * (double) stat.getBlockSizeLong(); } } /** * Is the device connceted to a wifi network? * * @return true if connected to a wifi network */ @SuppressWarnings("deprecation") public static boolean onWifi() { ConnectivityManager connManager = (ConnectivityManager) App.getApp() .getSystemService(Context.CONNECTIVITY_SERVICE); boolean onWifi = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Network[] networks = connManager.getAllNetworks(); NetworkInfo networkInfo; for (Network mNetwork : networks) { networkInfo = connManager.getNetworkInfo(mNetwork); if (networkInfo.getState().equals(NetworkInfo.State.CONNECTED) && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { onWifi = true; break; } } } else { //noinspection deprecation onWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected(); } return onWifi; } /** * Convert bytes in a human readable format. * * @param bytes The byte count * @param iec false for KB, false for KiB * @return The human readable file size */ public static String humanReadableBytes(long bytes, boolean iec) { // Are we using xB or xiB? int byteUnit = iec ? 1024 : 1000; float newBytes = bytes; int exp = 0; // Calculate the file size in the best readable way while (newBytes > byteUnit) { newBytes = newBytes / byteUnit; exp++; } // What prefix do we have to use? String prefix = ""; if (exp > 0) { prefix = (iec ? " KMGTPE" : " kMGTPE").charAt(exp) + ((iec) ? "i" : ""); } // Return a human readable String return String.format(Locale.US, "%.2f %sB", newBytes, prefix); } /** * Checks if Clementine Remote is connected to an instance * of Clementine. * * @return true if connected, false otherwise */ public static boolean isRemoteConnected() { return App.ClementineConnection != null && App.ClementineConnection.isConnected(); } /** * This method removes all illegal characters in a file name. * * @param str The string containing a file or folder name * @return A string that is a vaild file name */ public static String removeInvalidFileCharacters(String str) { String illegal = "[\\\\~#%&*{}/:<>?|\\\"-]"; return str.replaceAll(illegal, ""); } public static PendingIntent getClementineRemotePendingIntent(Context context) { // Set the result intent Intent resultIntent = new Intent(context, MainActivity.class); resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); resultIntent.putExtra(ClementineMediaSessionNotification.EXTRA_NOTIFICATION_ID, -1); // Create a TaskStack, so the app navigates correctly backwards TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); return stackBuilder.getPendingIntent(9912, PendingIntent.FLAG_UPDATE_CURRENT); } public static Inet4Address getIp4Address() { try { Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface networkInterface = interfaces.nextElement(); Enumeration<InetAddress> addresses = networkInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = addresses.nextElement(); if (address instanceof Inet4Address && !address.isLoopbackAddress()) { return (Inet4Address) address; } } } } catch (SocketException e) { return null; } return null; } }