用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的文章,希望對你有所幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章