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;
}
}