用AndroidStudio播放網易雲本地音樂
阿新 • • 發佈:2019-01-05
網易雲音樂是一款非常優秀的音樂軟體,它的播放介面由唱片機組成,顯得非常的古樸典雅。
現在我們就用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的文章,希望對你有所幫助。