dentex.youtube.downloader.utils.Utils.java Source code

Java tutorial

Introduction

Here is the source code for dentex.youtube.downloader.utils.Utils.java

Source

/***
Copyright (c) 2012-2013 Samuele Rini
    
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
       
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.
       
   You should have received a copy of the GNU General Public License
   along with this program. If not, see http://www.gnu.org/licenses
       
   ***
       
   https://github.com/dentex/ytdownloader/
https://sourceforge.net/projects/ytdownloader/
       
   ***
       
   Different Licenses and Credits where noted in code comments.
*/

package dentex.youtube.downloader.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Locale;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.res.Configuration;
import android.database.Cursor;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.bugsense.trace.BugSenseHandler;

import dentex.youtube.downloader.R;
import dentex.youtube.downloader.SettingsActivity;
import dentex.youtube.downloader.YTD;

public class Utils {

    static String DEBUG_TAG = "Utils";
    static MediaScannerConnection msc;

    public static void reload(Activity activity) {
        //finish
        activity.finish();
        activity.overridePendingTransition(0, 0);

        //start
        Intent intent = activity.getIntent();
        intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        activity.startActivity(intent);
        activity.overridePendingTransition(0, 0);
    }

    public static void themeInit(Context context) {
        String theme = YTD.settings.getString("choose_theme", "D");
        if (theme.equals("D")) {
            context.setTheme(R.style.AppThemeDark);
        } else {
            context.setTheme(R.style.AppThemeLight);
        }
    }

    public static int selectThemedInfoIcon() {
        String theme = YTD.settings.getString("choose_theme", "D");
        if (theme.equals("D")) {
            return R.drawable.ic_dialog_info_holo_dark;
        } else {
            return R.drawable.ic_dialog_info_holo_light;
        }
    }

    public static int selectThemedAlertIcon() {
        String theme = YTD.settings.getString("choose_theme", "D");
        if (theme.equals("D")) {
            return R.drawable.ic_dialog_alert_holo_dark;
        } else {
            return R.drawable.ic_dialog_alert_holo_light;
        }
    }

    public static void langInit(Context context) {
        String lang = YTD.settings.getString("lang", "default");
        Locale locale;
        if (!lang.equals("default")) {
            String[] fLang = filterLang(lang);
            locale = new Locale(fLang[0], fLang[1]);
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
        } else {
            locale = new Locale(YTD.settings.getString("DEF_LANG", ""));
            Locale.setDefault(locale);
        }

        Configuration config = new Configuration();
        config.locale = locale;
        context.getResources().updateConfiguration(config, null);
    }

    private static String[] filterLang(String lang) {
        if (lang.equals("el_GR") || lang.equals("bg_BG") || lang.equals("hu_HU") || lang.equals("ja_JP")
                || lang.equals("pl_PL") || lang.equals("pt_BR") || lang.equals("pt_PT") || lang.equals("tr_TR")
                || lang.equals("cs_CZ") || lang.equals("zh_CN") || lang.equals("zh_HK") || lang.equals("zh_TW"))
            return lang.split("_");
        return new String[] { lang, "" };
    }

    public static void logger(String type, String msg, String tag) {
        if (YTD.settings.getBoolean("enable_logging", false)) {
            if (type.equals("v")) {
                Log.v(tag, msg);
            } else if (type.equals("d")) {
                Log.d(tag, msg);
            } else if (type.equals("i")) {
                Log.i(tag, msg);
            } else if (type.equals("w")) {
                Log.w(tag, msg);
            }
        }
    }

    public static int pathCheck(File path) {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            if (path.canWrite()) {
                return 0;
            } else {
                logger("w", "Path not writable", DEBUG_TAG);
                return 1;
            }
        } else {
            logger("w", "Path not mounted", DEBUG_TAG);
            return 2;
        }
    }

    public static void writeToFile(File file, String content) {
        try {
            InputStream is = new ByteArrayInputStream(content.getBytes("UTF-8"));
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();
        } catch (IOException e) {
            Log.e(DEBUG_TAG, "Error creating '" + file.getName() + "' Log file", e);
        }
    }

    public static void setNotificationDefaults(NotificationCompat.Builder aBuilder) {
        String def = YTD.settings.getString("notification_defaults", "0");
        if (aBuilder != null) {
            if (def.equals("0")) {
                aBuilder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
            }
            if (def.equals("1")) {
                aBuilder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS);
            }
            if (def.equals("2")) {
                aBuilder.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
            }
            if (def.equals("3")) {
                aBuilder.setDefaults(Notification.DEFAULT_ALL);
            }
            if (def.equals("4")) {
                aBuilder.setDefaults(Notification.DEFAULT_SOUND);
            }
            if (def.equals("5")) {
                aBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
            }
            if (def.equals("6")) {
                aBuilder.setDefaults(Notification.DEFAULT_LIGHTS);
            }
            if (def.equals("7")) {
                // nothing...
            }
        }
    }

    public static String[] retrieveBitrateValuesFromPref(Context ctx) {
        String[] bitrateValues = ctx.getResources().getStringArray(R.array.mp3_bitrate_entry_values);

        String[] bitrateEntries = ctx.getResources().getStringArray(R.array.mp3_bitrate_entries);

        String bitrateValue = YTD.settings.getString("auto-mp3_bitrates", "192k");
        String bitrateType = null;
        if (bitrateValue.contains("k")) {
            bitrateType = "CBR";
        } else {
            bitrateType = "VBR";
        }

        String bitrateEntry = null;
        for (int i = 0; i < bitrateEntries.length; i++) {
            if (bitrateValue.equals(bitrateValues[i]))
                bitrateEntry = bitrateEntries[i];
        }

        Utils.logger("v", /*"selected bitrate value: " + bitrateValue + */
                "\nselected bitrate entry: " + bitrateEntry, DEBUG_TAG);

        return new String[] { bitrateType, bitrateValue };
    }

    public static void removeFromMediaStore(Context ctx, File fileToDel, String mediaUriString) {
        if (mediaUriString != null) {
            Uri mediaUri = Uri.parse(mediaUriString);
            // remove media file reference from MediaStore library via ContentResolver
            if (ctx.getContentResolver().delete(mediaUri, null, null) > 0) {
                Utils.logger("d", mediaUri.toString() + " Removed", DEBUG_TAG);
            } else {
                Utils.logger("w", mediaUri.toString() + " NOT removed", DEBUG_TAG);
            }
        } else {
            Utils.logger("w", "mediaUriString for " + fileToDel.getName() + " null", DEBUG_TAG);
        }
    }

    public static String cpuVersion() {
        String cpuAbi = Build.CPU_ABI;
        Utils.logger("d", "CPU_ABI: " + cpuAbi, DEBUG_TAG);
        if (cpuAbi.equals("armeabi-v7a")) {
            if (neonCpu()) {
                Utils.logger("d", " -> v7a NEON", DEBUG_TAG);
                return YTD.ARMv7a_NEON;
            } else {
                Utils.logger("d", " -> v7a", DEBUG_TAG);
                return YTD.ARMv7a;
            }
            //      } else if (cpuAbi.equals("armeabi")) {
            //         Utils.logger("d", " -> v5te", DEBUG_TAG);
            //         return YTD.ARMv5te;
        } else if (cpuAbi.equals("x86")) {
            Utils.logger("d", " -> x86", DEBUG_TAG);
            return YTD.x86;
        } else {
            return YTD.UNSUPPORTED_CPU;
        }
    }

    public static void secureShowDialog(final Activity act, final AlertDialog.Builder adb) {
        act.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!act.isFinishing()) {
                    adb.show();
                }
            }
        });
    }

    public static void offerDevMail(final Context ctx) {
        AlertDialog.Builder adb = new AlertDialog.Builder(ctx);
        adb.setIcon(Utils.selectThemedAlertIcon());
        adb.setTitle(ctx.getString(R.string.ffmpeg_device_not_supported));
        adb.setMessage(ctx.getString(R.string.ffmpeg_support_mail));

        adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                /*
                 * adapted form same source as createEmailOnlyChooserIntent below
                 */
                Intent i = new Intent(Intent.ACTION_SEND);
                i.setType("*/*");

                String content = Utils.getCpuInfo();
                /*File destDir = getActivity().getExternalFilesDir(null); 
                String filename = "cpuInfo.txt";
                try {
                 Utils.createLogFile(destDir, filename, content);
                 i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(destDir, filename)));*/
                i.putExtra(Intent.EXTRA_EMAIL, new String[] { "samuele.rini76@gmail.com" });
                i.putExtra(Intent.EXTRA_SUBJECT, "YTD: device info report");
                i.putExtra(Intent.EXTRA_TEXT, content);

                ctx.startActivity(createEmailOnlyChooserIntent(ctx, i, ctx.getString(R.string.email_via)));
                /*} catch (IOException e) {
                   Log.e(DEBUG_TAG, "IOException on creating cpuInfo Log file ", e);
                }*/
            }
        });

        adb.setNegativeButton(ctx.getString(R.string.dialogs_negative), new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                // cancel
            }
        });

        AlertDialog helpDialog = adb.create();
        if (!((Activity) ctx).isFinishing()) {
            helpDialog.show();
        }
    }

    /* Intent createEmailOnlyChooserIntent from Stack Overflow:
     * 
     * http://stackoverflow.com/questions/2197741/how-to-send-email-from-my-android-application/12804063#12804063
     * 
     * Q: http://stackoverflow.com/users/138030/rakesh
     * A: http://stackoverflow.com/users/1473663/nobu-games
     */
    public static Intent createEmailOnlyChooserIntent(Context ctx, Intent source, CharSequence chooserTitle) {
        BugSenseHandler.leaveBreadcrumb("createEmailOnlyChooserIntent");
        Stack<Intent> intents = new Stack<Intent>();
        Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", "info@domain.com", null));
        List<ResolveInfo> activities = ctx.getPackageManager().queryIntentActivities(i, 0);

        for (ResolveInfo ri : activities) {
            Intent target = new Intent(source);
            target.setPackage(ri.activityInfo.packageName);
            intents.add(target);
        }

        if (!intents.isEmpty()) {
            Intent chooserIntent = Intent.createChooser(intents.remove(0), chooserTitle);
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[intents.size()]));

            return chooserIntent;
        } else {
            return Intent.createChooser(source, chooserTitle);
        }
    }

    public static void notifyFfmpegNotInstalled(final Activity act) {
        Utils.logger("w", "FFmpeg not installed/enabled", DEBUG_TAG);
        BugSenseHandler.leaveBreadcrumb("notifyFfmpegNotInstalled");
        AlertDialog.Builder adb = new AlertDialog.Builder(act);
        adb.setTitle(act.getString(R.string.ffmpeg_not_enabled_title));
        adb.setMessage(act.getString(R.string.ffmpeg_not_enabled_msg));

        adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                act.startActivity(new Intent(act, SettingsActivity.class));
            }
        });

        adb.setNegativeButton(act.getString(R.string.dialogs_negative), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // cancel
            }
        });

        if (!act.isFinishing()) {
            adb.show();
        }
    }

    /*
     * method readFromFile adapted from Stack Overflow:
    * http://stackoverflow.com/questions/2902689/how-can-i-read-a-text-file-from-the-sd-card-in-android
    * 
    * Q: http://stackoverflow.com/users/349664/rsss
    * A: http://stackoverflow.com/users/3171/dave-webb
    */
    public static String readFromFile(File file) throws IOException {

        StringBuilder text = null;
        if (file.exists()) {
            text = new StringBuilder();
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line;
            while ((line = br.readLine()) != null) {
                text.append(line);
                text.append('\n');
            }
            br.close();
        }
        return text.toString();
    }

    /*
     * method MakeSizeHumanReadable(int bytes, boolean si) from Stack Overflow:
    * http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
    * 
    * Q: http://stackoverflow.com/users/404615/iimuhin
    * A: http://stackoverflow.com/users/276052/aioobe
    */

    @SuppressLint("DefaultLocale")
    public static String MakeSizeHumanReadable(long bytes, boolean decimal) {
        String hr = "-";
        int unit = decimal ? 1000 : 1024;
        if (bytes < unit) {
            hr = bytes + " B";
        } else {
            int exp = (int) (Math.log(bytes) / Math.log(unit));
            String pre = (decimal ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (decimal ? "" : "i");
            hr = String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
        }
        hr = hr.replace("-1 B", "-").replace("0 B", "-");
        return hr;
    }

    /* class VersionComparator from Stack Overflow:
     * 
     * http://stackoverflow.com/questions/198431/how-do-you-compare-two-version-strings-in-java
     * 
     * Q: http://stackoverflow.com/users/1288/bill-the-lizard
     * A: http://stackoverflow.com/users/57695/peter-lawrey
     */

    public static class VersionComparator {

        public static String compare(String v1, String v2) {
            String s1 = normalisedVersion(v1);
            String s2 = normalisedVersion(v2);
            int cmp = s1.compareTo(s2);
            String cmpStr = cmp < 0 ? "<" : cmp > 0 ? ">" : "==";
            return cmpStr;
        }

        public static String normalisedVersion(String version) {
            return normalisedVersion(version, ".", 4);
        }

        public static String normalisedVersion(String version, String sep, int maxWidth) {
            String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
            StringBuilder sb = new StringBuilder();
            for (String s : split) {
                sb.append(String.format("%" + maxWidth + 's', s));
            }
            return sb.toString();
        }
    }

    public static int getSigHash(Activity act) {
        int currentHash = 0;
        try {
            Signature[] sigs = act.getPackageManager().getPackageInfo(act.getPackageName(),
                    PackageManager.GET_SIGNATURES).signatures;

            for (Signature sig : sigs) {
                currentHash = sig.hashCode();
                logger("d", "getSigHash: App signature " + currentHash, DEBUG_TAG);
            }
        } catch (NameNotFoundException e) {
            Log.e(DEBUG_TAG, "getSigHash: App signature not found; " + e.getMessage());
        }
        return currentHash;
    }

    /*
     * checkMD5(String md5, File file)
     * -------------------------------
     * 
     * Copyright (C) 2012 The CyanogenMod Project
     *
     * * Licensed under the GNU GPLv2 license
     *
     * The text of the license can be found in the LICENSE_GPL file
     * or at https://www.gnu.org/licenses/gpl-2.0.txt
     */

    public static boolean checkMD5(String md5, File file) {
        if (md5 == null || md5.equals("") || file == null) {
            Log.e(DEBUG_TAG, "MD5 String NULL or File NULL");
            return false;
        }

        String calculatedDigest = calculateMD5(file);
        if (calculatedDigest == null) {
            Log.e(DEBUG_TAG, "calculatedDigest NULL");
            return false;
        }

        Log.i(DEBUG_TAG, "Calculated digest: " + calculatedDigest);
        Log.i(DEBUG_TAG, "Provided digest: " + md5);

        return calculatedDigest.equalsIgnoreCase(md5);
    }

    /*
     * calculateMD5(File file)
     * -----------------------
     * 
     * Copyright (C) 2012 The CyanogenMod Project
     *
     * * Licensed under the GNU GPLv2 license
     *
     * The text of the license can be found in the LICENSE_GPL file
     * or at https://www.gnu.org/licenses/gpl-2.0.txt
     */

    public static String calculateMD5(File file) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            Log.e(DEBUG_TAG, "Exception while getting Digest", e);
            return null;
        }

        InputStream is;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            Log.e(DEBUG_TAG, "Exception while getting FileInputStream", e);
            return null;
        }

        byte[] buffer = new byte[8192];
        int read;
        try {
            while ((read = is.read(buffer)) > 0) {
                digest.update(buffer, 0, read);
            }
            byte[] md5sum = digest.digest();
            BigInteger bigInt = new BigInteger(1, md5sum);
            String output = bigInt.toString(16);
            // Fill to 32 chars
            output = String.format("%32s", output).replace(' ', '0');
            return output;
        } catch (IOException e) {
            //throw new RuntimeException("Unable to process file for MD5", e);
            Log.e(DEBUG_TAG, "Unable to process file for MD5", e); //TODO check if actually avoid FC 
            return "00000000000000000000000000000000"; // fictional bad MD5: needed without "throw new RuntimeException"
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                Log.e(DEBUG_TAG, "Exception on closing MD5 input stream", e);
            }
        }
    }

    /* method copyFile(File src, File dst, Context context) adapted from Stack Overflow:
    * 
    * http://stackoverflow.com/questions/4770004/how-to-move-rename-file-from-internal-app-storage-to-external-storage-on-android
    * 
    * Q: http://stackoverflow.com/users/131871/codefusionmobile
    * A: http://stackoverflow.com/users/472270/barmaley
    */

    @SuppressWarnings("resource")
    public static void copyFile(File src, File dst) throws IOException {
        FileChannel inChannel = new FileInputStream(src).getChannel();
        FileChannel outChannel = new FileOutputStream(dst).getChannel();
        //if (!dst.exists()) {
        try {
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } finally {
            if (inChannel != null)
                inChannel.close();
            if (outChannel != null)
                outChannel.close();
        }
        /*} else {
           logger("w", "copyFile: destination already exists", DEBUG_TAG);
        }*/
    }

    /*
     * getCpuInfo() from:
     *   http://www.roman10.net/how-to-get-cpu-information-on-android/
     * by:
     *   Liu Feipeng 
     */

    public static String getCpuInfo() {
        StringBuffer sb = new StringBuffer();
        sb.append("abi: ").append(Build.CPU_ABI).append("\n");
        if (new File("/proc/cpuinfo").exists()) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(new File("/proc/cpuinfo")));
                String aLine;
                while ((aLine = br.readLine()) != null) {
                    sb.append(aLine + "\n");
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    // ------------

    public static boolean neonCpu() {
        if (new File("/proc/cpuinfo").exists()) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(new File("/proc/cpuinfo")));
                String aLine;
                while ((aLine = br.readLine()) != null) {
                    Pattern p = Pattern.compile("[F|f]eatures.*neon.*");
                    Matcher m = p.matcher(aLine);
                    if (m.find()) {
                        br.close();
                        return true;
                    }
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    // -----------

    /*
     * scanMedia method adapted from Wolfram Rittmeyer's blog:
     * http://www.grokkingandroid.com/adding-files-to-androids-media-library-using-the-mediascanner/
     */

    public static void scanMedia(Context context, final String[] filePath, final String[] mime) {
        MediaScannerConnection.scanFile(context, filePath, mime, new OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                Log.v(DEBUG_TAG, "file " + path + " was scanned successfully: " + uri);
                //YTD.videoinfo.edit().putString(path, uri.toString()).apply();
            }
        });
    }

    //-----------

    public static String getFileNameWithoutExt(String filename) {
        int index = filename.lastIndexOf('.');
        if (index > 0 && index <= filename.length() - 2) {
            return filename.substring(0, index);
        }
        return filename;
    }

    public static String getExtFromFileName(String filename) {
        int index = filename.lastIndexOf('.');
        if (index > 0 && index <= filename.length() - 2) {
            return filename.substring(index + 1);
        }
        return filename;
    }

    /* 
     * 'getContentUriFromFilePath' and 'getFilePathFromContentUri' adapted from StackOverflow:
     * http://stackoverflow.com/a/11603899/1865860
     * 
     * Q: http://stackoverflow.com/users/315998/stealthcopter
     * A: http://stackoverflow.com/users/429108/jon-o
     */

    /**
     * Gets the MediaStore video ID of a given file on external storage
     * @param filePath The path (on external storage) of the file to resolve the ID of
     * @param contentResolver The content resolver to use to perform the query.
     * @return the video ID as a long
     */
    public static String getContentUriFromFile(File file, ContentResolver contentResolver) {

        String filePath = file.getAbsolutePath();
        long videoId;
        logger("d", "Loading file " + filePath, DEBUG_TAG);

        String[] vprojection = { MediaStore.Video.VideoColumns._ID };
        String[] aprojection = { MediaStore.Audio.AudioColumns._ID };

        String ext = getExtFromFileName(filePath).toLowerCase(Locale.ENGLISH);
        //logger("d","ext: " + ext, DEBUG_TAG);

        Uri videosUri = null;
        String[] projection = null;
        String dataType = null;
        /*if (file.getName().contains("_AO_")) {
           videosUri = MediaStore.Audio.Media.getContentUri("external");
           projection = aprojection;
           dataType = MediaStore.Audio.AudioColumns.DATA;
           logger("d", " -> contentUri on Audio-Only file", DEBUG_TAG);
        } else */if (ext.equals("mp4") || ext.equals("3gp") || ext.equals("webm")) {
            videosUri = MediaStore.Video.Media.getContentUri("external");
            projection = vprojection;
            dataType = MediaStore.Video.VideoColumns.DATA;
        } else if (ext.equals("mp3") || ext.equals("ogg") || ext.equals("aac") || ext.equals("m4a")) {
            videosUri = MediaStore.Audio.Media.getContentUri("external");
            projection = aprojection;
            dataType = MediaStore.Audio.AudioColumns.DATA;
        } else if (ext.equals("flv")) {
            logger("w", " -> contentUri not available [FLV video]", DEBUG_TAG);
            return null;
        }

        Cursor cursor = null;
        String videoUri = null;

        try {
            cursor = contentResolver.query(videosUri, projection, dataType + " LIKE ?", new String[] { filePath },
                    null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(projection[0]);

            videoId = cursor.getLong(columnIndex);
            videoUri = videosUri + "/" + videoId;
            logger("d", " -> contentUri: " + videoUri, DEBUG_TAG);

            cursor.close();
        } catch (Exception e) {
            Log.e(DEBUG_TAG, "ContentUri not available: " + e.getMessage());
        } /*finally {
           cursor.close();
          }*/

        return videoUri;
    }

    /**
     * Gets the corresponding path to a file from the given content:// URI
     * @param selectedVideoUri The content:// URI to find the file path from
     * @param contentResolver The content resolver to use to perform the query.
     * @return the file path as a string
     */
    public static String getFilePathFromContentUri(Uri selectedVideoUri, ContentResolver contentResolver) {
        String filePath;
        String[] filePathColumn = { MediaColumns.DATA };

        Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        filePath = cursor.getString(columnIndex);
        cursor.close();
        return filePath;
    }

    public static void appendStringToFile(File file, String text) {
        PrintWriter out = null;
        try {
            out = new PrintWriter(new BufferedWriter(new FileWriter(file.getAbsolutePath(), true)));
            out.println("\n\n" + System.currentTimeMillis() + ":\n" + text);
        } catch (IOException e) {
            Log.e(DEBUG_TAG, "appendStringToFile: " + e.getMessage());
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    /*private static int totSeconds = 0;
    private static int currentTime = 0;
        
    public static int[] getAudioJobProgress(String shellLine) {
      Pattern totalTimePattern = Pattern.compile("Duration: (..):(..):(..)\\.(..)");
      Matcher totalTimeMatcher = totalTimePattern.matcher(shellLine);
      if (totalTimeMatcher.find()) {
     totSeconds = getTotSeconds(totalTimeMatcher);
      }
      Pattern currentTimePattern = Pattern.compile("time=(..):(..):(..)\\.(..)");
      Matcher currentTimeMatcher = currentTimePattern.matcher(shellLine);
      if (currentTimeMatcher.find()) {
     currentTime = getTotSeconds(currentTimeMatcher);
      }
        
      return new int[] { totSeconds, currentTime };
    }*/

    public static int getTotSeconds(Matcher timeMatcher) {
        int h = Integer.parseInt(timeMatcher.group(1));
        int m = Integer.parseInt(timeMatcher.group(2));
        int s = Integer.parseInt(timeMatcher.group(3));
        int f = Integer.parseInt(timeMatcher.group(4));

        long hToSec = TimeUnit.HOURS.toSeconds(h);
        long mToSec = TimeUnit.MINUTES.toSeconds(m);

        int tot = (int) (hToSec + mToSec + s);
        if (f > 50)
            tot = tot + 1;

        //logger("v", "h=" + h + " m=" + m + " s=" + s + "." + f + " -> tot=" + tot,   DEBUG_TAG);
        return tot;
    }
}

// ---------------------------------------------------------

/*
*  to get the name of an executing method, 
*  call this from inside the method itself:
*  
*  String name = new Exception().getStackTrace()[0].getMethodName();
*  Log.i(DEBUG_TAG, "==> " + name);
*/