1.喜马拉雅开放平台注册/审核后,在“我的应用”中创建应用
2.添加内容信息
3.我使用的是android studio androidmainfest中配置
权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<meta-data
android:name="app_key"
android:value="申请应用中的appkey" />
<meta-data
android:name="pack_id"
android:value="申请应用中的包名" />service/receiver:
<service android:name="com.ximalaya.ting.android.opensdk.player.service.XmPlayerService"
android:exported="true" android:process=":player" >
</service>
<receiver
android:name="com.ximalaya.ting.android.opensdk.player.receive.PlayerReceiver"
android:exported="true" android:process=":player" >
<intent-filter>
<action android:name="com.ximalaya.ting.android.ACTION_CONTROL_START_PAUSE" />
<action android:name="com.ximalaya.ting.android.ACTION_CONTROL_PLAY_PRE" />
<action android:name="com.ximalaya.ting.android.ACTION_CONTROL_PLAY_NEXT" />
<action android:name="com.ximalaya.ting.android.ACTION_CLOSE" />
<action android:name="com.ximalaya.ting.android.ACTION_CONTROL_RELEASE_SERVICE" />
</intent-filter>
</receiver>
<receiver android:name="com.ximalaya.ting.android.opensdk.player.receive.WireControlReceiver"
android:process=":player"
android:exported="true" />
<receiver android:name="com.ximalaya.ting.android.opensdk.test.reciver.MyPlayerReceiver" android:exported="true" android:process=":player">
<intent-filter>
<action android:name="com.app.test.android.Action_Close"/>
</intent-filter>
</receiver>
- app_key:开放平台应用公钥
- app_secret:开放平台应用私钥,请务必加密存储,切勿泄露
- pack_id:客户端包名,对Android客户端是apk包名
4.添加包-放入项目lib中
还有这个
build.gradle
(表油德。哥软斗)
android {
...
productFlavors{
arm{
ndk{
abiFilters "armeabi" ,"armeabi-v7a"
}
}
}
}5.混淆
-dontwarn okio.**
-keep class okio.** { *;}
-dontwarn okhttp3.**
-keep class okhttp3.** { *;}
-dontwarn com.google.gson.**
-keep class com.google.gson.** { *;}
-dontwarn android.support.**
-keep class android.support.** { *;}
-dontwarn com.ximalaya.ting.android.player.**
-keep class com.ximalaya.ting.android.player.** { *;}
-dontwarn com.ximalaya.ting.android.opensdk.**
-keep interface com.ximalaya.ting.android.opensdk.** {*;}
-keep class com.ximalaya.ting.android.opensdk.** { *; }6.可以开搞了 嗯嗯。。
application类中在oncreate中初始化喜马拉雅参数。
CommonRequest.getInstanse().init(context, appSecret);然后我自己定义了一个service,来用于初始化,播放,暂停 (由于项目功能要求不高,所以这一块就实现了2个实施功能)
2部分内容如下。
application 片段
private void initXmly() {private RequestTracker requestTracker = new RequestTracker() {
@Override
public void onWaiting(RequestParams params) {
Logger.log("TingApplication : onWaiting " + params);
}
@Override
public void onStart(RequestParams params) {
Logger.log("TingApplication : onStart " + params);
}
@Override
public void onRequestCreated(UriRequest request) {
Logger.log("TingApplication : onRequestCreated " + request);
}
@Override
public void onSuccess(UriRequest request, Object result) {
Logger.log("TingApplication : onSuccess " + request + " result = " + result);
}
@Override
public void onRemoved(UriRequest request) {
Logger.log("TingApplication : onRemoved " + request);
}
@Override
public void onCancelled(UriRequest request) {
Logger.log("TingApplication : onCanclelled " + request);
}
@Override
public void onError(UriRequest request, Throwable ex, boolean isCallbackError) {
Logger.log("TingApplication : onError " + request + " ex = " + ex + " isCallbackError = " + isCallbackError);
}
@Override
public void onFinished(UriRequest request) {
Logger.log("TingApplication : onFinished " + request);
}
};自定义service
public class DeviceXmlyPlayService extends Service {
private XmPlayerManager mPlayerManager;
private final String TAG=DeviceXmlyPlayService.class.getSimpleName();
private Intent it;
public class MyPlayBinder extends Binder {
public DeviceXmlyPlayService getService(){
return DeviceXmlyPlayService.this;
}
}
private MyPlayBinder binder=new MyPlayBinder();
@Override
public void onCreate() {
super.onCreate();
initPlayData();
it=new Intent(CustomStaticCode.XMLY_PLAYER_RECEIVER);
}
private void initPlayData() {
mPlayerManager = XmPlayerManager.getInstance(this);
Notification mNotification = XmNotificationCreater.getInstanse(this).initNotification(this, DcviceStoryDetalActivity.class);
mNotification.icon=R.drawable.mzlogo;
mPlayerManager.init((int) System.currentTimeMillis(), mNotification);
mPlayerManager.addPlayerStatusListener(mPlayerStatusListener);
mPlayerManager.setOnConnectedListerner(new XmPlayerManager.IConnectListener() {
@Override
public void onConnected() {
mPlayerManager.setPlayMode(XmPlayListControl.PlayMode.PLAY_MODEL_LIST_LOOP);
// ToastUtils.toast("初始化播放器成功");
}
});
XmPlayerManager.getInstance(this).setCommonBusinessHandle(XmDownloadManager.getInstance());
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public void playTracks(List<Track> track, int positon){
mPlayerManager.playList(track, positon);
}
public void pauseTracks(){
if (mPlayerManager.isPlaying()) {
mPlayerManager.pause();
} else {
mPlayerManager.play();
}
}
public boolean isPlaying(){
return mPlayerManager.isPlaying();
}
public int getPlayListSize(){
return mPlayerManager.getPlayListSize();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private IXmPlayerStatusListener mPlayerStatusListener = new IXmPlayerStatusListener() {
@Override
public void onSoundPrepared() {
// mSeekBar.setEnabled(true);
// mProgress.setVisibility(View.GONE);
}
@Override
public void onSoundSwitch(PlayableModel laModel, PlayableModel curModel) {
PlayableModel model = mPlayerManager.getCurrSound();
if (model != null) {
String title = null;
String coverUrl = null;
if (model instanceof Track) {
Track info = (Track) model;
title = info.getTrackTitle();
coverUrl = info.getCoverUrlLarge();
} else if (model instanceof Schedule) {
Schedule program = (Schedule) model;
title = program.getRelatedProgram().getProgramName();
coverUrl = program.getRelatedProgram().getBackPicUrl();
} else if (model instanceof Radio) {
Radio radio = (Radio) model;
title = radio.getRadioName();
coverUrl = radio.getCoverUrlLarge();
}
}
updateButtonStatus();
}
private void updateButtonStatus() {
}
@Override
public void onPlayStop() {
Bundle b=new Bundle();
b.putInt("status", CustomStaticCode.XMLY_NOW_STOP);
it.putExtras(b);
MyBaseApplication.getApplication().sendBroadcast(it);
}
@Override
public void onPlayStart() {
Bundle b=new Bundle();
b.putInt("status", CustomStaticCode.XMLY_NOW_PLAY);
it.putExtras(b);
MyBaseApplication.getApplication().sendBroadcast(it);
}
@Override
public void onPlayProgress(int currPos, int duration) {
String title = "";
PlayableModel info = mPlayerManager.getCurrSound();
if (info != null) {
if (info instanceof Track) {
title = ((Track) info).getTrackTitle();
} else if (info instanceof Schedule) {
title = ((Schedule) info).getRelatedProgram().getProgramName();
} else if (info instanceof Radio) {
title = ((Radio) info).getRadioName();
}
}
// mTextView.setText(title + "[" + ToolUtil.formatTime(currPos) + "/" + ToolUtil.formatTime(duration) + "]");
// if (mUpdateProgress && duration != 0) {
// mSeekBar.setProgress((int) (100 * currPos / (float) duration));
// }
}
@Override
public void onPlayPause() {
Bundle b=new Bundle();
b.putInt("status", CustomStaticCode.XMLY_NOW_PAUSE);
it.putExtras(b);
MyBaseApplication.getApplication().sendBroadcast(it);
}
@Override
public void onSoundPlayComplete() {
}
@Override
public boolean onError(XmPlayerException exception) {
stopSelf();
return false;
}
@Override
public void onBufferProgress(int position) {
// mSeekBar.setSecondaryProgress(position);
}
public void onBufferingStart() {
// mSeekBar.setEnabled(false);
// mProgress.setVisibility(View.VISIBLE);
}
public void onBufferingStop() {
// mSeekBar.setEnabled(true);
// mProgress.setVisibility(View.GONE);
}
};
@Override
public void onDestroy() {
super.onDestroy();
if (mPlayerManager != null) {
mPlayerManager.removePlayerStatusListener(mPlayerStatusListener);
mPlayerManager.release();
}
it=null;
}7.具体初始化基本完成 接下来就开始使用了。
我的项目只要需要儿童节目,对应抓包时候已经儿童节目的系列ID拿到手,所以在使用界面中 直接使用儿童系列的分类id
下面是我提供的工具UTIL 使用handler回传的数据
public class XMLYTingUtil {
private Handler handler;
private String TAG="XMLYTingUtilLOG";
public XMLYTingUtil(Context context, Handler handler) {
this.handler=handler;
}
//获取全部频道 (暂不用)
public void getCategories(){
CommonRequest.getCategories(null, new IDataCallBack<CategoryList>() {
@Override
public void onSuccess(CategoryList object) {
List<Category> categories = object.getCategories();
for (int i = 0; i < categories.size(); i++) {
Category c=categories.get(i);
}
}
@Override
public void onError(int code, String message) {
Log.e(TAG, "onCreate: code = [" + code + "], message = [" + message + "]");
// LogUtils.log("code = [" + code + "], message = [" + message + "]");
}
});
}
/**
* 获取对应儿童节目下的便签
* @param type 0-专辑标签,1-声音标签
*/
public void getChildTag(String type){
Map<String, String> mapx = new HashMap<String, String>();
mapx.put(DTransferConstants.CATEGORY_ID, CustomStaticCode.CATEGORY_ID+"");
mapx.put(DTransferConstants.TYPE, type.equals("") ? "0":type);
CommonRequest.getTags(mapx, new IDataCallBack<TagList>() {
@Override
public void onSuccess(TagList tagList) {
List<Tag> tlist = tagList.getTagList();
Message msg=Message.obtain();
msg.obj=tlist;
msg.arg1=999;
msg.what=CustomStaticCode.MESSAGE_CHILD_TAG;
handler.sendMessage(msg);
}
@Override
public void onError(int i, String s) {
Message msg=Message.obtain();
msg.obj=s;
msg.arg1=i;
msg.what=CustomStaticCode.MESSAGE_CHILD_TAG;
handler.sendMessage(msg);
}
});
}
/**
* 获取标签下的专辑
* @param tagName 分类名称
* @param page 页码 默认为1
* @param calc 最火(1),最新(2),经典或播放最多(3) 默认最火
*/
public void getAlbumList(String tagName,String page,String calc){
Map<String,String> map = new HashMap<String,String>();
map.put(DTransferConstants.CATEGORY_ID, "" + CustomStaticCode.CATEGORY_ID);
map.put(DTransferConstants.TAG_NAME, tagName);
map.put(DTransferConstants.PAGE, page.equals("") ? "1":page);
map.put(DTransferConstants.CALC_DIMENSION,calc.equals("") ? "1":calc);
CommonRequest.getAlbumList(map, new IDataCallBack<AlbumList>() {
@Override
public void onSuccess(AlbumList albumList) {
List<Album> albums = albumList.getAlbums();
Message msg=Message.obtain();
msg.obj=albums;
msg.arg1=999;
msg.what=CustomStaticCode.MESSAGE_ALBUM_TAG;
handler.sendMessage(msg);
}
@Override
public void onError(int i, String s) {
Message msg=Message.obtain();
msg.obj=s;
msg.arg1=i;
msg.what=CustomStaticCode.MESSAGE_ALBUM_TAG;
handler.sendMessage(msg);
}
});
}
/**
* 获取音频
* @param albumId 专辑ID
* @param sort 排序
* @param page 页码
*/
public void getTrack(String albumId,String sort,String page){
Map<String, String> maps = new HashMap<String, String>();
maps.put(DTransferConstants.ALBUM_ID, albumId);
maps.put(DTransferConstants.SORT, sort.equals("") ? "asc" : sort);
maps.put(DTransferConstants.PAGE, page.equals("") ? "1":page);
CommonRequest.getTracks(maps, new IDataCallBack<TrackList>() {
@Override
public void onSuccess(TrackList trackList) {
List<Track> tracks = trackList.getTracks();
Message msg=Message.obtain();
msg.obj=tracks;
int size = tracks.size();
if(size!=20){
msg.arg2=0;
}
msg.arg1=999;
msg.what=CustomStaticCode.MESSAGE_TRACK_TAG;
handler.sendMessage(msg);
}
@Override
public void onError(int i, String s) {
Message msg=Message.obtain();
msg.obj=s;
msg.arg1=i;
msg.what=CustomStaticCode.MESSAGE_TRACK_TAG;
handler.sendMessage(msg);
}
});
}
}CATEGORY_ID=6 //儿童频道
如果想查询对应的频道分类ID的话 可以参考getCategories这个方法来查阅对应id我的主界面是fragment 下面是代码
private TabLayout dcStoryMainTablayout;
private ViewPager dcStoryMainViewpager;
private XMLYTingUtil xmUtil;
private ArrayList<Tag> tlist;
private ImageView dcStoryMainPlay;
private ServiceConnection conn;
private DeviceXmlyPlayService mservice;
private UpdateImageReceiver updateImageReceiver;
private Handler handler=new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
int what = msg.what;
switch (what){
case CustomStaticCode.MESSAGE_CHILD_TAG:
int state = msg.arg1;
if(state==999){
tlist= (ArrayList<Tag>) msg.obj;
initTablayout();
xmUtil=null;
}else{
ToastUtils.toast("错误信息:"+msg.obj+"\n错误码:"+state);
}
break;
}
return false;
}
});
@Override
public void initData() {
super.initData();
IntentFilter receiver =new IntentFilter();
receiver.addAction(CustomStaticCode.XMLY_PLAYER_RECEIVER);
updateImageReceiver = new UpdateImageReceiver();
MyBaseApplication.getApplication().registerReceiver(updateImageReceiver,receiver);
}
private void initPlay() {
conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
DeviceXmlyPlayService.MyPlayBinder binder = (DeviceXmlyPlayService.MyPlayBinder) service;
mservice=binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
toast("连接失败..");
}
};
a.bindService(new Intent(a, DeviceXmlyPlayService.class),conn, Service.BIND_AUTO_CREATE);
}
@Override
public View initView(LayoutInflater inflater, @Nullable ViewGroup container) {
View v=inflater.inflate(R.layout.activity_device_story_main,null);
xmUtil=new XMLYTingUtil(getActivity(),handler);
init(v);
return v;
}
private void init(View root) {
dcStoryMainTablayout = (TabLayout) root.findViewById(R.id.dc_story_main_tablayout);
dcStoryMainViewpager = (ViewPager) root.findViewById(R.id.dc_story_main_viewpager);
dcStoryMainPlay = (ImageView) root.findViewById(R.id.dc_story_main_play);
dcStoryMainViewpager.setOffscreenPageLimit(1);
xmUtil.getChildTag("0");
initPlay();
dcStoryMainPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int playListSize = mservice.getPlayListSize();
if(playListSize<=0){
toast("请选择播放目录后再播放音乐哟~");
return;
}
mservice.pauseTracks();
setImageState();
}
});
}
private void initTablayout(){
ArrayList<Fragment> fragmentArrayList=new ArrayList<>();
if(tlist!=null&&tlist.size()>0){
initFragmentList(fragmentArrayList);
StoryMainFragmentAdapter smadapter=new StoryMainFragmentAdapter(getActivity().getSupportFragmentManager(),fragmentArrayList,tlist);
dcStoryMainViewpager.setAdapter(smadapter);
dcStoryMainTablayout.setTabMode(TabLayout.MODE_SCROLLABLE);
dcStoryMainTablayout.setupWithViewPager(dcStoryMainViewpager);
dcStoryMainViewpager.setCurrentItem(0);
dcStoryMainTablayout.getTabAt(0).select();
}
}
private void initFragmentList(ArrayList<Fragment> fragmentArrayList){
// fragmentArrayList.add(new StoryHotFragment(tlist.get(0).getTagName()));
int count=tlist.size();
for (int i = 0; i < count; i++) {
String tag=tlist.get(i).getTagName();
// if(tag.indexOf("0-2")!=1|| tag.indexOf("付费")!=1) continue;
StoryItemFragment sf=new StoryItemFragment(tag);
fragmentArrayList.add(sf);
}
}
private void setImageState(){
boolean playing = mservice.isPlaying();
if(playing){
dcStoryMainPlay.setImageResource(R.drawable.story_top_pause3x);
}else{
dcStoryMainPlay.setImageResource(R.drawable.story_top_play3x);
}
}
class UpdateImageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(CustomStaticCode.XMLY_PLAYER_RECEIVER)){
Bundle status = intent.getExtras();
int state=status.getInt("status",Integer.MIN_VALUE);
if(state!=Integer.MIN_VALUE){
if(state==CustomStaticCode.XMLY_NOW_PLAY){
dcStoryMainPlay.setImageResource(R.drawable.story_top_pause3x);
}else if(state==CustomStaticCode.XMLY_NOW_PAUSE || state==CustomStaticCode.XMLY_NOW_STOP){
dcStoryMainPlay.setImageResource(R.drawable.story_top_play3x);
}
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
if(updateImageReceiver!=null){
try {
a.unregisterReceiver(updateImageReceiver);
}catch (Exception e){
updateImageReceiver=null;
}
}
if(conn!=null){
try {
a.unbindService(conn);
}catch (Exception e){
conn=null;
}
}
}剩下的播放,切换,暂停,停止 就相对比较简单了,直接操作对应的service 就行了。
结束语
喜马拉雅SDK中还是很人性化的文档的 包含对应的moel类说明 和具体的操作说明。
整体来说使用感觉还是不错的,不过有时候还会有喜马拉雅的开篇广告,这个挺烦人的。

如果有什么不明白的 可以留言一起探讨。
泄泄~~

本文介绍了如何将喜马拉雅FM的SDK整合到Android项目中,包括在喜马拉雅开放平台注册应用、添加内容信息,以及在AndroidManifest.xml中配置必要的权限和服务设置。
919





