Xamarin.Android开发音乐播放器

最近.Net开源着实让C#火了一把,好久就听说Mono for Android一直没静下心来看,上周末找来看看,确实不错,前台界面axml编写跟Java安卓开发毫无区别,后台用C#其实很多windows下的方法都可以用,做一个安卓音乐播放器,主要实现音乐播放,上一曲下一曲,音乐播放列表,随机播放,扫描SD卡内所有音乐。

先show一组界面啊,话说有图有真相啊:

项目结构如图:

Lrc是歌词处理方法

MusicService是安卓服务播放音乐,服务Broadcast,以及界面接收Receiver

SqlHelper是歌曲扫描后寸本地数据库Sqlite的一些方法

说说几个难点:

音乐扫描:

主要就是遍历目录,代码如下

			IList<FileSystemInfo> visibleThings = new List<FileSystemInfo> ();
			var dir = new DirectoryInfo (directory);

			try {
				foreach (var item in dir.GetFileSystemInfos().Where(item => item.IsVisible())) {
					visibleThings.Add (item);
					if (item.IsDirectory ()) {
						RefreshFilesList (item.FullName);
					}
					if (item.IsFile () && (item.FullName.Substring (item.FullName.LastIndexOf (".") + 1)) == "mp3") {

			
					//是音乐文件

					}

  ListView添加数据,这个主要用到ListAdapter,ListAdapter是新建一个前台xaml界面,每个界面存放一首歌曲,然后最后把遍历所有歌曲加入N个界面,这N个界面加入ListView,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:id="@+id/songid"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:textColor="#FF7F3300"
        android:textSize="0dip"
        android:textStyle="italic"
        android:visibility="invisible" />
    <TextView
        android:id="@+id/songtitle"
        android:layout_width="wrap_content"
        android:layout_height="50dip"
        android:textSize="20dip"
        android:textColor="#FFFFFF"
        android:paddingLeft="5dip"
        android:gravity="center_vertical|left" />
    <TextView
        android:id="@+id/songurl"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:visibility="invisible" />
</LinearLayout>

  后台代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;

namespace MusicPlayer

{
	public class SongListAdapter: BaseAdapter<SongDetail>
	{   List<SongDetail> items;

		Activity context;
		public SongListAdapter (Activity context, List<SongDetail> items) : base()
		{
			this.context = context;
			this.items = items;

		}
		public override long GetItemId(int position)
		{
			return position;
		}
		public override SongDetail this[int position]
		{
			get { return items[position]; }
		}
		public override int Count
		{
			get { return items.Count; }
		}
		public override View GetView(int position, View convertView, ViewGroup parent)
		{
			var item = items[position];
			View view = convertView;
			if (view == null)
				view = context.LayoutInflater.Inflate(Resource.Layout.SongItem, null);
			view.FindViewById<TextView>(Resource.Id.songid).Text = item.ID.ToString();
			view.FindViewById<TextView>(Resource.Id.songtitle).Text = item.Title;
			view.FindViewById<TextView>(Resource.Id.songurl).Text=(item.Path);

			return view;
		}
	
	}
}

  listView加入方式:

Lv = FindViewById<ListView> (Resource.Id.listView1);
			
Lv.Adapter = new SongListAdapter (this, SonList);

  其中sonlist是遍历除了所有歌曲List集合

至于安卓服务,主要就是继承Service,主要代码:

[Service]
    public class MainService : Service
    {
        public override void OnCreate()
        {
            base.OnCreate();
            Log.Debug("xamarin", "创建服务");
        }

        public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {
            Log.Debug("xamarin", "启动服务");
            return StartCommandResult.Sticky;
        }

        public override void OnDestroy()
        {
            base.OnDestroy();
            Log.Debug("xamarin", "关闭服务");
        }

        public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
        {
            return null;
        }
}

  最后歌词显示,主要用到就是解析歌词,解析歌词C#下面有代码可参考,不知道具体怎么解析的搜搜winform做音乐播放器歌词是怎么做的,其实就是一个播放但钱position和播放时间转换成position的一个匹配,下面看解析歌词的方法:

public class Lrc
    {
        /// <summary>
        /// 歌曲
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 艺术家
        /// </summary>
        public string Artist { get; set; }
        /// <summary>
        /// 专辑
        /// </summary>
        public string Album { get; set; }
        /// <summary>
        /// 歌词作者
        /// </summary>
        public string LrcBy { get; set; }
        /// <summary>
        /// 偏移量
        /// </summary>
        public string Offset { get; set; }

        /// <summary>
        /// 歌词
        /// </summary>
        public Dictionary<double, string> LrcWord = new Dictionary<double, string>();

        /// <summary>
        /// 获得歌词信息
        /// </summary>
        /// <param name="LrcPath">歌词路径</param>
        /// <returns>返回歌词信息(Lrc实例)</returns>
        public static Lrc InitLrc(string LrcPath)
        {
            Lrc lrc = new Lrc();
            using (FileStream fs = new FileStream(LrcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                string line;
                using (StreamReader sr = new StreamReader(fs, Encoding.Default))
                {
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line.StartsWith("[ti:"))
                        {
                            lrc.Title = SplitInfo(line);
                        }
                        else if (line.StartsWith("[ar:"))
                        {
                            lrc.Artist = SplitInfo(line);
                        }
                        else if (line.StartsWith("[al:"))
                        {
                            lrc.Album = SplitInfo(line);
                        }
                        else if (line.StartsWith("[by:"))
                        {
                            lrc.LrcBy = SplitInfo(line);
                        }
                        else if (line.StartsWith("[offset:"))
                        {
                            lrc.Offset = SplitInfo(line);
                        }
                        else
                        {
                            Regex regex = new Regex(@"\[([0-9.:]*)\]+(.*)", RegexOptions.Compiled);
                            MatchCollection mc = regex.Matches(line);
                            double time = TimeSpan.Parse("00:" + mc[0].Groups[1].Value).TotalSeconds;
                            string word = mc[0].Groups[2].Value;
                            lrc.LrcWord.Add(time, word);
                        }
                    }
                }
            } 
            return lrc;
        }

        /// <summary>
        /// 处理信息(私有方法)
        /// </summary>
        /// <param name="line"></param>
        /// <returns>返回基础信息</returns>
        static string SplitInfo(string line)
        {
            return line.Substring(line.IndexOf(":") + 1).TrimEnd(‘]‘);
        }
    }
       一行代码:Lrc lrc= Lrc.InitLrc("test.lrc");

  差不多就这样,最后还有一个菜单创建

public override bool OnCreateOptionsMenu(IMenu menu)
		{
			var m1 = menu.Add(0, 1, 0, "歌曲列表");
			var m2 = menu.Add (0,2,0,"退出");
			return base.OnCreateOptionsMenu(menu);
		}

		public override bool OnOptionsItemSelected(IMenuItem item)
		{
			switch (item.ItemId)
			{
			case 1:
				
				break;
			case 2:
				
				break;
			}
			return base.OnOptionsItemSelected(item);
		}

  好啦,差不多就是这些,至于音乐播放都是用Mediaplaye系统提供Api搞定

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。