Music demo

Music

music demo

Menifests

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>



<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".StartActivity"
        android:label="@string/title_activity_main"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".MainActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustPan"/>
    <activity
        android:name=".NetMusicActivity"
        android:screenOrientation="portrait" />
    <activity
        android:name=".FavouriteActivity"
        android:screenOrientation="portrait" />
    <activity
        android:name=".MusicListActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustUnspecified|stateHidden"/>
    <activity android:name=".PlayMusicActivity"
               android:screenOrientation="portrait"/>


    <service android:name="com.example.srct.tools.PlayService">
        <intent-filter>
            <action android:name="com.app.media.MUSIC_SERVICE" />
        </intent-filter>
    </service>
</application>

StartActivity.java

package com.example.srct.music;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.os.Bundle;
import android.os.Handler;
import android.content.Intent;

import java.util.ArrayList;

public class StartActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback{

private static final int WAITTIME = 1000;
private ArrayList<String> permission=new ArrayList<String>();
private ArrayList<String> askPermissionList = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start);
    permission.add(Manifest.permission.READ_EXTERNAL_STORAGE);
    permission.add(Manifest.permission.READ_PHONE_STATE);
    checkPermission(permission,askPermissionList);
    if(askPermissionList.size() >0) {
        requestPermissions(askPermissionList,1);

    }else{
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(StartActivity.this, MainActivity.class);
                startActivity(intent);
                finish();

            }
        }, WAITTIME);

    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(verifyPermisson(grantResults)){
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {

                Intent intent = new Intent(StartActivity.this,
                        MainActivity.class);
                startActivity(intent);

                finish();

            }
        }, WAITTIME);
    }else {
        finish();
    }
}

/***
 * 请求权限的方法,requestPermissions() 传入一个Activity,一个需要的权限的数组,
 * 和一个整形的request code,与用户完成交互后,系统会回调该方法并返回对用的request code
 * @param needAskPermisson
 * @param requestCode
 */
private void requestPermissions(ArrayList<String> needAskPermisson,int requestCode) {
    String[] needpermisson = new String[needAskPermisson.size()];
    needpermisson = needAskPermisson.toArray(needpermisson);
    ActivityCompat.requestPermissions(this,needpermisson,1);//弹出对话框

}


/****
 * 判断应用权限的有无,如果没有这项权限,则将权限加入到askPermissionsList
 * @param permissions
 * @param askpermissionsList
 */
private void checkPermission(ArrayList<String> permissions, ArrayList<String> askpermissionsList) {
    for(int i=0;i<permissions.size();i++) {
        //检查权限的方法,第一个参数是context,第二个参数是权限名,返回值为PERMISSION_GRANTED(有权限)和PERMISSION_DENIED(无权限)
        if(ContextCompat.checkSelfPermission(StartActivity.this,permissions.get(i))!= PackageManager.PERMISSION_GRANTED){
            askpermissionsList.add(permissions.get(i));
        }
    }

}

private  boolean verifyPermisson(int[] grantResults) {
    if(grantResults.length<1) {
        return false;
    }
    for(int result:grantResults) {
        if(result!=PackageManager.PERMISSION_GRANTED){
            return false;
        }
    }
    return true;
}

}

MainActivity

package com.example.srct.music;

import android.app.Activity;

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.RadioGroup;
import android.content.Intent;
import android.widget.TabHost;

public class MainActivity extends TabActivity implements
RadioGroup.OnCheckedChangeListener {

private TabHost tabhost;
private Intent localmusic;
private Intent favorite;
private Intent net;
private RadioGroup maintab;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    maintab = (RadioGroup) findViewById(R.id.tab_group);
    maintab.setOnCheckedChangeListener(this);// 设置RadioGroup监听器
    tabhost = getTabHost();
    localmusic = new Intent(this, MusicListActivity.class);
    tabhost.addTab(tabhost.newTabSpec("localmusic").setIndicator("localmusic").setContent(localmusic));
    favorite = new Intent(this, FavouriteActivity.class);
    tabhost.addTab(tabhost.newTabSpec("favorite").setIndicator("favorite").setContent(favorite));
    net = new Intent(this, NetMusicActivity.class);
    tabhost.addTab(tabhost.newTabSpec("net").setIndicator("net").setContent(net));


}


@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
    switch (checkedId) {
        case R.id.local:
            tabhost.setCurrentTabByTag("localmusic");
            break;
        case R.id.favorite:
            tabhost.setCurrentTabByTag("favorite");
            break;
        case R.id.online:
            tabhost.setCurrentTabByTag("net");
    }

}

MusicListActivity

package com.example.srct.music;

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.Intent;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

import android.view.View;
import android.widget.Toast;

import com.example.srct.adapter.LocalMusicAdapter;

public class MusicListActivity extends Activity {

private ListView listview;
private LocalMusicAdapter adapter;
private Cursor cursor;//游标
SharedPreferences pf;
SharedPreferences.Editor editor;

public List<Bitmap> pic = new LinkedList<Bitmap>();
private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();

//通过MediaStore查询标题,时间,艺术家,ID,显示的名字,数据,专辑ID
String[] media_info = new String[]{MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.DURATION,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.DISPLAY_NAME,
        MediaStore.Audio.Media.DATA,
        MediaStore.Audio.Media.ALBUM_ID };
private String[] _title;// 标题
private String[] _duration;// 时长
private String[] _artist;// 艺术家
private int[] _id;// ID
private String[] _path;// 路径(数据)

//Menu Selector
private static final int PLAY_ITEM = Menu.FIRST;
private static final int DELETE_ITEM = Menu.FIRST + 1;
private static final int LIKE_ITEM = Menu.FIRST + 2;
private static final int MUSIC_INFO = Menu.FIRST + 3;
private int num;//记录所选中歌曲在listview中的位置,从0开始

EditText edit;//搜索框
ImageView deleteText;//叉叉
Handler myhandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_music_list);

    listview = (ListView) findViewById(R.id.music_list);
    edit = (EditText) findViewById(R.id.search);
    deleteText = (ImageView) findViewById(R.id.deleteText);

    showMp3List();
    listview.setOnItemClickListener(new MusicListOnClickListener());// 列表的选项的监听器,点击播放事件,未实现
    listview.setOnCreateContextMenuListener(new MusicContextMenuListner());//长按显示操作播放删除等信息
    deleteText.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            edit.setText("");
        }
    });

    set_eSearch_TextChanged();
    pf = getSharedPreferences("favourite",MODE_PRIVATE);
    editor = pf.edit();

    this.getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, new PersonObserver(new Handler()));

}


private void showMp3List() {
    // 通过游标的getContentResolver查询媒体信息
    cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, media_info, null, null, MediaStore.Audio.Media.TITLE + " ASC");
    //this.getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, new PersonObserver(new Handler()));
    if (null != cursor && cursor.getCount() > 0) {
        Log.d("ppll","d dd");
        cursor.moveToFirst();// 先游标移到第一列
        _id = new int[cursor.getCount()];// 实例化临时变量
        _title = new String[cursor.getCount()];
        _artist = new String[cursor.getCount()];
        _path = new String[cursor.getCount()];
        // 用循环把所有媒体信息便利出来
        for (int i = 0; i < cursor.getCount(); i++) {
            Bitmap bm = getArtwork(this, cursor.getInt(3),cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)), true);
            //pic.add((ImageView)bm);
            _title[i] = cursor.getString(0);
            _artist[i] = cursor.getString(2);
            _id[i] = cursor.getInt(3);
            _path[i] = cursor.getString(5);// /storage/emulated/0/musicplayer/music/Two Steps From Hell - Victory.mp3
            pic.add(bm);
            Log.d("frt","wwww   "+cursor.getString(5));
            Log.d("frt ",_path[i]);
            cursor.moveToNext();// 将游标移至下一行。
        }
        adapter = new LocalMusicAdapter(this, pic,_title,_artist);
        listview.setAdapter(adapter);// 用自定义的适配器装数据
    }
    else{
        _id = null;
        _artist = null;
        _path = null;
        _title = null;
        adapter = new LocalMusicAdapter(this, cursor);
        listview.setAdapter(adapter);// 用自定义的适配器装数据

    }


}
private class PersonObserver extends ContentObserver {

    public PersonObserver(Handler handler) {
        super(handler);
    }
    //当ContentProvier数据发生改变,则触发该函数
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        showMp3List();
        Log.d("hhhha","d");
    }
}

@Override
protected void onResume() {
    super.onResume();
   // showMp3List();
}

public class MusicListOnClickListener implements AdapterView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
        playMusic(position);
    }
}

public class MusicContextMenuListner implements View.OnCreateContextMenuListener {

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) {
        menu.setHeaderTitle("操作");
        menu.add(0, PLAY_ITEM, 0, "播放");
        menu.add(1, DELETE_ITEM, 1, "删除");
        menu.add(2, LIKE_ITEM, 2, "收藏");
        menu.add(3, MUSIC_INFO, 3, "查看该歌曲信息");
        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) info;
        num = menuInfo.position;
    }

}

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case PLAY_ITEM:
            playMusic(num);// 根据按的数字播放歌曲
            break;
        case DELETE_ITEM: // 删除一首歌曲
            Log.d("num","hhhppp"+"delete"+item.getItemId());
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("真的要删除这首歌曲吗").setPositiveButton("是", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    deleteMusic(num); // 删除音乐
                    deleteMusicFile(num);
                    //showMp3List(); // 从新获得列表中药显示的数据
                    adapter.notifyDataSetChanged(); // 更新列表UI
                }
            }).setNegativeButton("否", null).show();
            break;
        case LIKE_ITEM:
            doFavourite(num);
            break;
        case MUSIC_INFO:
            ReadMusicInfo();
            break;
    }
    return true;
}

private void deleteMusic(int position) {

    this.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MediaStore.Audio.Media._ID + "=" + _id[position], null);
    Toast toast = Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT);
    toast.show();
}

// 从sdcard中删除选中的音乐
private void deleteMusicFile(int position) {
    String rootPathSD = Environment.getExternalStorageDirectory().getPath();
    String[] tmp = _path[position].split("0");
    File file = new File(rootPathSD + tmp[1]);
    if (file.exists()) {
        file.delete();
        Toast toast = Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT);
        toast.show();
    }
}

private void doFavourite(int n){
    String tmp = ""+_id[n];
    if(pf.contains(tmp)) {
        Toast toast = Toast.makeText(this, "已经收藏", Toast.LENGTH_SHORT);
        toast.show();
    }
    else{
        editor.putInt(tmp,_id[n]);
        editor.commit();
        Toast toast = Toast.makeText(this, "收藏成功", Toast.LENGTH_SHORT);
        toast.show();
    }

}

private void ReadMusicInfo() {
    String[] musicinfo = {"歌名:" + _title[num], "歌手:" + _artist[num], "路径:" + _path[num]};
    AlertDialog.Builder builder = new AlertDialog.Builder(MusicListActivity.this);
    builder.setTitle(_title[num]).setItems(musicinfo, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    builder.create().show();
}

private void playMusic(int position) {
    Intent intent = new Intent(MusicListActivity.this, PlayMusicActivity.class);
    intent.putExtra("_ids", _id);
    intent.putExtra("_titles", _title);
    intent.putExtra("_artists", _artist);
    intent.putExtra("position", position);
    intent.putExtra("_path", _path);
    startActivity(intent);
}

private void set_eSearch_TextChanged() {

    edit.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            // TODO Auto-generated method stub
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            // TODO Auto-generated method stub
        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            if (s.length() == 0) {
                deleteText.setVisibility(View.GONE);//当文本框为空时,则叉叉消失
                listview.setAdapter(null);
                showMp3List();
            } else {
                deleteText.setVisibility(View.VISIBLE);//当文本框不为空时,出现叉叉
                myhandler.post(eChanged);
            }
        }
    });

}

Runnable eChanged = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        String str = edit.getText().toString();
        search_song(str);

    }
};

public void search_song(String str) {

    adapter = new LocalMusicAdapter(this, cursor);
    cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, media_info, "title like " +"'%"+str+"%'", null, null);
    if(cursor.getCount() <= 0)
        return;

    if (null != cursor && cursor.getCount() > 0) {
        cursor.moveToFirst();// 先游标移到第一列
        _id = new int[cursor.getCount()];// 实例化临时变量
        _title = new String[cursor.getCount()];
        _artist = new String[cursor.getCount()];
        _path = new String[cursor.getCount()];
        // 用循环把所有媒体信息便利出来
        for (int i = 0; i < cursor.getCount(); i++) {
            _id[i] = cursor.getInt(3);/// / 获得类型不要搞错了
            _title[i] = cursor.getString(0);
            _artist[i] = cursor.getString(2);
            _path[i] = cursor.getString(5).substring(4);
            cursor.moveToNext();// 将游标移至下一行。

        }
        adapter.notifyDataSetChanged();
        adapter = new LocalMusicAdapter(this, cursor, str);
        listview.setAdapter(adapter);// 用自定义的适配器装数据

    }


}

public static Bitmap getArtwork(Context context, long song_id, long album_id, boolean allowdefault) {

    if (album_id < 0) {
        if (song_id >= 0) {
            Bitmap bm = getArtworkFromFile(context, song_id, -1);
            if (bm != null) {
                return bm;
            }
        }
        if (allowdefault) {
            return getDefaultArtwork(context);
        }
        return null;
    }
    ContentResolver res = context.getContentResolver();
    Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
    if (uri != null) {
        InputStream in = null;
        try {
            in = res.openInputStream(uri);
            Bitmap bmp = BitmapFactory.decodeStream(in, null, sBitmapOptions);
            if (bmp == null) {
                bmp = getDefaultArtwork(context);
            }
            return bmp;
        } catch (FileNotFoundException ex) {
            Bitmap bm = getArtworkFromFile(context, song_id, album_id);
            if (bm != null) {
                if (bm.getConfig() == null) {
                    bm = bm.copy(Bitmap.Config.RGB_565, false);
                    if (bm == null && allowdefault) {
                        return getDefaultArtwork(context);
                    }
                }
            } else if (allowdefault) {
                bm = getDefaultArtwork(context);
            }
            return bm;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    return null;
}

private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
    Bitmap bm = null;

    if (albumid < 0 && songid < 0) {
        throw new IllegalArgumentException("Must specify an album or a song id");
    }
    try {

        BitmapFactory.Options options = new BitmapFactory.Options();

        FileDescriptor fd = null;
        if (albumid < 0) {
            Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
            if (pfd != null) {
                fd = pfd.getFileDescriptor();
                bm = BitmapFactory.decodeFileDescriptor(fd);//生成bitmap,这种方式比较省内存
            }
        } else {
            Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid);
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
            if (pfd != null) {
                fd = pfd.getFileDescriptor();
                bm = BitmapFactory.decodeFileDescriptor(fd,null,options);
            }
        }

    } catch (FileNotFoundException ex) {

    }

    return bm;
}

private static Bitmap getDefaultArtwork(Context context) {
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inPreferredConfig = Bitmap.Config.RGB_565;
    return BitmapFactory.decodeStream(context.getResources().openRawResource(+R.drawable.default_cover), null, opts);
}

FavouriteActivity

package com.example.srct.music;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import com.example.srct.adapter.LocalMusicAdapter;

import java.util.Iterator;
import java.util.Map;

public class FavouriteActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener{

private ListView listview;
private LocalMusicAdapter adapter;
private Cursor cursor;//游标
SharedPreferences pf;
SharedPreferences.Editor editor;
private static final int PLAY_ITEM = Menu.FIRST;
private static final int CANCEL_ITEM = Menu.FIRST + 1;
private static final int MUSIC_INFO = Menu.FIRST + 2;
private int num;//记录listview中的第几条记录

String[] media_info = new String[]{MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID};
private int[] _id;// 临时音乐id
private String[] _artist;// 艺术家
private String[] _title;// 标题
private String[] _path;// 路径
private String[] _duration;// 时长

private SwipeRefreshLayout mSwipeLayout;

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

    listview = (ListView) findViewById(R.id.favourite_list);

    showMp3List();
    listview.setOnItemClickListener(new MusicListOnClickListener());// 列表的选项的监听器,点击播放事件
    listview.setOnCreateContextMenuListener(new MusicContextMenuListner());//长按显示操作播放删除等信息

    mSwipeLayout = (SwipeRefreshLayout) findViewById(R.id.activity_favourite);
    mSwipeLayout.setOnRefreshListener(this);

}


@Override
protected void onResume() {
    super.onResume();
   // showMp3List();
}

private void showMp3List() {
    // 通过游标的getContentResolver查询媒体信息
    pf = getSharedPreferences("favourite", 0);
    Map<String ,?> tmp = pf.getAll();
    Iterator it = tmp.entrySet().iterator();
    String s = "";
    while(it.hasNext()){
        Map.Entry entry = (Map.Entry) it.next();
        Object val = entry.getValue();
        Log.d("_iddd " ," "+ val);
            s += val+" or _id=";
    }
    if(s.length()!= 0)
    s = s.substring(0,s.length() - 8);
    else
    Log.d("aaaa","aaa");

    if(s.length()==0)
        cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, media_info, "_id= 0" , null, null);
    else
        cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, media_info, "_id= "+s , null, null);
    if (null != cursor && cursor.getCount() > 0) {
        cursor.moveToFirst();// 先游标移到第一列
        _id = new int[cursor.getCount()];// 实例化临时变量
        _title = new String[cursor.getCount()];
        _artist = new String[cursor.getCount()];
        _path = new String[cursor.getCount()];
        // 用循环把所有媒体信息便利出来
        for (int i = 0; i < cursor.getCount(); i++) {
            _id[i] = cursor.getInt(3);/// / 获得类型不要搞错了
            _title[i] = cursor.getString(0);
            _artist[i] = cursor.getString(2);
            _path[i] = cursor.getString(5).substring(4);
            cursor.moveToNext();// 将游标移至下一行。
        }
        adapter = new LocalMusicAdapter(this, cursor);
        listview.setAdapter(adapter);// 用自定义的适配器装数据

    }
    else{
        _id = null;
        _artist = null;
        _path = null;
        _title = null;
        adapter = new LocalMusicAdapter(this, cursor);
        listview.setAdapter(adapter);// 用自定义的适配器装数据

    }
}
public class MusicListOnClickListener implements AdapterView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
        playMusic(position);
    }

}
public class MusicContextMenuListner implements View.OnCreateContextMenuListener {

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) {
        menu.setHeaderTitle("操作");
        menu.add(0, PLAY_ITEM, 0, "播放");
        menu.add(1, CANCEL_ITEM, 1, "取消收藏");
        menu.add(2, MUSIC_INFO, 2, "查看该歌曲信息");
        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) info;
        num = menuInfo.position;
    }

}

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case PLAY_ITEM:
            playMusic(num);// 根据按的数字播放歌曲
            Log.d("num","hhhppp"+item.getItemId());
            break;
        case CANCEL_ITEM: // 删除一首歌曲
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("取消收藏?").setPositiveButton("是", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    editor = pf.edit();
                    editor.remove(""+_id[num]);
                    editor.commit();
                    showMp3List(); // 从新获得列表中药显示的数据
                    adapter.notifyDataSetChanged(); // 更新列表UI
                }
            }).setNegativeButton("否", null).show();
            break;
        case MUSIC_INFO:
            ReadMusicInfo();
            break;
    }
    return true;
}

private void ReadMusicInfo() {
    String[] musicinfo = {"歌名:" + _title[num], "歌手:" + _artist[num], "路径:" + _path[num]};
    AlertDialog.Builder builder = new AlertDialog.Builder(FavouriteActivity.this);
    builder.setTitle(_title[num]).setItems(musicinfo, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    builder.create().show();
}

private void playMusic(int position) {
    Intent intent = new Intent(FavouriteActivity.this, PlayMusicActivity.class);
    intent.putExtra("_ids", _id);
    intent.putExtra("_titles", _title);
    intent.putExtra("_artists", _artist);
    intent.putExtra("position", position);
    intent.putExtra("_path", _path);
    startActivity(intent);
}


@Override
public void onRefresh() {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            // 停止刷新
            mSwipeLayout.setRefreshing(false);
            showMp3List();
        }
    }, 1000); // .5秒后发送消息,停止刷新
}

PlayMusicActivity

package com.example.srct.music;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.content.BroadcastReceiver;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.example.srct.adapter.ViewPagerAdapter;
import com.example.srct.tools.LRCbean;
import com.example.srct.tools.LyricView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.TreeMap;

public class PlayMusicActivity extends Activity{

private int[] _id;// 音乐id
private String[] _artist;// 艺术家
private String[] _title;// 标题
private String[] _path;//路径
private ImageView play_btn;// 播放按钮
private ImageView pre_btn;// 上一首
private ImageView next_btn;// 下一首
private int flag ;//标识位,是否播放
private static final int PLAY = 1;// 定义播放状态
private static final int PAUSE = 2;// 暂停状态
private static final int STOP = 3;// 停止
private static final int STATE_PLAY = 1;// 播放状态设为1
private static final int STATE_PAUSE = 2;// 播放状态设为2
private int mode = 1;//播放方式 1为顺序播放,2为单曲循环,3为随机播放
private TextView play_time = null;// 已播放时间
private TextView total_time = null;// 总时间
private int position;// 定义一个位置,用于定位用户点击列表曲首
private int currentPosition;// 当前播放位置
private int total;// 总时间
private SeekBar seekbar;// 进度条
private static final int PROGRESS_CHANGE = 4;// 进度条改变
private static final String MUSIC_CURRENT = "com.music.currentTime";// Action的状态
private static final String MUSIC_DURATION = "com.music.duration";
private static final String MUSIC_NEXT = "com.music.next";
private static final String MUSIC_UPDATE = "com.music.update";
private TextView music_name;
private TextView singer_name;
private TextView name;
private TextView lrc_ima_page;
private LyricView mylyc;
private ImageView mode_btn;
private int INTERVAL=45;
private ImageView pic;
private Cursor cursor;// 游标
private TreeMap<Integer, LRCbean> lrc_map = new TreeMap<Integer, LRCbean>();// Treemap对象

private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");//获取音乐文件内置图片的URI
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();//借助于BitmapFactory来解析,创建Bitmap对象

//View pager
private ViewPager viewPager;
private List views = new ArrayList();
private ViewPagerAdapter adaper ;

SharedPreferences pf;
SharedPreferences.Editor editor;

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

    Intent intent = getIntent();
    Bundle bundle = intent.getExtras();
    _id = bundle.getIntArray("_ids");
    position = bundle.getInt("position");
    _title = bundle.getStringArray("_titles");
    _artist = bundle.getStringArray("_artists");
    _path = bundle.getStringArray("_path");
    play_btn = (ImageView) findViewById(R.id.play_btn);
    pre_btn = (ImageView) findViewById(R.id.pre_btn);
    next_btn = (ImageView) findViewById(R.id.next_btn);
    mode_btn = (ImageView) findViewById(R.id.mode_btn);
    play_time = (TextView) findViewById(R.id.play_time);
    total_time = (TextView) findViewById(R.id.total_time);
    seekbar = (SeekBar) findViewById(R.id.seekbar);
    viewPager = (ViewPager)findViewById(R.id.viewpager);

    initViewPager();

    ShowPlayBtn();
    ShowPreBtn();
    ShowNextBtn();
    ShowSeekBar();
    ShowModeBtn();

    pf = getSharedPreferences("favourite",MODE_PRIVATE);
    editor = pf.edit();
    mode = pf.getInt("mode",1);
    Log.d("lloop"," "+mode);
    if(mode == 1)
        mode_btn.setImageResource(R.drawable.sequence);
    if(mode == 2)
        mode_btn.setImageResource(R.drawable.single);
    if(mode == 3)
        mode_btn.setImageResource(R.drawable.random);

}

//ViewPager initalise
private void initViewPager() {
    View music_page = LayoutInflater.from(getApplicationContext()).inflate(R.layout.music_image, null);
    views.add(music_page);
    music_name = music_page.findViewById(R.id.music_name);
    pic = music_page.findViewById(R.id.pic);
    singer_name = music_page.findViewById(R.id.singer_name);
    lrc_ima_page = music_page.findViewById(R.id.lrc);

    View lrc_page = LayoutInflater.from(getApplicationContext()).inflate(R.layout.lrc_page, null);
    views.add(lrc_page);
    name = lrc_page.findViewById(R.id.name);
    mylyc =(lrc_page).findViewById(R.id.mylrc);

    adaper = new ViewPagerAdapter(views);
    viewPager.setAdapter(adaper);
}

private void ShowPlayBtn() {
    play_btn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            switch (flag) {
                case STATE_PLAY:
                    pause();
                    break;

                case STATE_PAUSE:
                    play();
                    break;
            }
        }
    });

}

private void ShowNextBtn() {
    next_btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            nextOne();

        }
    });
}

private void ShowPreBtn() {
    pre_btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            preOne();
        }
    });
}

private void ShowSeekBar() {
    seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            play();

        }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            pause();

        }
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                seekbar_change(progress);
                mylyc.setOffsetY(220 - mylyc.SelectIndex(progress) * (mylyc.getSIZEWORD() + INTERVAL-1));
            }
        }
    });
}

private void ShowModeBtn(){
    mode_btn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            switch (mode) {
                case 1:
                    mode_btn.setImageResource(R.drawable.single);
                    Toast.makeText(PlayMusicActivity.this, "单曲循环", Toast.LENGTH_SHORT).show();
                    mode = 2;
                    editor.putInt("mode",mode);
                    editor.commit();
                    break;

                case 2:
                    mode_btn.setImageResource(R.drawable.random);
                    Toast.makeText(PlayMusicActivity.this, "随机播放", Toast.LENGTH_SHORT).show();
                    random();
                    mode = 3;
                    editor.putInt("mode",mode);
                    editor.commit();
                    break;

                case 3:
                    mode_btn.setImageResource(R.drawable.sequence);
                    Toast.makeText(PlayMusicActivity.this, "顺序播放", Toast.LENGTH_SHORT).show();
                    mode = 1;
                    editor.putInt("mode",mode);
                    editor.commit();
                    break;
            }
        }

    });
}

private void seekbar_change(int progress) {
    Intent intent = new Intent();
    intent.setAction("com.app.media.MUSIC_SERVICE");
    intent.putExtra("op", PROGRESS_CHANGE);
    intent.putExtra("progress", progress);
    intent.setPackage(getPackageName());
    startService(intent);

}

private void play() {
    flag = PLAY;
    play_btn.setImageResource(R.drawable.pause_btn);
    final Intent intent = new Intent();
    intent.setPackage(getPackageName());
    Log.d("packnmee"," "+getPackageName());
    intent.setAction("com.app.media.MUSIC_SERVICE");
    intent.putExtra("op", PLAY);
    music_name.setText(_title[position]);
    singer_name.setText(_artist[position]);
    name.setText(_title[position]);
    startService(intent);

}

private void pause() {
    flag = PAUSE;
    play_btn.setImageResource(R.drawable.play_btn);
    Intent intent = new Intent();
    intent.setPackage(getPackageName());
    intent.setAction("com.app.media.MUSIC_SERVICE");
    intent.putExtra("op", PAUSE);
    startService(intent);
}

private void random(){
    int tmp =_id.length  - 1;
    Log.d("newnnn", " "+position);
    if(tmp > 0)
        position = new Random().nextInt(tmp);
    else
        position = 0;
    Log.d("newnnn", " "+position);
}

private void single(){

}

private void nextOne() {
    if(mode == 1){
        if (position == _id.length - 1) {
            position = 0;
        } else if (position < _id.length - 1) {
            position++;
        }
    }
    if(mode == 2)
        single();
    if(mode == 3)
        random();
    stop();
    setup();
    play();
}

private void preOne() {
    if(mode == 1){
        if (position == 0) {
            position = _id.length - 1;
        } else if (position > 0) {
            position--;
        }
    }

    if(mode == 2)
        single();
    if(mode == 3)
        random();
    stop();
    setup();
    play();
}

private void stop() {
    unregisterReceiver(musicreciver);
    Intent intent = new Intent();
    intent.setPackage(getPackageName());
    intent.setAction("com.app.media.MUSIC_SERVICE");
    intent.putExtra("op", STOP);
    startService(intent);

}

protected void onStart() {

    Log.d("OnStart"," ");
    super.onStart();
    setup();
    play();
}

@Override
protected void onStop() {
    super.onStop();
    unregisterReceiver(musicreciver);
}

@Override
protected void onRestart() {
    super.onRestart();
}

@Override
protected void onResume() {

    Log.d("OnResume", " ");
    super.onResume();
}

private void setup() {
    loadclip();
    init();
    ReadSDLrc();
}

private void init() {
    IntentFilter filter = new IntentFilter();
    filter.addAction(MUSIC_CURRENT);
    filter.addAction(MUSIC_DURATION);
    filter.addAction(MUSIC_NEXT);
    filter.addAction(MUSIC_UPDATE);
    registerReceiver(musicreciver, filter);

}

private void loadclip() {
    seekbar.setProgress(0);
    int id = _id[position];
    final Intent intent = new Intent();
    intent.setPackage(getPackageName());
    intent.putExtra("_id", id);
    intent.putExtra("_titles", _title);
    intent.putExtra("position", position);
    intent.setAction("com.app.media.MUSIC_SERVICE");// 给将这个action发送服务
    startService(intent);

}

private BroadcastReceiver musicreciver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(MUSIC_CURRENT)) {
            currentPosition = intent.getExtras().getInt("currentTime");
            play_time.setText(toTime(currentPosition));
            seekbar.setProgress(currentPosition);
            mylyc.setOffsetY(mylyc.getOffsetY() - mylyc.SpeedLrc());
            mylyc.SelectIndex(currentPosition);
            Iterator<Integer> iterator = lrc_map.keySet().iterator();
            while (iterator.hasNext()) {
                Object o = iterator.next();
                LRCbean val = lrc_map.get(o);
                if (val != null) {
                    if (currentPosition > val.getBeginTime() && currentPosition < val.getBeginTime() + val.getLineTime()) {
                        lrc_ima_page.setText(val.getLrcBody());
                        Log.d("hhh",val.getLrcBody());
                        break;
                    }
                }
            }
            mHandler.post(mUpdateResults);
        } else if (action.equals(MUSIC_DURATION)) {
            total = intent.getExtras().getInt("duration");// 获取总时间
            seekbar.setMax(total);// 进度条设置最大值(传总时间)
            total_time.setText(toTime(total));// 总时间设置转换的函数
        } else if (action.equals(MUSIC_NEXT)) {
            System.out.println("音乐继续播放下一首");
            nextOne();
        } else if (action.equals(MUSIC_UPDATE)) {
            position = intent.getExtras().getInt("position");
            setup();
        }

    }
};

public String toTime(int time) {

    time /= 1000;
    int minute = time / 60;
    int second = time % 60;
    minute %= 60;
    return String.format("%02d:%02d", minute, second);
}

private void ReadSDLrc() {
    cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            new String[] { MediaStore.Audio.Media.TITLE,
                    MediaStore.Audio.Media.DURATION,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media.ALBUM,
                    MediaStore.Audio.Media.DISPLAY_NAME,
                    MediaStore.Audio.Media.ALBUM_ID }, "_id=?",// 歌词是String数组的第4个参数,显示文件名字
            new String[] { _id[position] + "" }, null);
    cursor.moveToFirst();// 将游标移至第一位
    Bitmap bm = getArtwork(this, _id[position], cursor.getInt(5), true);
    pic.setImageBitmap(bm);
    String name = cursor.getString(4);// 游标定位到DISPLAY_NAME
    Log.d("ggg",name);
    Log.d("hahaha","/sdcard/music/" + name.substring(0, name.indexOf(".")) + ".lrc");
    read("/sdcard/music/" + name.substring(0, name.indexOf(".")) + ".lrc");
    mylyc.read("/sdcard/music/" + name.substring(0, name.indexOf(".")) + ".lrc");
    mylyc.SetTextSize();
    mylyc.setOffsetY(350);
    System.out.println("MMM"+cursor.getString(4));

}

private void read(String path) {
    lrc_map.clear();
    TreeMap<Integer, LRCbean> lrc_read = new TreeMap<Integer, LRCbean>();
    String data = "";
    BufferedReader br = null;
    File file = new File(path);
    System.out.println(path);
    if (!file.exists()) {
        lrc_ima_page.setText("歌词不存在");
        return;
    }
    FileInputStream stream = null;
    try {
        stream = new FileInputStream(file);
        br = new BufferedReader(new InputStreamReader(stream, "GB2312"));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        while ((data = br.readLine()) != null) {
            if (data.length() > 6) {
                if (data.charAt(3) == ':' && data.charAt(6) == '.') {// 从歌词正文开始
                    data = data.replace("[", "");
                    data = data.replace("]", "@");
                    data = data.replace(".", ":");
                    String lrc[] = data.split("@");
                    String lrcContent = null;
                    if (lrc.length == 2) {
                        lrcContent = lrc[lrc.length - 1];// 歌词
                    } else {
                        lrcContent = "";
                    }

                    for (int i = 0; i < lrc.length - 1; i++) {
                        String lrcTime[] = lrc[0].split(":");

                        int m = Integer.parseInt(lrcTime[0]);// 分
                        int s = Integer.parseInt(lrcTime[1]);// 秒
                        int ms = Integer.parseInt(lrcTime[2]);// 毫秒

                        int begintime = (m * 60 + s) * 1000 + ms;// 转换成毫秒
                        LRCbean lrcbean = new LRCbean();
                        lrcbean.setBeginTime(begintime);// 设置歌词开始时间
                        lrcbean.setLrcBody(lrcContent);// 设置歌词的主体
                        lrc_read.put(begintime, lrcbean);

                    }

                }
            }
        }
        stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 计算每句歌词需要的时间
    lrc_map.clear();
    data = "";
    Iterator<Integer> iterator = lrc_read.keySet().iterator();
    LRCbean oldval = null;
    int i = 0;

    while (iterator.hasNext()) {
        Object ob = iterator.next();
        LRCbean val = lrc_read.get(ob);
        if (oldval == null) {
            oldval = val;
        } else {
            LRCbean item1 = new LRCbean();
            item1 = oldval;
            item1.setLineTime(val.getBeginTime() - oldval.getBeginTime());
            lrc_map.put(new Integer(i), item1);
            i++;
            oldval = val;
        }
    }
}

//获取封面
public static Bitmap getArtwork(Context context, long song_id, long album_id, boolean allowdefault) {
    if (album_id < 0) {
        if (song_id >= 0) {
            Bitmap bm = getArtworkFromFile(context, song_id, -1);
            if (bm != null) {
                return bm;
            }
        }
        if (allowdefault) {
            return getDefaultArtwork(context);
        }
        return null;
    }

    ContentResolver res = context.getContentResolver();
    Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
    if (uri != null) {
        InputStream in = null;
        try {
            in = res.openInputStream(uri);
            Bitmap bmp = BitmapFactory.decodeStream(in, null, sBitmapOptions);
            if (bmp == null) {
                bmp = getDefaultArtwork(context);
            }
            return bmp;
        } catch (FileNotFoundException ex) {
            Bitmap bm = getArtworkFromFile(context, song_id, album_id);
            if (bm != null) {
                if (bm.getConfig() == null) {
                    bm = bm.copy(Bitmap.Config.RGB_565, false);
                    if (bm == null && allowdefault) {
                        return getDefaultArtwork(context);
                    }
                }
            } else if (allowdefault) {
                bm = getDefaultArtwork(context);
            }
            return bm;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return null;
}

private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
    Bitmap bm = null;
    if (albumid < 0 && songid < 0) {
        throw new IllegalArgumentException("Must specify an album or a song id");
    }
    try {

        BitmapFactory.Options options = new BitmapFactory.Options();

        FileDescriptor fd = null;
        if (albumid < 0) {
            Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
            if (pfd != null) {
                fd = pfd.getFileDescriptor();
                bm = BitmapFactory.decodeFileDescriptor(fd);
            }
        } else {
            Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid);
            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
            if (pfd != null) {
                fd = pfd.getFileDescriptor();
                bm = BitmapFactory.decodeFileDescriptor(fd,null,options);
            }
        }
        bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
    } catch (FileNotFoundException ex) {

    }

    return bm;
}

private static Bitmap getDefaultArtwork(Context context) {
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inPreferredConfig = Bitmap.Config.RGB_565;
    return BitmapFactory.decodeStream(context.getResources().openRawResource(+R.drawable.default_cover), null, opts);
}

Handler mHandler = new Handler();
Runnable mUpdateResults = new Runnable() {
    public void run() {
        mylyc.invalidate(); // 更新视图
    }
};

LocalMusicAdapter

package com.example.srct.adapter;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import com.example.srct.music.MusicListActivity;
import com.example.srct.music.R;

import static com.example.srct.music.MusicListActivity.getArtwork;

public class LocalMusicAdapter extends BaseAdapter {

private Context mcontext;// 上下文
private Cursor mcursor;// 游标
private ImageView selector;
private String str;

public List<Bitmap> pic = new LinkedList<Bitmap>();
private String[] title;// 标题
private String[] artist;// 艺术家


public LocalMusicAdapter(Context c, Cursor cur) {
    mcontext = c;
    mcursor = cur;
}

public LocalMusicAdapter(Context c,List<Bitmap> mpic,String[] mtitle,String[] martist) {
    mcontext = c;
    pic = mpic;
    title = mtitle;
    artist = martist;
}

public LocalMusicAdapter(Context c, Cursor cur, String string) {
    mcontext = c;
    mcursor = cur;
    str = string;
}

@Override
public int getCount() {
    if(mcursor != null)
        return mcursor.getCount();// 得到结果集中有多少记录
    else if(title.length != 0)
        return title.length;
    return 0;
}

@Override
public Object getItem(int position) {

    return position;
}

@Override
public long getItemId(int position) {

    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {


    ViewHolder holder;
    if(convertView != null){
        holder = (ViewHolder)convertView.getTag();
    }
    else{
        convertView = LayoutInflater.from(mcontext).inflate(R.layout.music_list_item, null);
        holder = new ViewHolder();
        holder.name = (TextView) convertView.findViewById(R.id.music_name);
        holder.singer = (TextView) convertView.findViewById(R.id.music_singer);
        holder.pic = (ImageView) convertView.findViewById(R.id.music_pic);
        holder.more = (ImageView) convertView.findViewById(R.id.music_more);
        convertView.setTag(holder);
    }

    if(mcursor != null){
        mcursor.moveToPosition(position);// 将游标移动到相应位置
        holder.singer.setText(mcursor.getString(2));
        String tmp = mcursor.getString(0);
        if(str != null){
            SpannableString s = new SpannableString(tmp);
            Pattern p = Pattern.compile(str,Pattern.CASE_INSENSITIVE);//正则表达式,大小写不敏感
            Matcher m = p.matcher(s);
            while (m.find()) {
                int start = m.start();
                int end = m.end();
                s.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            tmp = s.toString();
        }

        holder.name.setText(tmp);
        Bitmap bm = getArtwork(mcontext, mcursor.getInt(3),mcursor.getInt(mcursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)), true);
        if(bm != null)
            holder.pic.setImageBitmap(bm);
    }
    else{
        holder.singer.setText(artist[position]);

        String tmp = title[position];
        if(str != null){
            SpannableString s = new SpannableString(tmp);
            Pattern p = Pattern.compile(str,Pattern.CASE_INSENSITIVE);//正则表达式,大小写不敏感
            Matcher m = p.matcher(s);
            while (m.find()) {
                int start = m.start();
                int end = m.end();
                s.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            tmp = s.toString();
        }

        holder.name.setText(tmp);

        //Bitmap bm = getArtwork(mcontext, mcursor.getInt(3),mcursor.getInt(mcursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)), true);
        Bitmap bm = pic.get(position);
        if(bm != null)
            holder.pic.setImageBitmap(bm);

    }


    holder.more.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(mcontext,"click ", Toast.LENGTH_SHORT).show();

        }
    });

    return convertView;
}

public class ViewHolder{
    public TextView name;
    public TextView singer;
    public ImageView pic;
    public ImageView more;
}

}

ViewPagerAdapter

package com.example.srct.adapter;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;

/**

  • Created by srct on 2017/7/27.
    */

import android.content.Context;

import android.view.View;
import android.view.ViewGroup;

import java.util.List;

public class ViewPagerAdapter extends PagerAdapter {
private List list;
private Context context;

public ViewPagerAdapter(List<View> list) {
    this.list = list;

}

public ViewPagerAdapter(List<View> list, Context context) {
    this.list = list;
    this.context = context;

}

@Override
public int getCount() {
    if (list != null && list.size() > 0) {
        return list.size();
    }
    return 0;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    container.addView(list.get(position));
    return list.get(position);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView(list.get(position));
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

}

LRCbean

package com.example.srct.tools;

public class LRCbean {
private int beginTime = 0;
private int lineTime = 0;
private String lrcBody = null;

public int getBeginTime() {
	return beginTime;
}

public void setBeginTime(int beginTime) {
	this.beginTime = beginTime;
}

public int getLineTime() {
	return lineTime;
}

public void setLineTime(int lineTime) {
	this.lineTime = lineTime;
}

public String getLrcBody() {
	return lrcBody;
}

public void setLrcBody(String lrcBody) {
	this.lrcBody = lrcBody;
}

LyricView

package com.example.srct.tools;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LyricView extends View{

private static TreeMap<Integer, LyricObject> lrc_map;
private float mX;       //屏幕X轴的中点,此值固定,保持歌词在X中间显示
private float offsetY;      //歌词在Y轴上的偏移量,此值会根据歌词的滚动变小
private static boolean blLrc=false;
private float touchY;   //当触摸歌词View时,保存为当前触点的Y轴坐标
private float touchX;
private boolean blScrollView=false;
private int lrcIndex=0; //保存歌词TreeMap的下标
private  int SIZEWORD=50;//显示歌词文字的大小值
private  int INTERVAL=50;//歌词每行的间隔
Paint paint=new Paint();//画笔,用于画不是高亮的歌词
Paint paintHL=new Paint();  //画笔,用于画高亮的歌词,即当前唱到这句歌词

public LyricView(Context context){
    super(context);
    init();
}

public LyricView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

/* (non-Javadoc)
 * @see android.view.View#onDraw(android.graphics.Canvas)
 */
@Override
protected void onDraw(Canvas canvas) {
    if(blLrc){
        paintHL.setTextSize(SIZEWORD+5);
        paint.setTextSize(SIZEWORD);
        LyricObject temp=lrc_map.get(lrcIndex);
        canvas.drawText(temp.lrc, mX, offsetY+(SIZEWORD+INTERVAL)*lrcIndex, paintHL);
        // 画当前歌词之前的歌词
        for(int i=lrcIndex-1,tmp = i;i>=0&&i >= tmp -5  ;i--){
            temp=lrc_map.get(i);
            if(offsetY+(SIZEWORD+INTERVAL)*i<0){
                break;
            }
            canvas.drawText(temp.lrc, mX, offsetY+(SIZEWORD+INTERVAL)*i, paint);
        }
        // 画当前歌词之后的歌词
        for(int i=lrcIndex+1,tmp = i;i<lrc_map.size()&&i < tmp+5;i++){//往下画五句
            temp=lrc_map.get(i);

// if(offsetY+(SIZEWORD+INTERVAL)*i>600){
// break;
// }
canvas.drawText(temp.lrc, mX, offsetY+(SIZEWORD+INTERVAL)*i, paint);
}
}
else{
paint.setTextSize(100);
canvas.drawText(“找不到歌词”, mX, 400, paint);
}
super.onDraw(canvas);
}

/* (non-Javadoc)
 * @see android.view.View#onTouchEvent(android.view.MotionEvent)
 */
@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub
   /* System.out.println("bllll==="+blScrollView);
    float tt=event.getY();
    if(!blLrc){
        //return super.onTouchEvent(event);

        return super.onTouchEvent(event);
    }
    switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchX=event.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            touchY=tt-touchY;
            offsetY=offsetY+touchY;
            break;
        case MotionEvent.ACTION_UP:
            blScrollView=false;
            break;
    }
    touchY=tt;
    return true;*/
    return false;
}

public void init(){
    lrc_map = new TreeMap<Integer, LyricObject>();
    offsetY=400;//起始位置在Y轴的偏移量

    paint=new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setColor(Color.WHITE);
    paint.setAntiAlias(true);//抗锯齿
    paint.setDither(true);//防抖动
    paint.setAlpha(180);//透明度


    paintHL=new Paint();
    paintHL.setTextAlign(Paint.Align.CENTER);
    paintHL.setColor(Color.RED);
    paintHL.setAntiAlias(true);
    paintHL.setAlpha(255);
}

/**
 * 根据歌词里面最长的那句来确定歌词字体的大小
 */

public void SetTextSize(){
    if(!blLrc){
        return;
    }
    int max=lrc_map.get(0).lrc.length();
    for(int i=1;i<lrc_map.size();i++){
        LyricObject lrcStrLength=lrc_map.get(i);
        if(max<lrcStrLength.lrc.length()){
            max=lrcStrLength.lrc.length();
        }
    }

    Log.d("max", "hhppq  "+max);
    if(max > 50)
        SIZEWORD=35;
    else
        SIZEWORD = 50;

}

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mX = w * 0.5f;
    super.onSizeChanged(w, h, oldw, oldh);
}

/**
 *  歌词滚动的速度
 *
 * @return 返回歌词滚动的速度
 */
public Float SpeedLrc(){
    float speed=0;
    if(offsetY+(SIZEWORD+INTERVAL)*lrcIndex>220){
        speed=((offsetY+(SIZEWORD+INTERVAL)*lrcIndex-220)/20);
        Log.d("fff"," "+speed);

    } else if(offsetY+(SIZEWORD+INTERVAL)*lrcIndex < 120){
        Log.i("speed", "speed is too fast!!!");
        speed = 0;
    }

// if(speed<0.2){
// speed=0.2f;
// }
return speed;
}

/**
 * 按当前的歌曲的播放时间,从歌词里面获得那一句
 * @param time 当前歌曲的播放时间
 * @return 返回当前歌词的索引值
 */
public int SelectIndex(int time){
    if(!blLrc){
        return 0;
    }
    int index=0;
    for(int i=0;i<lrc_map.size();i++){
        LyricObject temp=lrc_map.get(i);
        if(temp.begintime<time){
            ++index;
        }
    }
    lrcIndex=index-1;
    if(lrcIndex<0){
        lrcIndex=0;
    }
    return lrcIndex;

}

/**
 * 读取歌词文件
 * @param file 歌词的路径
 *
 */
public static void read(String file) {
    TreeMap<Integer, LyricObject> lrc_read =new TreeMap<Integer, LyricObject>();
    String data = "";
    try {
        File saveFile=new File(file);
        // System.out.println("是否有歌词文件"+saveFile.isFile());
        if(!saveFile.isFile()){
            blLrc=false;
            return;
        }
        blLrc=true;

        //System.out.println("bllrc==="+blLrc);
        FileInputStream stream = new FileInputStream(saveFile);//  context.openFileInput(file);


        BufferedReader br = new BufferedReader(new InputStreamReader(stream,"GB2312"));
        int i = 0;
        Pattern pattern = Pattern.compile("\\d{2}");
        while ((data = br.readLine()) != null) {
            System.out.println("++++++++++++>>"+data);
            data = data.replace("[","");//将前面的替换成后面的
            data = data.replace("]","@");
            String splitdata[] =data.split("@");//分隔
            System.out.println("++++++++++++1>>"+data);
            if(data.endsWith("@")){
                for(int k=0;k<splitdata.length;k++){
                    String str=splitdata[k];
                    str = str.replace(":",".");
                    str = str.replace(".","@");
                    String timedata[] =str.split("@");
                    Matcher matcher = pattern.matcher(timedata[0]);
                    if(timedata.length==3 && matcher.matches()){
                        int m = Integer.parseInt(timedata[0]);  //分
                        int s = Integer.parseInt(timedata[1]);  //秒
                        int ms = Integer.parseInt(timedata[2]); //毫秒
                        int currTime = (m*60+s)*1000+ms*10;
                        LyricObject item1= new LyricObject();
                        item1.begintime = currTime;
                        item1.lrc       = "";
                        lrc_read.put(currTime,item1);
                    }
                }

            }
            else{
                String lrcContenet = splitdata[splitdata.length-1];

                for (int j=0;j<splitdata.length-1;j++)
                {
                    String tmpstr = splitdata[j];

                    tmpstr = tmpstr.replace(":",".");
                    tmpstr = tmpstr.replace(".","@");
                    String timedata[] =tmpstr.split("@");
                    Matcher matcher = pattern.matcher(timedata[0]);
                    if(timedata.length==3 && matcher.matches()){
                        int m = Integer.parseInt(timedata[0]);  //分
                        int s = Integer.parseInt(timedata[1]);  //秒
                        int ms = Integer.parseInt(timedata[2]); //毫秒
                        int currTime = (m*60+s)*1000+ms*10;
                        LyricObject item1= new LyricObject();
                        item1.begintime = currTime;
                        item1.lrc       = lrcContenet;
                        lrc_read.put(currTime,item1);// 将currTime当标签  item1当数据 插入TreeMap里
                        i++;
                    }
                }
            }

        }
        stream.close();
    }
    catch (FileNotFoundException e) {
    }
    catch (IOException e) {
    }

    /*
     * 遍历hashmap 计算每句歌词所需要的时间
    */
    lrc_map.clear();
    data ="";
    Iterator<Integer> iterator = lrc_read.keySet().iterator();
    LyricObject oldval  = null;
    int i =0;
    while(iterator.hasNext()) {
        Object ob =iterator.next();

        LyricObject val = (LyricObject)lrc_read.get(ob);

        if (oldval==null)
            oldval = val;
        else
        {
            LyricObject item1= new LyricObject();
            item1  = oldval;
            item1.timeline = val.begintime-oldval.begintime;
            lrc_map.put(new Integer(i), item1);
            i++;
            oldval = val;
        }
        if (!iterator.hasNext()) {
            lrc_map.put(new Integer(i), val);
        }

    }

}

/**
 * @return the blLrc
 */
public static boolean isBlLrc() {
    return blLrc;
}

/**
 * @return the offsetY
 */
public float getOffsetY() {
    return offsetY;
}

/**
 * @param offsetY the offsetY to set
 */
public void setOffsetY(float offsetY) {
    this.offsetY = offsetY;
}

/**
 * @return 返回歌词文字的大小
 */
public int getSIZEWORD() {
    return SIZEWORD;
}

/**
 * 设置歌词文字的大小
 * @param sIZEWORD the sIZEWORD to set
 */
public void setSIZEWORD(int sIZEWORD) {
    SIZEWORD = sIZEWORD;
}

public static class LyricObject {
    public int begintime; // 开始时间
    public int endtime; // 结束时间
    public int timeline; // 单句歌词用时
    public String lrc; // 单句歌词
}

PlayService

package com.example.srct.tools;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import java.io.IOException;

public class PlayService extends Service implements OnCompletionListener {

private MediaPlayer mp;// MediaPlayer对象
private static final int PLAYING = 1;// 定义该怎么对音乐操作的常量,如播放是1
private static final int PAUSE = 2;// 暂停事件是2
private static final int STOP = 3;// 停止事件是3
private static final int PROGRESS_CHANGE = 4;// 进度条改变事件设为4
private static final String MUSIC_CURRENT = "com.music.currentTime";
private static final String MUSIC_DURATION = "com.music.duration";
private static final String MUSIC_NEXT = "com.music.next";
private Handler handler;// handler对象
private Uri uri = null;// 路径地址
private int id = 100000;
private int currentTime;// 当前时间
private int duration;// 总时间

public PlayService() {
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return null;
}

@Override
public void onCreate() {
    if (mp != null) {
        mp.release();// 建立服务先清空
        mp.reset();// 回起始点
        mp = null;
    }
    mp = new MediaPlayer();// 实例化Mdiaplayer对象
    mp.setOnCompletionListener(this);// 加下一首监听,网络流媒体播放结束监听
    IntentFilter intentfilter=new IntentFilter();
    intentfilter.addAction("com.app.media.MUSIC_SERVICE");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("onStartCommand entered"," ioio");
    int _id = intent.getIntExtra("_id", -1);
    Log.d("msgg","hhppa "+_id);
    if (_id!=-1){
        //if (id!=_id){
            id=_id;
            uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, "" + _id);

            Log.d("msgg",uri.toString());
            try {
                mp.reset();
                mp.setDataSource(this, uri);

            } catch (Exception e) {
                e.printStackTrace();
            }
        //}
    }
    setup();
    Load();// 初始化服务
    int op = intent.getIntExtra("op", -1);// 从UI接收到的数据交给服务处理
    // 从接收的数据中作判断播放操作
    if (op != -1) {
        switch (op) {
            case PLAYING:
                play();// 播放音乐
                break;

            case PAUSE:
                pause();// 暂停音乐
                break;

            case STOP:
                stop();// 停止播放
                break;
            // 进度条改变
            case PROGRESS_CHANGE:
                int progress = intent.getExtras().getInt("progress");
                mp.seekTo(progress);
                break;

        }
    }
    return START_NOT_STICKY;
}

@Override
public void onDestroy() {

    Log.d("ioio","ondestroy");
    super.onDestroy();
    if (mp != null) {
        mp.stop();
        mp = null;
    }
    if (handler != null) {
        handler.removeMessages(1);
        handler = null;
    }
}


public void play() {
    if (mp != null) {
        mp.start();
    }

}

public void pause() {
    if (mp != null) {
        mp.pause();
    }
}

// 停止播放
public void stop() {
    if (mp != null) {
        mp.stop();
        try {
            mp.prepare();
            mp.seekTo(0);
        } catch (IllegalStateException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }
        handler.removeMessages(1);

    }
}

public void setup() {
    final Intent intent = new Intent();
    intent.setAction(MUSIC_DURATION);
    try {
        if (!mp.isPlaying()) {
            mp.prepare();
            mp.start();
        } else if (!mp.isPlaying()) {
            mp.stop();
        }
        mp.setOnPreparedListener(new OnPreparedListener() {

            @Override
            public void onPrepared(MediaPlayer mp) {
                handler.sendEmptyMessage(1);

            }
        });
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    duration = mp.getDuration();
    intent.putExtra("duration", duration);
    sendBroadcast(intent);
}

public void Load() {
    final Intent intent = new Intent();
    intent.setAction(MUSIC_CURRENT);
    handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                currentTime = mp.getCurrentPosition();
                intent.putExtra("currentTime", currentTime);
                sendBroadcast(intent);

            }
            handler.sendEmptyMessageDelayed(1, 610);
        }

    };
}

@Override
public void onCompletion(MediaPlayer mp) {
    Intent intent = new Intent();
    intent.setAction(MUSIC_NEXT);
    sendBroadcast(intent);
    System.out.println("onCompletion...");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值