11 | *
24 | *
31 | * When dealing with the bitmaps of bigger size, this method must be called from a non-UI
32 | * thread.
33 | **/
34 | public static Bitmap scaleDownBitmap(Context ctx, Bitmap source, int newHeight) {
35 | final float densityMultiplier = Utils.getDensityMultiplier(ctx);
36 |
37 | // Log.v( TAG, "#scaleDownBitmap Original w: " + source.getWidth() + " h: " +
38 | // source.getHeight() );
39 |
40 | int h = (int) (newHeight * densityMultiplier);
41 | int w = (int) (h * source.getWidth() / ((double) source.getHeight()));
42 |
43 | // Log.v( TAG, "#scaleDownBitmap Computed w: " + w + " h: " + h );
44 |
45 | Bitmap photo = Bitmap.createScaledBitmap(source, w, h, true);
46 |
47 | // Log.v( TAG, "#scaleDownBitmap Final w: " + w + " h: " + h );
48 |
49 | return photo;
50 | }
51 |
52 | /**
53 | * Scales the image independently of the screen density of the device. Maintains image aspect
54 | * ratio.
55 | *
56 | * When dealing with the bitmaps of bigger size, this method must be called from a non-UI
57 | * thread.
58 | */
59 | public static Bitmap scaleBitmap(Context ctx, Bitmap source, int newHeight) {
60 |
61 | // Log.v( TAG, "#scaleDownBitmap Original w: " + source.getWidth() + " h: " +
62 | // source.getHeight() );
63 |
64 | int w = (int) (newHeight * source.getWidth() / ((double) source.getHeight()));
65 |
66 | // Log.v( TAG, "#scaleDownBitmap Computed w: " + w + " h: " + newHeight );
67 |
68 | Bitmap photo = Bitmap.createScaledBitmap(source, w, newHeight, true);
69 |
70 | // Log.v( TAG, "#scaleDownBitmap Final w: " + w + " h: " + newHeight );
71 |
72 | return photo;
73 | }
74 |
75 | /**
76 | * Scales the image independently of the screen density of the device. Maintains image aspect
77 | * ratio.
78 | *
79 | * @param uri Uri of the source bitmap
80 | **/
81 | public static Bitmap scaleDownBitmap(Context ctx, Uri uri, int newHeight) throws FileNotFoundException, IOException {
82 | Bitmap original = Media.getBitmap(ctx.getContentResolver(), uri);
83 | return scaleBitmap(ctx, original, newHeight);
84 | }
85 |
86 | /**
87 | * Scales the image independently of the screen density of the device. Maintains image aspect
88 | * ratio.
89 | *
90 | * @param uri Uri of the source bitmap
91 | **/
92 | public static Uri scaleDownBitmapForUri(Context ctx, Uri uri, int newHeight) throws FileNotFoundException, IOException {
93 |
94 | if (uri == null)
95 | throw new NullPointerException(ERROR_URI_NULL);
96 |
97 | if (!MediaUtils.isMediaContentUri(uri))
98 | return null;
99 |
100 | Bitmap original = Media.getBitmap(ctx.getContentResolver(), uri);
101 | Bitmap bmp = scaleBitmap(ctx, original, newHeight);
102 |
103 | Uri destUri = null;
104 | String uriStr = Utils.writeImageToMedia(ctx, bmp, "", "");
105 |
106 | if (uriStr != null) {
107 | destUri = Uri.parse(uriStr);
108 | }
109 |
110 | return destUri;
111 | }
112 |
113 | /**
114 | * Gets the orientation of the image pointed to by the parameter uri
115 | *
116 | * @return Image orientation value corresponding to
75 | *
79 | *
12 | *
13 | *
14 | * @author Jay
15 | **/
16 | public class SharedPreferenceManager {
17 |
18 | protected Context mContext;
19 |
20 | // TODO: make these members private.
21 | protected SharedPreferences mSettings;
22 | protected Editor mEditor;
23 |
24 | public SharedPreferenceManager(Context ctx, String prefFileName) {
25 | mContext = ctx;
26 |
27 | mSettings = mContext.getSharedPreferences(prefFileName,
28 | Context.MODE_PRIVATE);
29 | mEditor = mSettings.edit();
30 | }
31 |
32 | /***
33 | * Set a value for the key
34 | ****/
35 | public void setValue(String key, String value) {
36 | mEditor.putString(key, value);
37 | mEditor.commit();
38 | }
39 |
40 | /***
41 | * Set a value for the key
42 | ****/
43 | public void setValue(String key, int value) {
44 | mEditor.putInt(key, value);
45 | mEditor.commit();
46 | }
47 |
48 | /***
49 | * Set a value for the key
50 | ****/
51 | public void setValue(String key, double value) {
52 | setValue(key, Double.toString(value));
53 | }
54 |
55 | /***
56 | * Set a value for the key
57 | ****/
58 | public void setValue(String key, long value) {
59 | mEditor.putLong(key, value);
60 | mEditor.commit();
61 | }
62 |
63 | /****
64 | * Gets the value from the settings stored natively on the device.
65 | *
66 | * @param defaultValue Default value for the key, if one is not found.
67 | **/
68 | public String getValue(String key, String defaultValue) {
69 | return mSettings.getString(key, defaultValue);
70 | }
71 |
72 | public int getIntValue(String key, int defaultValue) {
73 | return mSettings.getInt(key, defaultValue);
74 | }
75 |
76 | public long getLongValue(String key, long defaultValue) {
77 | return mSettings.getLong(key, defaultValue);
78 | }
79 |
80 | /****
81 | * Gets the value from the preferences stored natively on the device.
82 | *
83 | * @param defValue Default value for the key, if one is not found.
84 | **/
85 | public boolean getValue(String key, boolean defValue) {
86 | return mSettings.getBoolean(key, defValue);
87 | }
88 |
89 | public void setValue(String key, boolean value) {
90 | mEditor.putBoolean(key, value);
91 | mEditor.commit();
92 | }
93 |
94 | /**
95 | * Clear all the preferences store in this {@link android.content.SharedPreferences.Editor}
96 | */
97 | public boolean clear() {
98 | try {
99 | mEditor.clear().commit();
100 | return true;
101 | } catch (Exception e) {
102 | e.printStackTrace();
103 | return false;
104 | }
105 | }
106 |
107 | /**
108 | * Removes preference entry for the given key.
109 | *
110 | * @param key
111 | */
112 | public void removeValue(String key) {
113 | if (mEditor != null) {
114 | mEditor.remove(key).commit();
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/Utils/app/src/main/java/net/the4thdimension/android/YouTubeUtils.java:
--------------------------------------------------------------------------------
1 | package net.the4thdimension.android;
2 |
3 | import android.net.Uri;
4 | import android.text.TextUtils;
5 |
6 | import java.net.MalformedURLException;
7 | import java.net.URL;
8 |
9 | /**
10 | * YouTube related utility class.
11 | */
12 | public class YouTubeUtils {
13 |
14 | /*default.jpg - default
15 | https://i1.ytimg.com/vi/
67 | * Use {@link nl.changer.android.opensource.AudioUtils#saveAudio(android.content.Context)}
68 | * Insert an audio into {@link android.provider.MediaStore.Images.Media} content provider of the device.
69 | *
70 | * @return The media content Uri to the newly created audio, or null if failed for any reason.
71 | * ***/
72 | public static Uri writeAudioToMedia(Context ctx, File audioFile) {
73 | ContentValues values = new ContentValues();
74 | values.put(MediaStore.MediaColumns.DATA, audioFile.getAbsolutePath());
75 | values.put(MediaStore.MediaColumns.TITLE, "");
76 | values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");
77 | values.put(MediaStore.MediaColumns.SIZE, audioFile.length());
78 | values.put(MediaStore.Audio.Media.ARTIST, "");
79 | values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
80 | // Now set some extra features it depend on you
81 | values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
82 | values.put(MediaStore.Audio.Media.IS_ALARM, false);
83 | values.put(MediaStore.Audio.Media.IS_MUSIC, false);
84 |
85 | Uri uri = MediaStore.Audio.Media.getContentUriForPath(audioFile.getAbsolutePath());
86 | Uri uri2 = ctx.getContentResolver().insert(uri, values);
87 |
88 | if (uri2 == null || TextUtils.isEmpty(uri2.toString())) {
89 | Log.w(TAG, "Something went wrong while inserting data to content resolver");
90 | }
91 |
92 | return uri2;
93 | }
94 |
95 | /**
96 | *
97 | * @param ctx
98 | * @return The media content Uri to the newly created audio, or null if failed for any reason.
99 | */
100 | private static Uri saveAudio(Context ctx) {
101 | File audioFile = new File(mFileName);
102 |
103 | ContentValues values = new ContentValues();
104 | values.put(MediaStore.MediaColumns.DATA, audioFile.getAbsolutePath());
105 | values.put(MediaStore.MediaColumns.TITLE, "");
106 | values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");
107 | values.put(MediaStore.MediaColumns.SIZE, audioFile.length());
108 | values.put(MediaStore.Audio.Media.ARTIST, "");
109 | values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
110 | // Now set some extra features it depend on you
111 | values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
112 | values.put(MediaStore.Audio.Media.IS_ALARM, false);
113 | values.put(MediaStore.Audio.Media.IS_MUSIC, false);
114 |
115 | Uri uri = MediaStore.Audio.Media.getContentUriForPath(audioFile.getAbsolutePath());
116 | Uri uri2 = ctx.getContentResolver().insert(uri, values);
117 |
118 | if (uri2 == null || TextUtils.isEmpty(uri2.toString())) {
119 | Log.w(TAG, "Something went wrong while inserting data to content resolver");
120 | }
121 |
122 | return uri2;
123 | }
124 |
125 | /****
126 | * Remove audio file that is existing on the device.
127 | *
128 | * @param ctx
129 | * {@link android.content.Context}
130 | * @param uri
131 | * {@link android.net.Uri} of the audio file
132 | *
133 | * @throws NullPointerException
134 | * if the Uri parameter is null
135 | * */
136 | public static boolean removeAudio(Context ctx, Uri uri) {
137 |
138 | if (uri == null) {
139 | throw new NullPointerException("Uri cannot be null");
140 | }
141 |
142 | return (ctx.getContentResolver().delete(uri, null, null) != 0);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/Utils/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/Utils/gradle/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/Utils/app/src/main/java/net/the4thdimension/android/ViewUtils.java:
--------------------------------------------------------------------------------
1 | package net.the4thdimension.android;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.Shader;
9 | import android.graphics.drawable.BitmapDrawable;
10 | import android.graphics.drawable.Drawable;
11 | import android.os.Build;
12 | import android.text.Editable;
13 | import android.text.InputFilter;
14 | import android.text.TextWatcher;
15 | import android.util.Log;
16 | import android.view.View;
17 | import android.widget.EditText;
18 | import android.widget.TextView;
19 |
20 |
21 | /**
22 | * Provides utility methods and convenience methods for View controls.
23 | *
25 | *
26 | * @author Jay
27 | */
28 | public class ViewUtils {
29 |
30 | private static final String TAG = ViewUtils.class.getSimpleName();
31 |
32 | /**
33 | * Shows live character counter for the number of characters typed in the parameter {@link android.widget.EditText}
34 | *
35 | * @param editTextView Characters to count from
36 | * @param textCounterView {@link android.widget.TextView} to show live character count in
37 | * @param maxCharCount Max characters that can be typed in into the parameter edittext
38 | * @param countdown if true, only the remaining of the max character count will be displayed. If false,
39 | * current character count as well as max character count will be displayed in the UI.
40 | */
41 | public static void setLiveCharCounter(EditText editTextView, final TextView textCounterView, final int maxCharCount, final boolean countdown) {
42 |
43 | if (editTextView == null) {
44 | throw new NullPointerException("View to count text characters on cannot be null");
45 | }
46 |
47 | if (textCounterView == null) {
48 | throw new NullPointerException("View to display count cannot be null");
49 | }
50 |
51 | // initialize the TextView initial state
52 | if (countdown) {
53 | textCounterView.setText(String.valueOf(maxCharCount));
54 | } else {
55 | textCounterView.setText(String.valueOf("0 / " + maxCharCount));
56 | }
57 |
58 | // initialize the edittext
59 | setMaxLength(editTextView, maxCharCount);
60 |
61 | editTextView.addTextChangedListener(new TextWatcher() {
62 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
63 |
64 | }
65 |
66 | public void onTextChanged(CharSequence s, int start, int before, int count) {
67 |
68 | if (countdown) {
69 | // show only the remaining number of characters
70 | int charsLeft = maxCharCount - s.length();
71 |
72 | if (charsLeft >= 0) {
73 | textCounterView.setText(String.valueOf(charsLeft));
74 | }
75 | } else {
76 | // show number of chars / maxChars in the UI
77 | textCounterView.setText(s.length() + " / " + maxCharCount);
78 | }
79 |
80 | }
81 |
82 | public void afterTextChanged(Editable s) {
83 |
84 | }
85 | });
86 | }
87 |
88 | /**
89 | * Set max text length for textview
90 | */
91 | public static void setMaxLength(TextView textView, int maxLength) {
92 |
93 | if (textView == null) {
94 | throw new NullPointerException("TextView cannot be null");
95 | }
96 |
97 | InputFilter[] fArray = new InputFilter[1];
98 | fArray[0] = new InputFilter.LengthFilter(maxLength);
99 | textView.setFilters(fArray);
100 | }
101 |
102 | /**
103 | * Tiles the background of the for a view with viewId as a parameter.
104 | */
105 | public static void tileBackground(Context ctx, int viewId, int resIdOfTile) {
106 |
107 | try {
108 | // Tiling the background.
109 | Bitmap bmp = BitmapFactory.decodeResource(ctx.getResources(), resIdOfTile);
110 | BitmapDrawable bitmapDrawable = new BitmapDrawable(ctx.getResources(), bmp);
111 | bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
112 | View view = ((Activity) ctx).findViewById(viewId);
113 |
114 | if (view == null) {
115 | throw new NullPointerException("View to which the tile has to be applied should not be null");
116 | } else {
117 | setBackground(view, bitmapDrawable);
118 | }
119 | } catch (Exception e) {
120 | Log.w(TAG, "#tileBackground Exception while tiling the background of the view");
121 | }
122 | }
123 |
124 | @Deprecated
125 | /**
126 | * Use {@link ViewCompat#setBackground(view, background);} instead.
127 | * Sets the passed-in drawable parameter as a background to the
128 | * passed in target parameter in an SDK independent way. This
129 | * is the recommended way of setting background rather
130 | * than using native background setters provided by {@link android.view.View}
131 | * class. This method should NOT be used for setting background of an {@link android.widget.ImageView}
132 | *
133 | * @param target View to set background to.
134 | * @param drawable background image
135 | */
136 | @SuppressLint("NewApi")
137 | public static void setBackground(View target, Drawable drawable) {
138 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
139 | target.setBackgroundDrawable(drawable);
140 | } else {
141 | target.setBackground(drawable);
142 | }
143 | }
144 |
145 | public static void tileBackground(Context ctx, int layoutId, View viewToTileBg, int resIdOfTile) {
146 |
147 | try {
148 | // Tiling the background.
149 | Bitmap bmp = BitmapFactory.decodeResource(ctx.getResources(), resIdOfTile);
150 | // deprecated constructor
151 | // BitmapDrawable bitmapDrawable = new BitmapDrawable(bmp);
152 | BitmapDrawable bitmapDrawable = new BitmapDrawable(ctx.getResources(), bmp);
153 | bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
154 | View view = viewToTileBg.findViewById(layoutId);
155 |
156 | if (view != null) {
157 | setBackground(view, bitmapDrawable);
158 | }
159 |
160 | } catch (Exception e) {
161 | Log.e(TAG, "Exception while tiling the background of the view");
162 | }
163 | }
164 |
165 | /**
166 | * Set style to the parameter text view considering the current build SDK version.
167 | *
168 | * @param activity
169 | * @param textView
170 | * @param style
171 | */
172 | public static void setStyle(Activity activity, TextView textView,
173 | int style) {
174 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
175 | textView.setTextAppearance(style);
176 | } else {
177 | textView.setTextAppearance(activity, style);
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/Utils/app/src/main/java/net/the4thdimension/android/ImageUtils.java:
--------------------------------------------------------------------------------
1 |
2 | package net.the4thdimension.android;
3 |
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.Matrix;
9 | import android.media.ExifInterface;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.provider.MediaStore.Images.Media;
13 | import android.util.Log;
14 |
15 | import java.io.FileNotFoundException;
16 | import java.io.IOException;
17 |
18 | /**
19 | * Provides helper methods for image operations
20 | ***/
21 | public class ImageUtils {
22 |
23 | private final static String TAG = ImageUtils.class.getSimpleName();
24 |
25 | private static final String ERROR_URI_NULL = "Uri cannot be null";
26 |
27 | /**
28 | * Scales the image depending upon the display density of the device. Maintains image aspect
29 | * ratio.
30 | * ExifInterface.ORIENTATION_*
117 | * Returns -1 if the row for the {@link android.net.Uri} is not found.
118 | **/
119 | public static int getOrientation(Context context, Uri uri) {
120 |
121 | int invalidOrientation = -1;
122 | if (uri == null) {
123 | throw new NullPointerException(ERROR_URI_NULL);
124 | }
125 |
126 | if (!MediaUtils.isMediaContentUri(uri)) {
127 | return invalidOrientation;
128 | }
129 |
130 | String filePath = Utils.getPathForMediaUri(context, uri);
131 | ExifInterface exif = null;
132 |
133 | try {
134 | exif = new ExifInterface(filePath);
135 | } catch (IOException e) {
136 | e.printStackTrace();
137 | }
138 |
139 | int orientation = invalidOrientation;
140 | if (exif != null) {
141 | orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, invalidOrientation);
142 | }
143 |
144 | return orientation;
145 | }
146 |
147 | /**
148 | * Rotate the image at the specified uri. For the rotation of the image the
149 | * {@link android.media.ExifInterface} data in the image will be used.
150 | *
151 | * @param uri Uri of the image to be rotated.
152 | **/
153 | public static Uri rotateImage(Context context, Uri uri) throws FileNotFoundException, IOException {
154 | // rotate the image
155 | if (uri == null) {
156 | throw new NullPointerException(ERROR_URI_NULL);
157 | }
158 |
159 | if (!MediaUtils.isMediaContentUri(uri)) {
160 | return null;
161 | }
162 |
163 | int invalidOrientation = -1;
164 | byte[] data = Utils.getMediaData(context, uri);
165 |
166 | int orientation = getOrientation(context, uri);
167 |
168 | Uri newUri = null;
169 |
170 | try {
171 |
172 | Log.d(TAG, "#rotateImage Exif orientation: " + orientation);
173 |
174 | if (orientation != invalidOrientation) {
175 | Matrix matrix = new Matrix();
176 |
177 | switch (orientation) {
178 | case ExifInterface.ORIENTATION_ROTATE_90:
179 | matrix.postRotate(90);
180 | break;
181 | case ExifInterface.ORIENTATION_ROTATE_180:
182 | matrix.postRotate(180);
183 | break;
184 | case ExifInterface.ORIENTATION_ROTATE_270:
185 | matrix.postRotate(270);
186 | break;
187 | }
188 |
189 | // set some options so the memory is manager properly
190 | BitmapFactory.Options options = new BitmapFactory.Options();
191 | // options.inPreferredConfig = Bitmap.Config.RGB_565; // try to enable this if
192 | // OutOfMem issue still persists
193 | options.inPurgeable = true;
194 | options.inInputShareable = true;
195 |
196 | Bitmap original = BitmapFactory.decodeByteArray(data, 0, data.length, options);
197 | Bitmap rotatedBitmap = Bitmap.createBitmap(original, 0, 0, original.getWidth(), original.getHeight(), matrix, true); // rotating
198 | // bitmap
199 | String newUrl = Media.insertImage(((Activity) context).getContentResolver(), rotatedBitmap, "", "");
200 |
201 | if (newUrl != null) {
202 | newUri = Uri.parse(newUrl);
203 | }
204 | }
205 | } catch (Exception e) {
206 | e.printStackTrace();
207 | }
208 |
209 | return newUri;
210 | }
211 |
212 | /**
213 | * Get the size of parameter {@link Bitmap}. This maybe a heavy operation.
214 | * Prefer not calling from main thread of the activity.
215 | *
216 | * @param data
217 | * @return
218 | */
219 | public static int sizeOf(Bitmap data) {
220 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
221 | return data.getRowBytes() * data.getHeight();
222 | } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
223 | return data.getByteCount();
224 | } else {
225 | return data.getAllocationByteCount();
226 | }
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/Utils/app/src/main/java/net/the4thdimension/android/DateUtils.java:
--------------------------------------------------------------------------------
1 |
2 | package net.the4thdimension.android;
3 |
4 | import android.net.ParseException;
5 |
6 | import java.text.SimpleDateFormat;
7 | import java.util.Calendar;
8 | import java.util.Date;
9 | import java.util.Locale;
10 | import java.util.TimeZone;
11 |
12 | /***
13 | * Provides helper methods for date utilities.
14 | * Yes, some times I write shit code.
15 | */
16 | public class DateUtils {
17 |
18 | /***
19 | * Converts ISO date string to UTC timezone equivalent.
20 | *
21 | * @param dateAndTime ISO formatted time string.
22 | */
23 | public static String getUtcTime(String dateAndTime) {
24 | Date d = parseDate(dateAndTime);
25 |
26 | String format = "yyyy-MM-dd'T'HH:mm:ss'Z'";
27 | SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
28 |
29 | // Convert Local Time to UTC
30 | sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
31 |
32 | return sdf.format(d);
33 | }
34 |
35 | /****
36 | * Parses date string and return a {@link java.util.Date} object
37 | *
38 | * @return The ISO formatted date object
39 | */
40 | public static Date parseDate(String date) {
41 |
42 | if (date == null) {
43 | return null;
44 | }
45 |
46 | StringBuffer sbDate = new StringBuffer();
47 | sbDate.append(date);
48 | String newDate = null;
49 | Date dateDT = null;
50 |
51 | try {
52 | newDate = sbDate.substring(0, 19).toString();
53 | } catch (Exception e) {
54 | e.printStackTrace();
55 | }
56 |
57 | String rDate = newDate.replace("T", " ");
58 | String nDate = rDate.replaceAll("-", "/");
59 |
60 | try {
61 | dateDT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()).parse(nDate);
62 | // Log.v( TAG, "#parseDate dateDT: " + dateDT );
63 | } catch (ParseException e) {
64 | e.printStackTrace();
65 | } catch (Exception e) {
66 | e.printStackTrace();
67 | }
68 |
69 | return dateDT;
70 | }
71 |
72 | /***
73 | * Converts UTC time formatted as ISO to device local time.
74 | *
76 | *
77 | * Sample usage
78 | *
80 | *
81 | * {
82 | * SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
83 | * d = toLocalTime("2014-10-08T09:46:04.455Z", sdf);
84 | * }
85 | *
86 | *
87 | * @param utcDate
88 | * @param format
89 | * @return Date
90 | * @throws Exception
91 | */
92 | public static Date toLocalTime(String utcDate, SimpleDateFormat sdf) throws Exception {
93 |
94 | // create a new Date object using
95 | // the timezone of the specified city
96 | sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
97 | Date localDate = sdf.parse(utcDate);
98 |
99 | sdf.setTimeZone(TimeZone.getDefault());
100 | String dateFormateInUTC = sdf.format(localDate);
101 |
102 | return sdf.parse(dateFormateInUTC);
103 | }
104 |
105 | /**
106 | * Returns abbreviated (3 letters) day of the week.
107 | *
108 | * @param date ISO format date
109 | * @return The name of the day of the week
110 | */
111 | public static String getDayOfWeekAbbreviated(String date) {
112 | Date dateDT = parseDate(date);
113 |
114 | if (dateDT == null) {
115 | return null;
116 | }
117 |
118 | // Get current date
119 | Calendar c = Calendar.getInstance();
120 | // it is very important to
121 | // set the date of
122 | // the calendar.
123 | c.setTime(dateDT);
124 | int day = c.get(Calendar.DAY_OF_WEEK);
125 |
126 | String dayStr = null;
127 |
128 | switch (day) {
129 |
130 | case Calendar.SUNDAY:
131 | dayStr = "Sun";
132 | break;
133 |
134 | case Calendar.MONDAY:
135 | dayStr = "Mon";
136 | break;
137 |
138 | case Calendar.TUESDAY:
139 | dayStr = "Tue";
140 | break;
141 |
142 | case Calendar.WEDNESDAY:
143 | dayStr = "Wed";
144 | break;
145 |
146 | case Calendar.THURSDAY:
147 | dayStr = "Thu";
148 | break;
149 |
150 | case Calendar.FRIDAY:
151 | dayStr = "Fri";
152 | break;
153 |
154 | case Calendar.SATURDAY:
155 | dayStr = "Sat";
156 | break;
157 | }
158 |
159 | return dayStr;
160 | }
161 |
162 | /***
163 | * Gets the name of the month from the given date.
164 | *
165 | * @param date ISO format date
166 | * @return Returns the name of the month
167 | */
168 | public static String getMonth(String date) {
169 | Date dateDT = parseDate(date);
170 |
171 | if (dateDT == null) {
172 | return null;
173 | }
174 |
175 | // Get current date
176 | Calendar c = Calendar.getInstance();
177 | // it is very important to
178 | // set the date of
179 | // the calendar.
180 | c.setTime(dateDT);
181 | int day = c.get(Calendar.MONTH);
182 |
183 | String dayStr = null;
184 |
185 | switch (day) {
186 |
187 | case Calendar.JANUARY:
188 | dayStr = "January";
189 | break;
190 |
191 | case Calendar.FEBRUARY:
192 | dayStr = "February";
193 | break;
194 |
195 | case Calendar.MARCH:
196 | dayStr = "March";
197 | break;
198 |
199 | case Calendar.APRIL:
200 | dayStr = "April";
201 | break;
202 |
203 | case Calendar.MAY:
204 | dayStr = "May";
205 | break;
206 |
207 | case Calendar.JUNE:
208 | dayStr = "June";
209 | break;
210 |
211 | case Calendar.JULY:
212 | dayStr = "July";
213 | break;
214 |
215 | case Calendar.AUGUST:
216 | dayStr = "August";
217 | break;
218 |
219 | case Calendar.SEPTEMBER:
220 | dayStr = "September";
221 | break;
222 |
223 | case Calendar.OCTOBER:
224 | dayStr = "October";
225 | break;
226 |
227 | case Calendar.NOVEMBER:
228 | dayStr = "November";
229 | break;
230 |
231 | case Calendar.DECEMBER:
232 | dayStr = "December";
233 | break;
234 | }
235 |
236 | return dayStr;
237 | }
238 |
239 | /**
240 | * Gets abbreviated name of the month from the given date.
241 | *
242 | * @param date ISO format date
243 | * @return Returns the name of the month
244 | */
245 | public static String getMonthAbbreviated(String date) {
246 | Date dateDT = parseDate(date);
247 |
248 | if (dateDT == null) {
249 | return null;
250 | }
251 |
252 | // Get current date
253 | Calendar c = Calendar.getInstance();
254 | // it is very important to
255 | // set the date of
256 | // the calendar.
257 | c.setTime(dateDT);
258 | int day = c.get(Calendar.MONTH);
259 |
260 | String dayStr = null;
261 |
262 | switch (day) {
263 |
264 | case Calendar.JANUARY:
265 | dayStr = "Jan";
266 | break;
267 |
268 | case Calendar.FEBRUARY:
269 | dayStr = "Feb";
270 | break;
271 |
272 | case Calendar.MARCH:
273 | dayStr = "Mar";
274 | break;
275 |
276 | case Calendar.APRIL:
277 | dayStr = "Apr";
278 | break;
279 |
280 | case Calendar.MAY:
281 | dayStr = "May";
282 | break;
283 |
284 | case Calendar.JUNE:
285 | dayStr = "Jun";
286 | break;
287 |
288 | case Calendar.JULY:
289 | dayStr = "Jul";
290 | break;
291 |
292 | case Calendar.AUGUST:
293 | dayStr = "Aug";
294 | break;
295 |
296 | case Calendar.SEPTEMBER:
297 | dayStr = "Sep";
298 | break;
299 |
300 | case Calendar.OCTOBER:
301 | dayStr = "Oct";
302 | break;
303 |
304 | case Calendar.NOVEMBER:
305 | dayStr = "Nov";
306 | break;
307 |
308 | case Calendar.DECEMBER:
309 | dayStr = "Dec";
310 | break;
311 | }
312 |
313 | return dayStr;
314 | }
315 |
316 | /**
317 | * Gets a string TimeStamp phrase like 5 mins ago
318 | * yesterday, 3 days ago.
319 | *
320 | *
321 | *
322 | *
323 | * sample usage
324 | *
325 | * *
326 | *
327 | * {
328 | * String timeStamp = getTimeStamp(originalDate);
329 | *
330 | * }
331 | *
332 | *
333 | * @param originalDate
334 | * @return convertedDate String
335 | *
336 | */
337 | public static String getTimeStamp(Date originalDate){
338 |
339 | String convertedDate = DateUtils.getRelativeTimeSpanString(originalDate.getTime(),
340 | new Date().getTime(),
341 | DateUtils.SECOND_IN_MILLIS).toString();
342 |
343 | return convertedDate;
344 | }
345 |
346 |
347 | /**
348 | * Gets a string TimeStamp phrase like 5 mins ago
349 | * yesterday, 3 days ago.
350 | *
351 | *
352 | *
353 | *
354 | * sample usage
355 | *
356 | * *
357 | *
358 | * {
359 | * String timeStamp = getTimeStamp(originalDate);
360 | *
361 | * }
362 | *
363 | *
364 | * @param originalDateTime time in miliseconds since epoch
365 | * @return convertedDate String
366 | *
367 | */
368 | public static String getTimeStamp(Long originalDateTime) {
369 |
370 | String convertedDate = DateUtils.getRelativeTimeSpanString(originalDateTime,
371 | new Date().getTime(),
372 | DateUtils.SECOND_IN_MILLIS).toString();
373 |
374 | return convertedDate;
375 |
376 | }
377 |
378 | }
379 |
--------------------------------------------------------------------------------
/Utils/app/src/main/java/net/the4thdimension/android/MediaUtils.java:
--------------------------------------------------------------------------------
1 | package net.the4thdimension.android;
2 |
3 | import android.app.Activity;
4 | import android.content.ComponentName;
5 | import android.content.ContentValues;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.pm.PackageManager;
9 | import android.content.pm.ResolveInfo;
10 | import android.database.Cursor;
11 | import android.net.Uri;
12 | import android.os.Parcelable;
13 | import android.provider.MediaStore;
14 | import android.provider.MediaStore.Video;
15 | import android.support.annotation.Nullable;
16 | import android.text.TextUtils;
17 | import android.util.Log;
18 |
19 | import java.io.File;
20 | import java.io.FileInputStream;
21 | import java.io.FileNotFoundException;
22 | import java.io.FileOutputStream;
23 | import java.io.IOException;
24 | import java.io.OutputStream;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | public class MediaUtils {
29 |
30 | private static final String TAG = MediaUtils.class.getSimpleName();
31 |
32 | /**
33 | * Get runtime duration of media such as audio or video in milliseconds
34 | ****/
35 | public static long getDuration(Context ctx, Uri mediaUri) {
36 | Cursor cur = ctx.getContentResolver().query(mediaUri, new String[]{Video.Media.DURATION}, null, null, null);
37 | long duration = -1;
38 |
39 | try {
40 | if (cur != null && cur.getCount() > 0) {
41 | while (cur.moveToNext()) {
42 | duration = cur.getLong(cur.getColumnIndex(Video.Media.DURATION));
43 |
44 | if (duration == 0)
45 | Log.w(TAG, "#getMediaDuration The image size was found to be 0. Reason: UNKNOWN");
46 |
47 | } // end while
48 | } else if (cur.getCount() == 0) {
49 | Log.e(TAG, "#getMediaDuration cur size is 0. File may not exist");
50 | } else {
51 | Log.e(TAG, "#getMediaDuration cur is null");
52 | }
53 | } finally {
54 | if (cur != null && !cur.isClosed()) {
55 | cur.close();
56 | }
57 | }
58 |
59 | return duration;
60 | }
61 |
62 | /**
63 | * Checks if the parameter {@link android.net.Uri} is a Media content uri.
64 | ****/
65 | public static boolean isMediaContentUri(Uri uri) {
66 | if (!uri.toString().contains("content://media/")) {
67 | Log.w(TAG, "#isContentUri The uri is not a media content uri");
68 | return false;
69 | } else {
70 | return true;
71 | }
72 | }
73 |
74 | /**
75 | * Creates an intent to take a video from camera or gallery or any other application that can
76 | * handle the intent.
77 | *
78 | * @param ctx
79 | * @param savingUri
80 | * @param durationInSeconds
81 | * @return
82 | */
83 | public static Intent createTakeVideoIntent(Activity ctx, Uri savingUri, int durationInSeconds) {
84 |
85 | if (savingUri == null) {
86 | throw new NullPointerException("Uri cannot be null");
87 | }
88 |
89 | final List
304 | *
308 | *
309 | * @param ctx Context object
310 | * @param uri Media content uri of the image, audio or video resource
311 | */
312 | public static byte[] getMediaData(Context ctx, Uri uri) {
313 | if (uri == null) {
314 | throw new NullPointerException("Uri cannot be null");
315 | }
316 |
317 | Cursor cur = ctx.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
318 | byte[] data = null;
319 |
320 | try {
321 | if (cur != null && cur.getCount() > 0) {
322 | if (cur.moveToNext()) {
323 | String path = cur.getString(cur.getColumnIndex(MediaStore.Images.Media.DATA));
324 |
325 | try {
326 | File f = new File(path);
327 | FileInputStream fis = new FileInputStream(f);
328 | data = Utils.readStreamToBytes(fis);
329 | } catch (FileNotFoundException e) {
330 | e.printStackTrace();
331 | } catch (Exception e) {
332 | e.printStackTrace();
333 | }
334 |
335 | // Log.v( TAG, "#getVideoData byte.size: " + data.length );
336 | } // end while
337 | } else
338 | Log.e(TAG, "#getMediaData cur is null or blank");
339 | } finally {
340 | if (cur != null && !cur.isClosed()) {
341 | cur.close();
342 | }
343 | }
344 |
345 | return data;
346 | }
347 |
348 | /**
349 | * Returns true if the mime type is a standard image mime type
350 | */
351 | public static boolean isImage(String mimeType) {
352 | // TODO: apply regex patter for checking the MIME type
353 | if (mimeType != null) {
354 | if (mimeType.startsWith("image/"))
355 | return true;
356 | else
357 | return false;
358 | } else
359 | return false;
360 | }
361 |
362 | /**
363 | * Returns true if the mime type is a standard audio mime type
364 | */
365 | public static boolean isAudio(String mimeType) {
366 | // TODO: apply regex patter for checking the MIME type
367 | if (mimeType != null) {
368 | if (mimeType.startsWith("audio/"))
369 | return true;
370 | else
371 | return false;
372 | } else
373 | return false;
374 | }
375 |
376 | /**
377 | * Returns true if the mime type is a standard video mime type
378 | */
379 | public static boolean isVideo(String mimeType) {
380 | // TODO: apply regex patter for checking the MIME type
381 | if (mimeType != null) {
382 | if (mimeType.startsWith("video/"))
383 | return true;
384 | else
385 | return false;
386 | } else {
387 | return false;
388 | }
389 | }
390 |
391 | /**
392 | * Identifies if the content represented by the parameter mimeType is media. Image, Audio and
393 | * Video is treated as media by this method. You can refer to standard MIME type here. Standard MIME
395 | * types.
396 | *
397 | * @param mimeType standard MIME type of the data.
398 | */
399 | public static boolean isMedia(String mimeType) {
400 | boolean isMedia = false;
401 |
402 | if (mimeType != null) {
403 | if (mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.startsWith("audio/")) {
404 | isMedia = true;
405 | }
406 | } else {
407 | isMedia = false;
408 | }
409 |
410 | return isMedia;
411 | }
412 |
413 | /**
414 | * Get the type of the media. Audio, Video or Image.
415 | *
416 | * @return Lower case string for one of above listed media type
417 | */
418 | public static String getMediaType(String contentType) {
419 | if (isMedia(contentType)) {
420 | if (isVideo(contentType))
421 | return "video";
422 | else if (isAudio(contentType))
423 | return "audio";
424 | else if (isImage(contentType))
425 | return "image";
426 | else
427 | return null;
428 | } else {
429 | return null;
430 | }
431 | }
432 |
433 | /**
434 | * Writes the given image to the external storage of the device. If external storage is not
435 | * available, the image is written to the application private directory
436 | *
437 | * @return Path of the image file that has been written.
438 | **/
439 | public static String writeImage(Context ctx, byte[] imageData) {
440 |
441 | final String FILE_NAME = "photograph.jpeg";
442 | File dir = null;
443 | String filePath = null;
444 | OutputStream imageFileOS;
445 |
446 | dir = Utils.getStorageDirectory(ctx, null);
447 |
448 | // dir.mkdirs();
449 | File f = new File(dir, FILE_NAME);
450 |
451 | // File f = getFile( FILE_NAME );
452 |
453 | try {
454 | imageFileOS = new FileOutputStream(f);
455 | imageFileOS.write(imageData);
456 | imageFileOS.flush();
457 | imageFileOS.close();
458 | } catch (FileNotFoundException e) {
459 | e.printStackTrace();
460 | } catch (IOException e) {
461 | e.printStackTrace();
462 | } catch (Exception e) {
463 | e.printStackTrace();
464 | }
465 |
466 | filePath = f.getAbsolutePath();
467 |
468 | return filePath;
469 | }
470 | }
471 |
--------------------------------------------------------------------------------
/Utils/app/src/main/java/net/the4thdimension/android/Utils.java:
--------------------------------------------------------------------------------
1 |
2 | package net.the4thdimension.android;
3 |
4 | import android.app.Activity;
5 | import android.app.ActivityManager;
6 | import android.app.ActivityManager.RunningServiceInfo;
7 | import android.app.AlertDialog;
8 | import android.app.ProgressDialog;
9 | import android.content.ComponentName;
10 | import android.content.ContentValues;
11 | import android.content.Context;
12 | import android.content.DialogInterface;
13 | import android.content.Intent;
14 | import android.content.pm.ApplicationInfo;
15 | import android.content.pm.PackageManager;
16 | import android.content.pm.PackageManager.NameNotFoundException;
17 | import android.content.pm.ResolveInfo;
18 | import android.database.Cursor;
19 | import android.database.sqlite.SQLiteDatabase;
20 | import android.database.sqlite.SQLiteException;
21 | import android.graphics.Bitmap;
22 | import android.graphics.Bitmap.Config;
23 | import android.graphics.BitmapFactory;
24 | import android.graphics.Canvas;
25 | import android.graphics.Color;
26 | import android.graphics.Paint;
27 | import android.graphics.PorterDuff.Mode;
28 | import android.graphics.PorterDuffXfermode;
29 | import android.graphics.Rect;
30 | import android.graphics.Typeface;
31 | import android.graphics.drawable.BitmapDrawable;
32 | import android.graphics.drawable.Drawable;
33 | import android.location.Location;
34 | import android.location.LocationManager;
35 | import android.location.LocationProvider;
36 | import android.net.ConnectivityManager;
37 | import android.net.NetworkInfo;
38 | import android.net.ParseException;
39 | import android.net.Uri;
40 | import android.os.Build;
41 | import android.os.Environment;
42 | import android.os.Parcelable;
43 | import android.provider.MediaStore;
44 | import android.provider.MediaStore.Images.ImageColumns;
45 | import android.provider.MediaStore.Images.Media;
46 | import android.provider.MediaStore.MediaColumns;
47 | import android.provider.MediaStore.Video;
48 | import android.support.annotation.NonNull;
49 | import android.support.annotation.Nullable;
50 | import android.support.annotation.StringRes;
51 | import android.telephony.TelephonyManager;
52 | import android.text.Spannable;
53 | import android.text.SpannableStringBuilder;
54 | import android.text.TextUtils;
55 | import android.text.style.StyleSpan;
56 | import android.util.Base64;
57 | import android.util.Log;
58 | import android.view.inputmethod.InputMethodManager;
59 | import android.widget.TextView;
60 | import android.widget.Toast;
61 |
62 | import org.json.JSONArray;
63 | import org.json.JSONException;
64 |
65 | import java.io.BufferedReader;
66 | import java.io.ByteArrayInputStream;
67 | import java.io.ByteArrayOutputStream;
68 | import java.io.File;
69 | import java.io.FileInputStream;
70 | import java.io.FileNotFoundException;
71 | import java.io.FileOutputStream;
72 | import java.io.IOException;
73 | import java.io.InputStream;
74 | import java.io.InputStreamReader;
75 | import java.io.OutputStream;
76 | import java.lang.reflect.InvocationTargetException;
77 | import java.lang.reflect.Method;
78 | import java.net.MalformedURLException;
79 | import java.net.URISyntaxException;
80 | import java.net.URL;
81 | import java.security.MessageDigest;
82 | import java.security.NoSuchAlgorithmException;
83 | import java.text.DecimalFormat;
84 | import java.text.SimpleDateFormat;
85 | import java.util.ArrayList;
86 | import java.util.Calendar;
87 | import java.util.Date;
88 | import java.util.GregorianCalendar;
89 | import java.util.List;
90 | import java.util.Random;
91 | import java.util.TimeZone;
92 | import java.util.regex.Matcher;
93 | import java.util.regex.Pattern;
94 |
95 |
96 | /**
97 | * Provides convenience methods and abstractions to some tasks in Android
98 | *
99 | *
100 | *
101 | *
102 | * @author Jay
103 | */
104 | public class Utils {
105 |
106 | private static final String TAG = Utils.class.getSimpleName();
107 |
108 | static ProgressDialog mProgressDialog;
109 |
110 | /**
111 | * Shows a long time duration toast message.
112 | *
113 | * @param msg Message to be show in the toast.
114 | * @return Toast object just shown
115 | **/
116 | public static Toast showToast(Context ctx, CharSequence msg) {
117 | return showToast(ctx, msg, Toast.LENGTH_LONG);
118 | }
119 |
120 | /**
121 | * Shows the message passed in the parameter in the Toast.
122 | *
123 | * @param msg Message to be show in the toast.
124 | * @param duration Duration in milliseconds for which the toast should be shown
125 | * @return Toast object just shown
126 | **/
127 | public static Toast showToast(Context ctx, CharSequence msg, int duration) {
128 | Toast toast = Toast.makeText(ctx, msg, Toast.LENGTH_SHORT);
129 | toast.setDuration(duration);
130 | toast.show();
131 | return toast;
132 | }
133 |
134 | /**
135 | * Checks if the Internet connection is available.
136 | *
137 | * @return Returns true if the Internet connection is available. False otherwise.
138 | **/
139 | public static boolean isInternetAvailable(Context ctx) {
140 | // using received context (typically activity) to get SystemService causes memory link as this holds strong reference to that activity.
141 | // use application level context instead, which is available until the app dies.
142 | ConnectivityManager connectivityManager = (ConnectivityManager) ctx.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
143 |
144 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
145 |
146 | // if network is NOT available networkInfo will be null
147 | // otherwise check if we are connected
148 | if (networkInfo != null && networkInfo.isConnected()) {
149 | return true;
150 | }
151 |
152 | return false;
153 | }
154 |
155 | /**
156 | * Checks if the SD Card is mounted on the device.
157 | **/
158 | public static boolean isSdCardMounted() {
159 | String status = Environment.getExternalStorageState();
160 |
161 | if (status != null && status.equals(Environment.MEDIA_MOUNTED)) {
162 | return true;
163 | }
164 |
165 | return false;
166 | }
167 |
168 | /**
169 | * Shows an alert dialog with the OK button. When the user presses OK button, the dialog
170 | * dismisses.
171 | **/
172 | public static void showAlertDialog(Context context, @StringRes int titleResId, @StringRes int bodyResId) {
173 | showAlertDialog(context, context.getString(titleResId),
174 | context.getString(bodyResId), null);
175 | }
176 |
177 | /**
178 | * Shows an alert dialog with the OK button. When the user presses OK button, the dialog
179 | * dismisses.
180 | **/
181 | public static void showAlertDialog(Context context, String title, String body) {
182 | showAlertDialog(context, title, body, null);
183 | }
184 |
185 | /**
186 | * Shows an alert dialog with OK button
187 | **/
188 | public static void showAlertDialog(Context context, String title, String body, DialogInterface.OnClickListener okListener) {
189 |
190 | if (okListener == null) {
191 | okListener = new DialogInterface.OnClickListener() {
192 |
193 | public void onClick(DialogInterface dialog, int which) {
194 | dialog.cancel();
195 | }
196 | };
197 | }
198 |
199 | AlertDialog.Builder builder = new AlertDialog.Builder(context)
200 | .setMessage(body).setPositiveButton("OK", okListener);
201 |
202 | if (!TextUtils.isEmpty(title)) {
203 | builder.setTitle(title);
204 | }
205 |
206 | builder.show();
207 | }
208 |
209 | /**
210 | * Serializes the Bitmap to Base64
211 | *
212 | * @return Base64 string value of a {@linkplain android.graphics.Bitmap} passed in as a parameter
213 | * @throws NullPointerException If the parameter bitmap is null.
214 | **/
215 | public static String toBase64(Bitmap bitmap) {
216 |
217 | if (bitmap == null) {
218 | throw new NullPointerException("Bitmap cannot be null");
219 | }
220 |
221 | String base64Bitmap = null;
222 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
223 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
224 | byte[] imageBitmap = stream.toByteArray();
225 | base64Bitmap = Base64.encodeToString(imageBitmap, Base64.DEFAULT);
226 |
227 | return base64Bitmap;
228 | }
229 |
230 | /**
231 | * Converts the passed in drawable to Bitmap representation
232 | *
233 | * @throws NullPointerException If the parameter drawable is null.
234 | **/
235 | public static Bitmap drawableToBitmap(Drawable drawable) {
236 |
237 | if (drawable == null) {
238 | throw new NullPointerException("Drawable to convert should NOT be null");
239 | }
240 |
241 | if (drawable instanceof BitmapDrawable) {
242 | return ((BitmapDrawable) drawable).getBitmap();
243 | }
244 |
245 | if (drawable.getIntrinsicWidth() <= 0 && drawable.getIntrinsicHeight() <= 0) {
246 | return null;
247 | }
248 |
249 | Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
250 | Canvas canvas = new Canvas(bitmap);
251 | drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
252 | drawable.draw(canvas);
253 |
254 | return bitmap;
255 | }
256 |
257 | /**
258 | * Converts the given bitmap to {@linkplain java.io.InputStream}.
259 | *
260 | * @throws NullPointerException If the parameter bitmap is null.
261 | **/
262 | public static InputStream bitmapToInputStream(Bitmap bitmap) throws NullPointerException {
263 |
264 | if (bitmap == null) {
265 | throw new NullPointerException("Bitmap cannot be null");
266 | }
267 |
268 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
269 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
270 | InputStream inputstream = new ByteArrayInputStream(baos.toByteArray());
271 |
272 | return inputstream;
273 | }
274 |
275 | /**
276 | * Shows a progress dialog with a spinning animation in it. This method must preferably called
277 | * from a UI thread.
278 | *
279 | * @param ctx Activity context
280 | * @param title Title of the progress dialog
281 | * @param body Body/Message to be shown in the progress dialog
282 | * @param isCancellable True if the dialog can be cancelled on back button press, false otherwise
283 | **/
284 | public static void showProgressDialog(Context ctx, String title, String body, boolean isCancellable) {
285 | showProgressDialog(ctx, title, body, null, isCancellable);
286 | }
287 |
288 | /**
289 | * Shows a progress dialog with a spinning animation in it. This method must preferably called
290 | * from a UI thread.
291 | *
292 | * @param ctx Activity context
293 | * @param title Title of the progress dialog
294 | * @param body Body/Message to be shown in the progress dialog
295 | * @param icon Icon to show in the progress dialog. It can be null.
296 | * @param isCancellable True if the dialog can be cancelled on back button press, false otherwise
297 | **/
298 | public static void showProgressDialog(Context ctx, String title, String body, Drawable icon, boolean isCancellable) {
299 |
300 | if (ctx instanceof Activity) {
301 | if (!((Activity) ctx).isFinishing()) {
302 | mProgressDialog = ProgressDialog.show(ctx, title, body, true);
303 | mProgressDialog.setIcon(icon);
304 | mProgressDialog.setCancelable(isCancellable);
305 | }
306 | }
307 | }
308 |
309 | /**
310 | * Check if the {@link android.app.ProgressDialog} is visible in the UI.
311 | **/
312 | public static boolean isProgressDialogVisible() {
313 | return (mProgressDialog != null);
314 | }
315 |
316 | /**
317 | * Dismiss the progress dialog if it is visible.
318 | **/
319 | public static void dismissProgressDialog() {
320 |
321 | if (mProgressDialog != null) {
322 | mProgressDialog.dismiss();
323 | }
324 |
325 | mProgressDialog = null;
326 | }
327 |
328 | /**
329 | * Gives the device independent constant which can be used for scaling images, manipulating view
330 | * sizes and changing dimension and display pixels etc.
331 | **/
332 | public static float getDensityMultiplier(Context context) {
333 | return context.getResources().getDisplayMetrics().density;
334 | }
335 |
336 | /**
337 | * This method converts device specific pixels to density independent pixels.
338 | *
339 | * @param px A value in px (pixels) unit. Which we need to convert into db
340 | * @param context Context to get resources and device specific display metrics
341 | * @return A int value to represent dp equivalent to px value
342 | */
343 | public static int getDip(int px, Context context) {
344 | final float scale = context.getResources().getDisplayMetrics().density;
345 | return (int) (px * scale + 0.5f);
346 | }
347 |
348 | /**
349 | * Creates a confirmation dialog with Yes-No Button. By default the buttons just dismiss the
350 | * dialog.
351 | *
352 | * @param ctx
353 | * @param message Message to be shown in the dialog.
354 | * @param yesListener Yes click handler
355 | * @param noListener
356 | **/
357 | public static void showConfirmDialog(Context ctx, String message, DialogInterface.OnClickListener yesListener, DialogInterface.OnClickListener noListener) {
358 | showConfirmDialog(ctx, message, yesListener, noListener, "Yes", "No");
359 | }
360 |
361 | /**
362 | * Creates a confirmation dialog with Yes-No Button. By default the buttons just dismiss the
363 | * dialog.
364 | *
365 | * @param ctx
366 | * @param message Message to be shown in the dialog.
367 | * @param yesListener Yes click handler
368 | * @param noListener
369 | * @param yesLabel Label for yes button
370 | * @param noLabel Label for no button
371 | **/
372 | public static void showConfirmDialog(Context ctx, String message, DialogInterface.OnClickListener yesListener, DialogInterface.OnClickListener noListener, String yesLabel, String noLabel) {
373 |
374 | AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
375 |
376 | if (yesListener == null) {
377 | yesListener = new DialogInterface.OnClickListener() {
378 |
379 | @Override
380 | public void onClick(DialogInterface dialog, int which) {
381 | dialog.dismiss();
382 | }
383 | };
384 | }
385 |
386 | if (noListener == null) {
387 | noListener = new DialogInterface.OnClickListener() {
388 |
389 | public void onClick(DialogInterface dialog, int which) {
390 | dialog.dismiss();
391 | }
392 | };
393 | }
394 |
395 | builder.setMessage(message).setPositiveButton(yesLabel, yesListener).setNegativeButton(noLabel, noListener).show();
396 | }
397 |
398 | /**
399 | * Creates a confirmation dialog that show a pop-up with button labeled as parameters labels.
400 | *
401 | * @param ctx {@link android.app.Activity} {@link android.content.Context}
402 | * @param message Message to be shown in the dialog.
403 | * @param dialogClickListener
404 | * @param positiveBtnLabel For e.g. "Yes"
405 | * @param negativeBtnLabel For e.g. "No"
406 | **/
407 | public static void showDialog(Context ctx, String message, String positiveBtnLabel, String negativeBtnLabel, DialogInterface.OnClickListener dialogClickListener) {
408 |
409 | if (dialogClickListener == null) {
410 | throw new NullPointerException("Action listener cannot be null");
411 | }
412 |
413 | AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
414 |
415 | builder.setMessage(message).setPositiveButton(positiveBtnLabel, dialogClickListener).setNegativeButton(negativeBtnLabel, dialogClickListener).show();
416 | }
417 |
418 | /**
419 | * Gets the version name of the application. For e.g. 1.9.3
420 | **/
421 | public static String getApplicationVersionNumber(Context context) {
422 |
423 | String versionName = null;
424 |
425 | if (context == null) {
426 | return versionName;
427 | }
428 |
429 | try {
430 | versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
431 | } catch (NameNotFoundException e) {
432 | e.printStackTrace();
433 | }
434 |
435 | return versionName;
436 | }
437 |
438 | /**
439 | * Gets the version code of the application. For e.g. Maverick Meerkat or 2013050301
440 | **/
441 | public static int getApplicationVersionCode(Context ctx) {
442 |
443 | int versionCode = 0;
444 |
445 | try {
446 | versionCode = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0).versionCode;
447 | } catch (NameNotFoundException e) {
448 | e.printStackTrace();
449 | }
450 |
451 | return versionCode;
452 | }
453 |
454 | /**
455 | * Gets the version number of the Android OS For e.g. 2.3.4 or 4.1.2
456 | **/
457 | public static String getOsVersion() {
458 | return Build.VERSION.RELEASE;
459 | }
460 |
461 | /**
462 | * Checks if the service with the given name is currently running on the device.
463 | *
464 | * @param serviceName Fully qualified name of the server.
465 | * For e.g. nl.changer.myservice.name
466 | **/
467 | public static boolean isServiceRunning(Context ctx, String serviceName) {
468 |
469 | if (serviceName == null) {
470 | throw new NullPointerException("Service name cannot be null");
471 | }
472 |
473 | // use application level context to avoid unnecessary leaks.
474 | ActivityManager manager = (ActivityManager) ctx.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
475 | for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
476 | if (service.service.getClassName().equals(serviceName)) {
477 | return true;
478 | }
479 | }
480 |
481 | return false;
482 | }
483 |
484 | /**
485 | * Gets the device unique id called IMEI. Sometimes, this returns 00000000000000000 for the
486 | * rooted devices.
487 | **/
488 | public static String getDeviceImei(Context ctx) {
489 | // use application level context to avoid unnecessary leaks.
490 | TelephonyManager telephonyManager = (TelephonyManager) ctx.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
491 | return telephonyManager.getDeviceId();
492 | }
493 |
494 | /**
495 | * Shares an application over the social network like Facebook, Twitter etc.
496 | *
497 | * @param sharingMsg Message to be pre-populated when the 3rd party app dialog opens up.
498 | * @param emailSubject Message that shows up as a subject while sharing through email.
499 | * @param title Title of the sharing options prompt. For e.g. "Share via" or "Share using"
500 | **/
501 | public static void share(Context ctx, String sharingMsg, String emailSubject, String title) {
502 | Intent sharingIntent = new Intent(Intent.ACTION_SEND);
503 |
504 | sharingIntent.setType("text/plain");
505 | sharingIntent.putExtra(Intent.EXTRA_TEXT, sharingMsg);
506 | sharingIntent.putExtra(Intent.EXTRA_SUBJECT, emailSubject);
507 |
508 | ctx.startActivity(Intent.createChooser(sharingIntent, title));
509 | }
510 |
511 | /**
512 | * Checks the type of data connection that is currently available on the device.
513 | *
514 | * @return ConnectivityManager.TYPE_* as a type of internet connection on the
515 | * device. Returns -1 in case of error or none of
516 | * ConnectivityManager.TYPE_* is found.
517 | **/
518 | public static int getDataConnectionType(Context ctx) {
519 |
520 | // use application level context to avoid unnecessary leaks.
521 | ConnectivityManager connectivityManager = (ConnectivityManager) ctx.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
522 |
523 | if (connectivityManager != null && connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) != null) {
524 | if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected()) {
525 | return ConnectivityManager.TYPE_MOBILE;
526 | } else if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
527 | return ConnectivityManager.TYPE_WIFI;
528 | } else
529 | return -1;
530 | } else
531 | return -1;
532 | }
533 |
534 | /**
535 | * Checks if the input parameter is a valid email.
536 | *
537 | * @param email
538 | * @return
539 | */
540 | public static boolean isValidEmail(String email) {
541 |
542 | if (email == null) {
543 | return false;
544 | }
545 |
546 | final String emailPattern = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
547 | Matcher matcher;
548 | Pattern pattern = Pattern.compile(emailPattern);
549 |
550 | matcher = pattern.matcher(email);
551 |
552 | if (matcher != null) {
553 | return matcher.matches();
554 | } else {
555 | return false;
556 | }
557 | }
558 |
559 | @Nullable
560 | /**
561 | * Capitalizes each word in the string.
562 | * @param string
563 | * @return
564 | */
565 | public static String capitalizeString(String string) {
566 |
567 | if (string == null) {
568 | return null;
569 | }
570 |
571 | char[] chars = string.toLowerCase().toCharArray();
572 | boolean found = false;
573 | for (int i = 0; i < chars.length; i++) {
574 | if (!found && Character.isLetter(chars[i])) {
575 | chars[i] = Character.toUpperCase(chars[i]);
576 | found = true;
577 | } else if (Character.isWhitespace(chars[i]) || chars[i] == '.' || chars[i] == '\'') { // You
578 | // can add other
579 | // chars here
580 | found = false;
581 | }
582 | } // end for
583 |
584 | return String.valueOf(chars);
585 | }
586 |
587 | /**
588 | * Checks if the DB with the given name is present on the device.
589 | *
590 | * @param packageName
591 | * @param dbName
592 | * @return
593 | */
594 | public static boolean isDatabasePresent(String packageName, String dbName) {
595 | SQLiteDatabase sqLiteDatabase = null;
596 | try {
597 | sqLiteDatabase = SQLiteDatabase.openDatabase("/data/data/" + packageName + "/databases/" + dbName, null, SQLiteDatabase.OPEN_READONLY);
598 | sqLiteDatabase.close();
599 | } catch (SQLiteException e) {
600 | // database doesn't exist yet.
601 | e.printStackTrace();
602 | Log.e(TAG, "The database does not exist." + e.getMessage());
603 | } catch (Exception e) {
604 | e.printStackTrace();
605 | Log.e(TAG, "Exception " + e.getMessage());
606 | }
607 |
608 | return (sqLiteDatabase != null);
609 | }
610 |
611 | /**
612 | * Get the file path from the Media Content Uri for video, audio or images.
613 | *
614 | * @param mediaContentUri Media content Uri.
615 | **/
616 | public static String getPathForMediaUri(Context context, Uri mediaContentUri) {
617 |
618 | Cursor cur = null;
619 | String path = null;
620 |
621 | try {
622 | String[] projection = {MediaColumns.DATA};
623 | cur = context.getContentResolver().query(mediaContentUri, projection, null, null, null);
624 |
625 | if (cur != null && cur.getCount() != 0) {
626 | cur.moveToFirst();
627 | path = cur.getString(cur.getColumnIndexOrThrow(MediaColumns.DATA));
628 | }
629 |
630 | // Log.v( TAG, "#getRealPathFromURI Path: " + path );
631 | } catch (Exception e) {
632 | e.printStackTrace();
633 | } finally {
634 | if (cur != null && !cur.isClosed())
635 | cur.close();
636 | }
637 |
638 | return path;
639 | }
640 |
641 | public static ArrayList
1070 | *
1071 | *
1072 | * @param compressionFactor Powers of 2 are often faster/easier for the decoder to honor
1073 | */
1074 | public static Bitmap compressImage(Bitmap sourceBitmap, int compressionFactor) {
1075 | BitmapFactory.Options opts = new BitmapFactory.Options();
1076 | opts.inPreferredConfig = Config.ARGB_8888;
1077 | opts.inSampleSize = compressionFactor;
1078 |
1079 | if (Build.VERSION.SDK_INT >= 10) {
1080 | opts.inPreferQualityOverSpeed = true;
1081 | }
1082 |
1083 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
1084 | sourceBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
1085 | byte[] byteArray = stream.toByteArray();
1086 |
1087 | Bitmap image = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, opts);
1088 |
1089 | return image;
1090 | }
1091 |
1092 | private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
1093 | // Raw height and width of image
1094 | final int height = options.outHeight;
1095 | final int width = options.outWidth;
1096 | int inSampleSize = 1;
1097 |
1098 | if (height > reqHeight || width > reqWidth) {
1099 |
1100 | // Calculate ratios of height and width to requested height and
1101 | // width
1102 | final int heightRatio = Math.round((float) height / (float) reqHeight);
1103 | final int widthRatio = Math.round((float) width / (float) reqWidth);
1104 |
1105 | // Choose the smallest ratio as inSampleSize value, this will
1106 | // guarantee
1107 | // a final image with both dimensions larger than or equal to the
1108 | // requested height and width.
1109 | inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
1110 | }
1111 |
1112 | return inSampleSize;
1113 | }
1114 |
1115 | /**
1116 | * Provide the height to which the sourceImage is to be resized. This method will calculate the
1117 | * resultant height. Use scaleDownBitmap from {@link Utils} wherever possible
1118 | */
1119 | public Bitmap resizeImageByHeight(int height, Bitmap sourceImage) {
1120 | // TODO: move this method to ImageUtils
1121 | int widthO = 0; // original width
1122 | int heightO = 0; // original height
1123 | int widthNew = 0;
1124 | int heightNew = 0;
1125 |
1126 | widthO = sourceImage.getWidth();
1127 | heightO = sourceImage.getHeight();
1128 | heightNew = height;
1129 |
1130 | // Maintain the aspect ratio
1131 | // of the original banner image.
1132 | widthNew = (heightNew * widthO) / heightO;
1133 |
1134 | return Bitmap.createScaledBitmap(sourceImage, widthNew, heightNew, true);
1135 | }
1136 |
1137 | /**
1138 | * Checks if the url is valid
1139 | */
1140 | public static boolean isValidURL(String url) {
1141 | URL urlObj;
1142 |
1143 | try {
1144 | urlObj = new URL(url);
1145 | } catch (MalformedURLException e) {
1146 | return false;
1147 | }
1148 |
1149 | try {
1150 | urlObj.toURI();
1151 | } catch (URISyntaxException e) {
1152 | return false;
1153 | }
1154 |
1155 | return true;
1156 | }
1157 |
1158 | @Nullable
1159 | /**
1160 | * @return Lower case string for one of above listed media type
1161 | * @deprecated Use {@link MediaUtils#getMediaType(Uri)}
1162 | * Get the type of the media. Audio, Video or Image.
1163 | */
1164 | public static String getMediaType(String contentType) {
1165 | if (isMedia(contentType)) {
1166 | if (isVideo(contentType)) {
1167 | return "video";
1168 | } else if (isAudio(contentType)) {
1169 | return "audio";
1170 | } else if (isImage(contentType)) {
1171 | return "image";
1172 | } else {
1173 | return null;
1174 | }
1175 | } else {
1176 | return null;
1177 | }
1178 | }
1179 |
1180 | /**
1181 | * @param mimeType standard MIME type of the data.
1182 | * @deprecated {@link MediaUtils#isMedia(String)}
1183 | * Identifies if the content represented by the parameter mimeType is media. Image, Audio and
1184 | * Video is treated as media by this method. You can refer to standard MIME type here. Standard MIME
1186 | * types.
1187 | */
1188 | public static boolean isMedia(String mimeType) {
1189 | boolean isMedia = false;
1190 |
1191 | if (mimeType != null) {
1192 | if (mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.startsWith("audio/")) {
1193 | isMedia = true;
1194 | }
1195 | } else {
1196 | isMedia = false;
1197 | }
1198 |
1199 | return isMedia;
1200 | }
1201 |
1202 | /**
1203 | * Gets the Uri without the fragment. For e.g if the uri is
1204 | * content://com.android.storage/data/images/48829#is_png the part after '#' is called as
1205 | * fragment. This method strips the fragment and returns the url.
1206 | */
1207 | public static String removeUriFragment(String url) {
1208 |
1209 | if (url == null || url.length() == 0) {
1210 | return null;
1211 | }
1212 |
1213 | String[] arr = url.split("#");
1214 |
1215 | if (arr.length == 2) {
1216 | return arr[0];
1217 | } else {
1218 | return url;
1219 | }
1220 | }
1221 |
1222 | /**
1223 | * Removes the parameters from the query from the uri
1224 | */
1225 | public static String removeQueryParameters(Uri uri) {
1226 | assert (uri.getAuthority() != null);
1227 | assert (uri.getPath() != null);
1228 | Uri.Builder builder = new Uri.Builder();
1229 | builder.scheme(uri.getScheme());
1230 | builder.encodedAuthority(uri.getAuthority());
1231 | builder.encodedPath(uri.getPath());
1232 | return builder.build().toString();
1233 | }
1234 |
1235 | /**
1236 | * @deprecated Use {@link MediaUtils#isImage(String)}
1237 | * Returns true if the mime type is a standard image mime type
1238 | */
1239 | public static boolean isImage(String mimeType) {
1240 | if (mimeType != null) {
1241 | if (mimeType.startsWith("image/")) {
1242 | return true;
1243 | } else {
1244 | return false;
1245 | }
1246 | } else {
1247 | return false;
1248 | }
1249 | }
1250 |
1251 | /**
1252 | * @deprecated Use {@link MediaUtils#isAudio(String)}
1253 | * Returns true if the mime type is a standard audio mime type
1254 | */
1255 | public static boolean isAudio(String mimeType) {
1256 | if (mimeType != null) {
1257 | if (mimeType.startsWith("audio/")) {
1258 | return true;
1259 | } else {
1260 | return false;
1261 | }
1262 | } else {
1263 | return false;
1264 | }
1265 | }
1266 |
1267 | /**
1268 | * @deprecated Use {@link MediaUtils#isVideo(String)}
1269 | * Returns true if the mime type is a standard video mime type
1270 | */
1271 | public static boolean isVideo(String mimeType) {
1272 | if (mimeType != null) {
1273 | if (mimeType.startsWith("video/")) {
1274 | return true;
1275 | } else {
1276 | return false;
1277 | }
1278 | } else {
1279 | return false;
1280 | }
1281 | }
1282 |
1283 | @Nullable
1284 | /**
1285 | * @deprecated This is a monster that will lead to OutOfMemory exception some day and the world
1286 | * will come to an end.
1287 | * Gets the media data from the one of the following media {@link android.content.ContentProvider} This method
1288 | * should not be called from the main thread of the application. Calling this method may have
1289 | * performance issues as this may allocate a huge memory array.
1290 | *
1291 | *
1295 | *
1296 | * @param context Context object
1297 | * @param uri Media content uri of the image, audio or video resource
1298 | */
1299 | public static byte[] getMediaData(Context context, Uri uri) {
1300 | if (uri == null) {
1301 | throw new NullPointerException("Uri cannot be null");
1302 | }
1303 |
1304 | Cursor cursor = context.getContentResolver().query(uri, new String[]{Media.DATA}, null, null, null);
1305 | byte[] data = null;
1306 |
1307 | try {
1308 | if (cursor != null && cursor.getCount() > 0) {
1309 | if (cursor.moveToNext()) {
1310 | String path = cursor.getString(cursor.getColumnIndex(Media.DATA));
1311 |
1312 | try {
1313 | File file = new File(path);
1314 | FileInputStream fileInputStream = new FileInputStream(file);
1315 | data = readStreamToBytes(fileInputStream);
1316 | } catch (FileNotFoundException e) {
1317 | e.printStackTrace();
1318 | } catch (Exception e) {
1319 | e.printStackTrace();
1320 | }
1321 |
1322 | // Log.v( TAG, "#getVideoData byte.size: " + data.length );
1323 | } // end while
1324 | } else {
1325 | Log.e(TAG, "#getMediaData cur is null or blank");
1326 | }
1327 | } finally {
1328 | if (cursor != null && !cursor.isClosed()) {
1329 | cursor.close();
1330 | }
1331 | }
1332 |
1333 | return data;
1334 | }
1335 |
1336 | /**
1337 | * Convert {@linkplain java.io.InputStream} to byte array.
1338 | *
1339 | * @throws NullPointerException If input parameter {@link java.io.InputStream} is null
1340 | **/
1341 | public static byte[] readStreamToBytes(InputStream inputStream) {
1342 |
1343 | if (inputStream == null) {
1344 | throw new NullPointerException("InputStream is null");
1345 | }
1346 |
1347 | byte[] bytesData = null;
1348 | BufferedReader reader = null;
1349 | try {
1350 | reader = new BufferedReader(new InputStreamReader(inputStream));
1351 | ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1352 |
1353 | int nRead;
1354 | byte[] data = new byte[16384];
1355 |
1356 | while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
1357 | buffer.write(data, 0, nRead);
1358 | }
1359 |
1360 | buffer.flush();
1361 |
1362 | bytesData = buffer.toByteArray();
1363 |
1364 | // Log.d( TAG, "#readStream data: " + data );
1365 | } catch (IOException e) {
1366 | e.printStackTrace();
1367 | } catch (Exception e) {
1368 | e.printStackTrace();
1369 | } finally {
1370 |
1371 | if (reader != null) {
1372 | try {
1373 | reader.close();
1374 |
1375 | if (inputStream != null)
1376 | inputStream.close();
1377 | } catch (IOException e) {
1378 | e.printStackTrace();
1379 | } catch (Exception e) {
1380 | e.printStackTrace();
1381 | }
1382 | }
1383 | } // finally
1384 |
1385 | return bytesData;
1386 | }
1387 |
1388 | /**
1389 | * @param mediaUri uri to the media resource. For e.g. content://media/external/images/media/45490 or
1390 | * content://media/external/video/media/45490
1391 | * @return Size in bytes
1392 | * @deprecated Use {@link MediaUtils#getMediaSize(Context, Uri)}
1393 | * Gets the size of the media resource pointed to by the paramter mediaUri.
1394 | *
1395 | * Known bug: for unknown reason, the image size for some images was found to be 0
1396 | **/
1397 | public static long getMediaSize(Context context, Uri mediaUri) {
1398 | Cursor cur = context.getContentResolver().query(mediaUri, new String[]{Media.SIZE}, null, null, null);
1399 | long size = -1;
1400 |
1401 | try {
1402 | if (cur != null && cur.getCount() > 0) {
1403 | while (cur.moveToNext()) {
1404 | size = cur.getLong(cur.getColumnIndex(Media.SIZE));
1405 |
1406 | // for unknown reason, the image size for image was found to
1407 | // be 0
1408 | // Log.v( TAG, "#getSize byte.size: " + size );
1409 |
1410 | if (size == 0)
1411 | Log.w(TAG, "#getSize The media size was found to be 0. Reason: UNKNOWN");
1412 |
1413 | } // end while
1414 | } else if (cur.getCount() == 0) {
1415 | Log.e(TAG, "#getMediaSize cur size is 0. File may not exist");
1416 | } else {
1417 | Log.e(TAG, "#getMediaSize cur is null");
1418 | }
1419 | } finally {
1420 | if (cur != null && !cur.isClosed()) {
1421 | cur.close();
1422 | }
1423 | }
1424 |
1425 | return size;
1426 | }
1427 |
1428 | /**
1429 | * @deprecated {@link MediaUtils#getMediaFileName(Context, Uri)}
1430 | * Gets media file name.
1431 | **/
1432 | public static String getMediaFileName(Context ctx, Uri mediaUri) {
1433 | String colName = MediaColumns.DISPLAY_NAME;
1434 | Cursor cur = ctx.getContentResolver().query(mediaUri, new String[]{colName}, null, null, null);
1435 | String dispName = null;
1436 |
1437 | try {
1438 | if (cur != null && cur.getCount() > 0) {
1439 | while (cur.moveToNext()) {
1440 | dispName = cur.getString(cur.getColumnIndex(colName));
1441 |
1442 | // for unknown reason, the image size for image was found to
1443 | // be 0
1444 | // Log.v( TAG, "#getMediaFileName byte.size: " + size );
1445 |
1446 | if (TextUtils.isEmpty(colName)) {
1447 | Log.w(TAG, "#getMediaFileName The file name is blank or null. Reason: UNKNOWN");
1448 | }
1449 |
1450 | } // end while
1451 | } else if (cur != null && cur.getCount() == 0) {
1452 | Log.e(TAG, "#getMediaFileName File may not exist");
1453 | } else {
1454 | Log.e(TAG, "#getMediaFileName cur is null");
1455 | }
1456 | } finally {
1457 | if (cur != null && !cur.isClosed()) {
1458 | cur.close();
1459 | }
1460 | }
1461 |
1462 | return dispName;
1463 | }
1464 |
1465 | @Nullable
1466 | /**
1467 | * @deprecated Use {@link MediaUtils#getMediaType(Uri)}
1468 | * Gets media type from the Uri.
1469 | */
1470 | public static String getMediaType(Uri uri) {
1471 | if (uri == null) {
1472 | return null;
1473 | }
1474 |
1475 | String uriStr = uri.toString();
1476 |
1477 | if (uriStr.contains("video")) {
1478 | return "video";
1479 | } else if (uriStr.contains("audio")) {
1480 | return "audio";
1481 | } else if (uriStr.contains("image")) {
1482 | return "image";
1483 | } else {
1484 | return null;
1485 | }
1486 | }
1487 |
1488 | /**
1489 | * @param sourceText String to be converted to bold.
1490 | * @deprecated Use {@link #toBold(String, String)}
1491 | * Returns {@link android.text.SpannableString} in Bold typeface
1492 | */
1493 | public static SpannableStringBuilder toBold(String sourceText) {
1494 |
1495 | if (sourceText == null) {
1496 | throw new NullPointerException("String to convert cannot be bold");
1497 | }
1498 |
1499 | final SpannableStringBuilder sb = new SpannableStringBuilder(sourceText);
1500 |
1501 | // Span to set text color to some RGB value
1502 | final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD);
1503 |
1504 | // set text bold
1505 | sb.setSpan(bss, 0, sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
1506 | return sb;
1507 | }
1508 |
1509 | /**
1510 | * Typefaces the string as bold.
1511 | * If sub-string is null, entire string will be typefaced as bold and returned.
1512 | *
1513 | * @param string
1514 | * @param subString The subString within the string to bold. Pass null to bold entire string.
1515 | * @return {@link android.text.SpannableString}
1516 | */
1517 | public static SpannableStringBuilder toBold(String string, String subString) {
1518 | if (TextUtils.isEmpty(string)) {
1519 | return new SpannableStringBuilder("");
1520 | }
1521 |
1522 | SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(string);
1523 |
1524 | StyleSpan bss = new StyleSpan(Typeface.BOLD);
1525 | if (subString != null) {
1526 | int substringNameStart = string.toLowerCase().indexOf(subString);
1527 | if (substringNameStart > -1) {
1528 | spannableBuilder.setSpan(bss, substringNameStart, substringNameStart + subString.length(),
1529 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1530 | }
1531 | } else {
1532 | // set entire text to bold
1533 | spannableBuilder.setSpan(bss, 0, spannableBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
1534 | }
1535 | return spannableBuilder;
1536 | }
1537 |
1538 | /**
1539 | * Formats given size in bytes to KB, MB, GB or whatever. This will work up to 1000 TB
1540 | */
1541 | public static String formatSize(long size) {
1542 |
1543 | if (size <= 0) return "0";
1544 |
1545 | final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
1546 | int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
1547 | return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
1548 | }
1549 |
1550 | /**
1551 | * Formats given size in bytes to KB, MB, GB or whatever. Preferably use this method for
1552 | * performance efficiency.
1553 | *
1554 | * @param si Controls byte value precision. If true, formatting is done using approx. 1000 Uses
1555 | * 1024 if false.
1556 | **/
1557 | public static String formatSize(long bytes, boolean si) {
1558 | int unit = si ? 1000 : 1024;
1559 |
1560 | if (bytes < unit) {
1561 | return bytes + " B";
1562 | }
1563 |
1564 | int exp = (int) (Math.log(bytes) / Math.log(unit));
1565 | String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
1566 | return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
1567 | }
1568 |
1569 | /**
1570 | * Creates the uri to a file located on external storage or application internal storage.
1571 | */
1572 | public static Uri createUri(Context ctx) {
1573 | File root = getStorageDirectory(ctx, null);
1574 | root.mkdirs();
1575 | File file = new File(root, Long.toString(new Date().getTime()));
1576 | Uri uri = Uri.fromFile(file);
1577 |
1578 | return uri;
1579 | }
1580 |
1581 | /**
1582 | * @param ctx
1583 | * @param savingUri
1584 | * @param durationInSeconds
1585 | * @return
1586 | * @deprecated Use {@link MediaUtils#createTakeVideoIntent(Activity, Uri, int)}
1587 | * Creates an intent to take a video from camera or gallery or any other application that can
1588 | * handle the intent.
1589 | */
1590 | public static Intent createTakeVideoIntent(Activity ctx, Uri savingUri, int durationInSeconds) {
1591 |
1592 | if (savingUri == null) {
1593 | throw new NullPointerException("Uri cannot be null");
1594 | }
1595 |
1596 | final List