1. 程式人生 > >用AndroidStudio播放網易雲本地音樂

用AndroidStudio播放網易雲本地音樂

網易雲音樂是一款非常優秀的音樂軟體,它的播放介面由唱片機組成,顯得非常的古樸典雅。

現在我們就用AndirdStudio來實現這個任務:

效果圖
這裡寫圖片描述
這裡寫圖片描述

第一步:建立一個新的專案,例如wymusicdemo12
這裡寫圖片描述
第二步:在java目錄下的第一個資料夾下建立3個包檔案
adapter、entity和fragment
第三步:建立佈局檔案music_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal">
<ImageView android:id="@+id/music_item_bmg" android:layout_width="50dp" android:layout_height="50dp" android:src="@mipmap/ic_launcher"/> <TextView
android:id="@+id/music_item_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="成都"/>
<TextView android:id="@+id/music_item_artist" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="趙雷" android:layout_gravity="bottom" />
</LinearLayout> 第四步寫主函式的佈局檔案 `` <?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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context="com.example.user.wymusicdemo1.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:id="@+id/mian_local_tv" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="1" android:text="本地音樂" android:textSize="20sp" android:gravity="center" /> <TextView android:id="@+id/mian_online_tv" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="1" android:text="線上音樂" android:textSize="20sp"/> </LinearLayout> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/mian_vp"> </android.support.v4.view.ViewPager> </LinearLayout>

第五步:在adpter下建立2個類
MusicListAdapter和MusicPagerAdapter
entity下建立1個類
Music
fragment下建立2個fragment檔案(注意不是新建類)
LocalMusicFragment和OnlineMusicFragment
這裡寫圖片描述
敲黑板了:由於不需要相應的功能,可以不需要勾選第二個第三個選項,使程式碼看起來不那麼複雜。
OnlineMusicFragment需要聯網,暫時不考慮,我們選擇寫本地檔案也就是LocalMusicFragment
程式碼實現如下

package com.example.user.wymusicdemo1.fragment;


import android.Manifest;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
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.ListView;

import com.example.user.wymusicdemo1.R;
import com.example.user.wymusicdemo1.adapter.MusicListAdapter;
import com.example.user.wymusicdemo1.entity.Music;

import java.security.Permission;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 */
public class LocalMusicFragment extends Fragment {
    private ListView localListView;
    private List<Music> musicList;


    public LocalMusicFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_local_music, container, false);
        localListView = view.findViewById(R.id.mian_local_tv);

        return view;
    }


    private void initListView() {
        musicList = new ArrayList<>();
        ContentResolver resolver = getActivity().getContentResolver();
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
        cursor.moveToFirst();
        do {

            Music m = new Music();
            m.title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            m.artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
            m.album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            m.path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            m.length = Integer.parseInt(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));
            //獲取專輯ID
            int albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
            //根據專輯ID獲取到專輯封面圖
            m.thumbBitmap = getAlbumArt(albumId);

            musicList.add(m);
        } while (cursor.moveToFirst());
        cursor.close();


        MusicListAdapter adapter = new MusicListAdapter(musicList, getActivity());
        localListView.setAdapter(adapter);


    private Bitmap getAlbumArt(int album_id) {
        String mUriAlbums = "content://media/external/audio/albums";
        String[] projection = new String[]{"album_art"};
        Cursor cur = context.getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(album_id)), projection, null, null, null);
        String album_art = null;
        if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
            cur.moveToNext();
            album_art = cur.getString(0);
        }
        cur.close();
        Bitmap bm = null;
        if (album_art != null) {
            bm = BitmapFactory.decodeFile(album_art);
        } else {
            bm = BitmapFactory.decodeResource(getResources(), R.drawable.default_cover);
        }
        return bm;
    }
}

}

這裡涉及到一個許可權問題
在Android 5.0裝置執行時,可以得到正確結果,但在Android 6.0以上裝置執行時,提示沒有讀寫許可權。但AndroidManifest檔案中已經設定過許可權了。
方法解決如下

public class MainActivity extends AppCompatActivity {

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

        //檢查當前許可權(若沒有該許可權,值為-1;若有該許可權,值為0)
        int hasReadExternalStoragePermission = ContextCompat.checkSelfPermission(getApplication(),Manifest.permission.READ_EXTERNAL_STORAGE);
        Log.e("PERMISION_CODE",hasReadExternalStoragePermission+"***");
        if(hasReadExternalStoragePermission== PackageManager.PERMISSION_GRANTED){
            obtainMediaInfo();
        }else{
            //若沒有授權,會彈出一個對話方塊(這個對話方塊是系統的,開發者不能自己定製),使用者選擇是否授權應用使用系統許可權
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
        }

    }

    //使用者選擇是否同意授權後,會回撥這個方法
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(requestCode==1){
            if(permissions[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE)&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                //使用者同意授權,執行讀取檔案的程式碼
                obtainMediaInfo();
            }else{
                //若使用者不同意授權,直接暴力退出應用。
                // 當然,這裡也可以有比較溫柔的操作。
                finish();
            }
        }
    }

    //將之前獲取音樂資訊的程式碼單獨封裝到了一個方法裡面
    private void obtainMediaInfo() {
        Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
        cursor.moveToFirst();
        do {
            String title = cursor.getString(cursor.getColumnIndex("title"));
            Log.e("TITLE",title);
        }while (cursor.moveToNext());
    }
}

接著實現播放介面中獲取本地音樂的出操作
獲取音訊檔案專輯ID和根據專輯ID繼續獲取專輯封面圖
程式碼如下

ContentResolver resolver = context.getContentResolver();
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
        cursor.moveToFirst();
        do {
            Music m = new Music();
            m.name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            m.artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
            m.album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            m.path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            m.length = Integer.parseInt(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));
            //獲取專輯ID
            int albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
            //根據專輯ID獲取到專輯封面圖
            m.thumbBitmap = getAlbumArt(albumId);

            musicList.add(m);
        } while (cursor.moveToNext());
        cursor.close();
/**
     * 根據專輯ID獲取專輯封面圖
     * @param album_id 專輯ID
     * @return
     */
    private Bitmap getAlbumArt(int album_id) {
        String mUriAlbums = "content://media/external/audio/albums";
        String[] projection = new String[]{"album_art"};
        Cursor cur = context.getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(album_id)), projection, null, null, null);
        String album_art = null;
        if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
            cur.moveToNext();
            album_art = cur.getString(0);
        }
        cur.close();
        Bitmap bm = null;
        if (album_art != null) {
            bm = BitmapFactory.decodeFile(album_art);
        } else {
            bm = BitmapFactory.decodeResource(getResources(), R.drawable.default_cover);
        }
        return bm;
    }

寫完了,其實當中可能會有一些錯誤,還有一些參考了3052world的文章,希望對你有所幫助。