com.jams.music.player.SettingsActivity.SettingsMusicFoldersDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.jams.music.player.SettingsActivity.SettingsMusicFoldersDialog.java

Source

/*
 * Copyright (C) 2014 Saravan Pantham
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jams.music.player.SettingsActivity;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.jams.music.player.AsyncTasks.AsyncSaveMusicFoldersTask;
import com.jams.music.player.DBHelpers.DBAccessHelper;
import com.jams.music.player.Helpers.TypefaceHelper;
import com.jams.music.player.Helpers.UIElementsHelper;
import com.jams.music.player.MusicFoldersSelectionFragment.MultiselectListViewAdapter;
import com.jams.music.player.R;
import com.jams.music.player.Utils.Common;
import com.jams.music.player.WelcomeActivity.WelcomeActivity;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class SettingsMusicFoldersDialog extends DialogFragment {

    private Context mContext;
    private Common mApp;
    private boolean mWelcomeSetup = false;

    private RelativeLayout mUpLayout;
    private ImageView mUpIcon;
    private TextView mUpText;
    private TextView mCurrentFolderText;

    private ListView mFoldersListView;
    private Cursor mCursor;

    private String mRootDir;
    private String mCurrentDir;

    private List<String> mFileFolderNamesList;
    private List<String> mFileFolderPathsList;
    private List<String> mFileFolderSizesList;
    private HashMap<String, Boolean> mMusicFolders;

    @Override
    public Dialog onCreateDialog(Bundle onSavedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        mContext = getActivity().getApplicationContext();
        mApp = (Common) mContext;
        View rootView = getActivity().getLayoutInflater().inflate(R.layout.fragment_folders_selection, null);
        mMusicFolders = new HashMap<String, Boolean>();

        mFoldersListView = (ListView) rootView.findViewById(R.id.folders_list_view);
        mFoldersListView.setFastScrollEnabled(true);
        mWelcomeSetup = getArguments().getBoolean("com.jams.music.player.WELCOME");

        mUpLayout = (RelativeLayout) rootView.findViewById(R.id.folders_up_layout);
        mUpIcon = (ImageView) rootView.findViewById(R.id.folders_up_icon);
        mUpText = (TextView) rootView.findViewById(R.id.folders_up_text);
        mCurrentFolderText = (TextView) rootView.findViewById(R.id.folders_current_directory_text);

        mUpText.setTypeface(TypefaceHelper.getTypeface(mContext, "Roboto-Regular"));
        mCurrentFolderText.setTypeface(TypefaceHelper.getTypeface(mContext, "Roboto-Regular"));

        mUpLayout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    getDir(new File(mCurrentDir).getParentFile().getCanonicalPath());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }

        });

        if (mWelcomeSetup) {
            mFoldersListView.setDivider(getResources().getDrawable(R.drawable.icon_list_divider_light));
            mUpIcon.setImageResource(R.drawable.up);
        } else {
            mUpIcon.setImageResource(UIElementsHelper.getIcon(mContext, "up"));

            if (mApp.getCurrentTheme() == Common.DARK_THEME) {
                mUpIcon.setImageResource(R.drawable.icon_list_divider_light);
            } else {
                mUpIcon.setImageResource(R.drawable.icon_list_divider);
            }

        }

        mFoldersListView.setDividerHeight(1);
        mRootDir = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
        mCurrentDir = mRootDir;

        //Get a mCursor with a list of all the current folder paths (will be empty if this is the first run).
        mCursor = mApp.getDBAccessHelper().getAllMusicFolderPaths();

        //Get a list of all the paths that are currently stored in the DB.
        for (int i = 0; i < mCursor.getCount(); i++) {
            mCursor.moveToPosition(i);

            //Filter out any double slashes.
            String path = mCursor.getString(mCursor.getColumnIndex(DBAccessHelper.FOLDER_PATH));
            if (path.contains("//")) {
                path.replace("//", "/");
            }

            mMusicFolders.put(path, true);
        }

        //Close the cursor.
        if (mCursor != null)
            mCursor.close();

        //Get the folder hierarchy of the selected folder.
        getDir(mRootDir);

        mFoldersListView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
                String newPath = mFileFolderPathsList.get(index);
                getDir(newPath);

            }

        });

        builder.setTitle(R.string.select_music_folders);
        builder.setView(rootView);
        builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                getActivity().finish();

                Intent intent = new Intent(mContext, WelcomeActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                intent.putExtra("REFRESH_MUSIC_LIBRARY", true);
                mContext.startActivity(intent);

            }

        });

        builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();

            }

        });

        return builder.create();
    }

    /**
     * Sets the current directory's text.
     */
    private void setCurrentDirText() {
        mCurrentFolderText.setText(mCurrentDir);
    }

    /**
     * Retrieves the folder hierarchy for the specified folder 
     * (this method is NOT recursive and doesn't go into the parent 
     * folder's subfolders. 
     */
    private void getDir(String dirPath) {

        mFileFolderNamesList = new ArrayList<String>();
        mFileFolderPathsList = new ArrayList<String>();
        mFileFolderSizesList = new ArrayList<String>();

        File f = new File(dirPath);
        File[] files = f.listFiles();
        Arrays.sort(files);

        if (files != null) {

            for (int i = 0; i < files.length; i++) {

                File file = files[i];

                if (!file.isHidden() && file.canRead()) {

                    if (file.isDirectory()) {

                        /*
                         * Starting with Android 4.2, /storage/emulated/legacy/... 
                         * is a symlink that points to the actual directory where 
                         * the user's files are stored. We need to detect the 
                         * actual directory's file path here.
                         */
                        String filePath;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                            filePath = getRealFilePath(file.getAbsolutePath());
                        else
                            filePath = file.getAbsolutePath();

                        mFileFolderPathsList.add(filePath);
                        mFileFolderNamesList.add(file.getName());

                        File[] listOfFiles = file.listFiles();

                        if (listOfFiles != null) {
                            if (listOfFiles.length == 1) {
                                mFileFolderSizesList.add("" + listOfFiles.length + " item");
                            } else {
                                mFileFolderSizesList.add("" + listOfFiles.length + " items");
                            }

                        }

                    }

                }

            }

        }

        boolean dirChecked = false;

        //Get the directory and the parent dir.
        String concatatedString = "";
        int secondSlashIndex = dirPath.lastIndexOf("/", dirPath.lastIndexOf("/") - 1);
        if ((secondSlashIndex < dirPath.length()) && secondSlashIndex != -1)
            concatatedString = dirPath.substring(secondSlashIndex, dirPath.length());

        if (getMusicFoldersHashMap().get(concatatedString) != null)
            dirChecked = getMusicFoldersHashMap().get(concatatedString);

        SettingsMultiselectAdapter mFoldersListViewAdapter = new SettingsMultiselectAdapter(getActivity(), this,
                mWelcomeSetup, dirChecked);

        mFoldersListView.setAdapter(mFoldersListViewAdapter);
        mFoldersListViewAdapter.notifyDataSetChanged();

        mCurrentDir = dirPath;
        setCurrentDirText();

    }

    /**
     * Resolves the /storage/emulated/legacy paths to 
     * their true folder path representations. Required 
     * for Nexuses and other devices with no SD card.
     */
    @SuppressLint("SdCardPath")
    private String getRealFilePath(String filePath) {

        if (filePath.equals("/storage/emulated/0") || filePath.equals("/storage/emulated/0/")
                || filePath.equals("/storage/emulated/legacy") || filePath.equals("/storage/emulated/legacy/")
                || filePath.equals("/storage/sdcard0") || filePath.equals("/storage/sdcard0/")
                || filePath.equals("/sdcard") || filePath.equals("/sdcard/") || filePath.equals("/mnt/sdcard")
                || filePath.equals("/mnt/sdcard/")) {

            return Environment.getExternalStorageDirectory().toString();
        }

        return filePath;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        if (isRemoving()) {
            mCursor.close();
            mCursor = null;

            //Clear the DB and insert the new selections (along with the old ones).
            mApp.getDBAccessHelper().deleteAllMusicFolderPaths();
            try {
                mApp.getDBAccessHelper().getWritableDatabase().beginTransaction();

                //Retrieve a list of all keys in the hash map (key = music folder path).
                ArrayList<String> mPathsList = new ArrayList<String>(mMusicFolders.keySet());

                for (int i = 0; i < mMusicFolders.size(); i++) {
                    String path = mPathsList.get(i);
                    boolean include = mMusicFolders.get(path);

                    //Trim down the folder path to include only the folder and its parent.
                    int secondSlashIndex = path.lastIndexOf("/", path.lastIndexOf("/") - 1);
                    if ((secondSlashIndex < path.length()) && secondSlashIndex != -1)
                        path = path.substring(secondSlashIndex, path.length());

                    ContentValues values = new ContentValues();
                    values.put(DBAccessHelper.FOLDER_PATH, path);
                    values.put(DBAccessHelper.INCLUDE, include);

                    mApp.getDBAccessHelper().getWritableDatabase().insert(DBAccessHelper.MUSIC_FOLDERS_TABLE, null,
                            values);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                mApp.getDBAccessHelper().getWritableDatabase().setTransactionSuccessful();
                mApp.getDBAccessHelper().getWritableDatabase().endTransaction();
            }

        }

    }

    /*
     * Getter methods.
     */
    public HashMap<String, Boolean> getMusicFoldersHashMap() {
        return mMusicFolders;
    }

    public ArrayList<String> getMusicFolderPaths() {
        return new ArrayList<String>(mMusicFolders.keySet());
    }

    public List<String> getFileFolderNamesList() {
        return mFileFolderNamesList;
    }

    public List<String> getFileFolderSizesList() {
        return mFileFolderSizesList;
    }

    public List<String> getFileFolderPathsList() {
        return mFileFolderPathsList;
    }

}