Tuesday, August 22, 2017

android - Get sd card musics and play

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    android:background="#e9e0d5"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_margin="2dp"
        >
        <Button
            android:id="@+id/btn_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Search"
            />
        <Button
            android:id="@+id/btn_stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Stop Playing"
            />
    </LinearLayout>
    <TextView
        android:id="@+id/stats"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:background="#cbf5bc"
        android:padding="10dp"
        />
    <ListView
        android:id="@+id/list_view"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
</LinearLayout>
MainActivity.java

package com.cfsuman.me.androidcodesnippets;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.HashMap;


public class MainActivity extends AppCompatActivity {
    private Context mContext;
    private Activity mActivity;

    private LinearLayout mRootLayout;
    private Button mButtonSearch;
    private Button mButtonStop;
    private ListView mListView;
    private TextView mStats;

    private MediaPlayer mPlayer;

    private static final int MY_PERMISSION_REQUEST_CODE = 123;

    private HashMap<Long,String> mAudioMap = new HashMap<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the application context
        mContext = getApplicationContext();
        mActivity = MainActivity.this;

        // Get the widget reference from xml layout
        mRootLayout = findViewById(R.id.root_layout);
        mButtonSearch = findViewById(R.id.btn_search);
        mButtonStop = findViewById(R.id.btn_stop);
        mListView = findViewById(R.id.list_view);
        mStats = findViewById(R.id.stats);

        // Custom method to check permission at run time
        checkPermission();

        // Click listener for stop button
        mButtonStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Stop playing music
                stopPlaying();
            }
        });

        // Set a click listener for button
        mButtonSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Get the audio files id and title from sd card
                mAudioMap = getMediaFileList();

                // Ids array for music map
                final Long[] ids = mAudioMap.keySet().toArray(new Long[mAudioMap.size()]);

                // Titles array from music map
                String[] titles = mAudioMap.values().toArray(new String[mAudioMap.size()]);

                // ArrayAdapter from titles array
                ArrayAdapter<String> titlesAdapter = new ArrayAdapter<String>(
                        mContext,
                        android.R.layout.simple_list_item_1
                        ,titles
                );
                // Data bind list view with adapter
                mListView.setAdapter(titlesAdapter);

                // Click listener for list item
                mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        // Selected item's title and is
                        String titleValue = (String) adapterView.getItemAtPosition(i);
                        Long idValue = ids[i];

                        /*
                            ContentUris
                                Utility methods useful for working with Uri objects that use
                                the "content" (content://) scheme.
                        */
                        /*
                            Uri withAppendedId (Uri contentUri, long id)
                                Appends the given ID to the end of the path.

                            Parameters
                                contentUri Uri : to start with
                                id long : to append

                            Returns
                                Uri : a new URI with the given ID appended to the end of the path
                        */

                        // Get the uri of selected music
                        Uri contentUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,idValue);

                        stopPlaying(); // Stop playing first, it already playing a music

                        // Try to play the selected music
                        try{
                            // Initialize the media player
                            mPlayer = new MediaPlayer();
                            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

                            // Set media player data source
                            mPlayer.setDataSource(mContext,contentUri);
                            //Toast.makeText(mContext,contentUri+"",Toast.LENGTH_SHORT).show();

                            // Prepare the selected audio
                            mPlayer.prepare();

                            // Finally, start playing selected music
                            mPlayer.start();

                            // Listener for media player completion
                            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                                @Override
                                public void onCompletion(MediaPlayer mediaPlayer) {
                                    mStats.setBackgroundColor(Color.RED);
                                }
                            });
                            mStats.setBackgroundColor(Color.GREEN);
                            mStats.setText("Playing : " + titleValue);
                        }catch (IOException e){
                            // When IO exception catch
                            e.printStackTrace();
                            Toast.makeText(mContext,"Error.",Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        });
    }

    // Custom method to get all audio files list from external storage
    protected HashMap getMediaFileList(){
        // Get the content resolver
        ContentResolver contentResolver = mContext.getContentResolver();

        // Get the external storage uri of media store audio
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

        Cursor cursor = contentResolver.query(
                uri, // Uri
                null, // Projection
                null, // Selection
                null, // Selection args
                null // Sor order
        );

        if (cursor == null) {
            // Query failed, handle error
        } else if (!cursor.moveToFirst()) {
            // No media on the device
        } else {
            int title = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
            int id = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
            // Loop through the musics
            do {
                // Get the current audio file id
                long thisId = cursor.getLong(id);

                // Get the current audio title
                String thisTitle = cursor.getString(title);
                // Process current music here

                mAudioMap.put(thisId,thisTitle);
            } while (cursor.moveToNext());
        }

        return mAudioMap;
    }

    // Custom method to stop music playing
    protected void stopPlaying(){
        if(mPlayer!=null){
            mPlayer.stop();
            mPlayer.release();
            mPlayer = null;
            Toast.makeText(mContext,"Stop playing",Toast.LENGTH_SHORT).show();
            mStats.setBackgroundColor(Color.RED);
        }
    }

    protected void checkPermission(){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
                if(shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)){
                    // Show an alert dialog
                    AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
                    builder.setMessage("Read external storage permission is required.");
                    builder.setTitle("Please grant permission");
                    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            ActivityCompat.requestPermissions(
                                    mActivity,
                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                    MY_PERMISSION_REQUEST_CODE
                            );
                        }
                    });
                    builder.setNeutralButton("Cancel",null);
                    AlertDialog dialog = builder.create();
                    dialog.show();
                }else {
                    // Request permission
                    ActivityCompat.requestPermissions(
                            mActivity,
                            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                            MY_PERMISSION_REQUEST_CODE
                    );
                }
            }else {
                // Permission already granted
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
        switch(requestCode){
            case MY_PERMISSION_REQUEST_CODE:{
                if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    // Permission granted
                }else {
                    // Permission denied
                }
            }
        }
    }

    @Override
    public void onDestroy(){
        if(mPlayer!=null){
            mPlayer.release();
        }
        super.onDestroy();
    }
}
AndroidManifest.xml [Permission]

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>