如何使用android.net uri作为Xamarin android中MediaPlayer类的源?
我已经尝试使用GetItemAtId方法。但是,当我设置应该播放的音乐的数据源时,它返回一个错误如何使用android.net uri作为Xamarin android中MediaPlayer类的源?,android,xamarin,objectdatasource,Android,Xamarin,Objectdatasource,我已经尝试使用GetItemAtId方法。但是,当我设置应该播放的音乐的数据源时,它返回一个错误 void MediaListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e) { //var selectedFromList = mediaListView.GetItemIdAtPosition (e.Position); var selectedFromList = song
void MediaListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
//var selectedFromList = mediaListView.GetItemIdAtPosition (e.Position);
var selectedFromList = songList.GetItemId(position: e.Position);
string stringSong = selectedFromList.ToString ();
Android.Net.Uri musicUri = Android.Net.Uri.Parse (stringSong);
string path = musicUri.ToString();
//mediaPlayer = MediaPlayer.Create (this, musicUri);
//mediaPlayer.Start ();
//var chosenSong = ;
mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType (Stream.Music);
mediaPlayer.SetDataSource (path);
mediaPlayer.Prepare ();
mediaPlayer.Start ();
在代码示例中,我试图在单击列表视图中的某个元素时启动媒体播放器。当我运行此命令时,它会在以下行返回一个错误:
“mediaPlayer.SetDataSource(路径);”。变量路径是在列表视图中单击的元素的位置,该元素从long转换为字符串,然后转换为Uri,Uri再作为另一个变量转换为字符串。我知道这是无效的,但这是将long转换为字符串的唯一方法
错误消息显示“SetDataSource无效”。我有办法解决这个问题吗
编辑1:
歌曲列表的值可通过以下方式找到:
private List<Song> myMediaManager()
{
List<Song> songsList;
var uri = MediaStore.Audio.Media.ExternalContentUri;
string[] projection = {
MediaStore.Audio.Media.InterfaceConsts.Id,
MediaStore.Audio.Media.InterfaceConsts.AlbumId,
MediaStore.Audio.Media.InterfaceConsts.Title,
MediaStore.Audio.Media.InterfaceConsts.Artist,
};
var loader = new CursorLoader(this, uri, projection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();
songsList = new List<Song>();
if (cursor.MoveToFirst())
{
do
{
songsList.Add(new Song
(
cursor.GetLong(cursor.GetColumnIndex(projection[0])),
cursor.GetString(cursor.GetColumnIndex(projection[1])),
cursor.GetString(cursor.GetColumnIndex(projection[2])),
cursor.GetString(cursor.GetColumnIndex(projection[3]))
));
} while (cursor.MoveToNext());
}
return songsList;
}
}
编辑2
我忘了在这里展示与此相关的另一个类,它是:
public class MusicTabActivity : Activity
{
int count = 1;
public string chosenSong;
ListView mediaListView;
//List view for song list
IList<Song> theSongs;
//records of songs found sorted into an array
MediaListAdapter songList;
//song adapter
MediaPlayer mediaPlayer;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.musicTabMain);
//Variables for music items
mediaListView = FindViewById<ListView>(Resource.Id.mediaList);
mediaListView.ItemClick += MediaListView_ItemClick;
// Get our button from the layout resource,
// and attach an event to it
//Button button = FindViewById<Button> (Resource.Id.myButton);
Button mediaButton = FindViewById<Button>(Resource.Id.myMedia);
//button.Click += delegate {
// button.Text = string.Format ("{0} clicks!", count++);
//};
mediaButton.Click += delegate
{
//This will be the action that gets the list of music items
//Get the list of music items
theSongs = myMediaManager();
//Create the adapter
songList = new MediaListAdapter(this, theSongs);
mediaListView.Adapter = songList;
};
}
公共课堂音乐活动:活动
{
整数计数=1;
公共字符串Chosenson;
列表视图媒体列表视图;
//歌曲列表的列表视图
伊里斯特歌曲;
//按数组排序找到的歌曲记录
MediaListAdapter歌曲列表;
//歌曲适配器
媒体播放器;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
//从“主”布局资源设置视图
SetContentView(Resource.Layout.musicTabMain);
//音乐项目的变量
mediaListView=findviewbyd(Resource.Id.mediaList);
mediaListView.ItemClick+=mediaListView\u ItemClick;
//从布局资源中获取我们的按钮,
//并在其上附加一个事件
//Button Button=FindViewById(Resource.Id.myButton);
Button mediaButton=FindViewById(Resource.Id.myMedia);
//按钮。单击+=委派{
//button.Text=string.Format(“{0}点击!”,count++);
//};
mediaButton。单击+=委派
{
//这将是获取音乐项列表的操作
//获取音乐项目列表
歌曲=myMediaManager();
//创建适配器
歌曲列表=新的MediaListAdapter(这是歌曲);
mediaListView.Adapter=songList;
};
}
以及列表适配器的代码
public class MediaListAdapter : BaseAdapter<Song>
{
Activity context = null;
IList<Song> songs = new List<Song>();
public MediaListAdapter(Activity context, IList<Song> songs) : base ()
{
this.context = context;
this.songs = songs;
}
public override Song this[int position]
{
get { return songs[position]; }
}
public override int Count
{
get { return songs.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var song = songs[position];
var view = (convertView ??
context.LayoutInflater.Inflate(
Resource.Layout.SongDetail,
parent,
false)) as LinearLayout;
var txtName = view.FindViewById<TextView>(Resource.Id.NameText);
var txtArtistName = view.FindViewById<TextView>(Resource.Id.ArtistText);
txtName.SetText (song.getTitle(), TextView.BufferType.Normal);
txtArtistName.SetText(song.getArtist(), TextView.BufferType.Normal);
return view;
}
}
公共类MediaListAdapter:BaseAdapter
{
活动上下文=null;
IList歌曲=新列表();
公共MediaListAdapter(活动上下文,IList歌曲):基本()
{
this.context=上下文;
这个。歌曲=歌曲;
}
公共覆盖此[int位置]
{
获取{返回歌曲[位置];}
}
公共覆盖整数计数
{
获取{return songs.Count;}
}
公共覆盖长GetItemId(int位置)
{
返回位置;
}
公共覆盖视图GetView(int位置、视图转换视图、视图组父视图)
{
var song=歌曲[位置];
变量视图=(convertView??
context.layoutiner.flater.flate(
Resource.Layout.SongDetail,
父母亲
假)作为线性布局;
var txtName=view.findviewbyd(Resource.Id.NameText);
var txtArtistName=view.findviewbyd(Resource.Id.ArtistText);
txtName.SetText(song.getTitle(),TextView.BufferType.Normal);
txtaristname.SetText(song.getArtist(),TextView.BufferType.Normal);
返回视图;
}
}
}您只需将uri传递给MediaPlayer,如下所示:
mediaPlayer.setDataSource(context, musicUri);
请参阅Android文档。您的歌曲类不包含歌曲的URI,而ToString()方法将返回类的名称,而不是歌曲的URI 如果您花时间在调试器中逐步检查代码,那么情况显然就是这样。学习使用调试器是一项重要的技能,您应该花时间去做。这将使你成为一个更有效的程序员 我相信歌曲的URI只是附加到媒体URI的ID,因此您应该能够让URI执行以下操作(未测试): 然后可以将单击处理程序修改为
void MediaListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
var song = songList.GetItemId(position: e.Position);
mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType (Stream.Music);
mediaPlayer.SetDataSource (song.Uri);
mediaPlayer.Prepare ();
mediaPlayer.Start ();
}
我找到了解决方案,通过在Song类中使用get方法,我能够通过将其添加到click事件来传递歌曲的uri
void MediaListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
var song = songList[e.Position];
var songUri = song.Uri
mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType (Stream.Music);
mediaPlayer.SetDataSource (this, songUri);
mediaPlayer.Prepare ();
mediaPlayer.Start ();
}
转换过程中每个阶段的具体值是什么?听起来你没有得到一个有效的URI,这可能是因为你使用了错误的数据,或者转换过程中的某个步骤出现了问题。最初,列表视图中单击的位置的值(这是一个传递整数的长值)转换为字符串,然后转换为Uri。我要求的是精确的值,而不是关于其类型的模糊注释。你确定你正在处理的值是有效的Android媒体URI吗?你怎么能不知道你自己数据的值?歌曲列表是在没有任何代码的情况下神奇地创建的吗?还是您创建了它并用数据填充了它?使用调试器或一些控制台.Writeline语句来确定值是什么。哦,好的,我不确定你的意思,但现在我已经编辑了这个问题。我已经为songList返回的值编写了代码。我尝试将musicUri传递到MediaPlayer中,但它在此时返回一个异常“MediaPlayer.setDataSource(context,musicUri);”。除Uri.WithAppendedPath(Uri.WithAppendedPath(MediaStore.Audio.Media.ExternalContentUri,id.ToString())外,大多数都能正常工作;节显示编译器错误“MediaBrowserService\MediaBrowserService\Song.cs(33,33):错误CS0176:无法使用实例引用访问成员“Android.Net.Uri.WithAppendedPath(Android.Net.Uri,string)”;请改为使用类型名(CS0176)(MotorVator)对其进行限定我已将其更改为您编辑的内容,但我无法使用mediaPlayer.SetDataSource(sing.Uri)
void MediaListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
var song = songList.GetItemId(position: e.Position);
mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType (Stream.Music);
mediaPlayer.SetDataSource (song.Uri);
mediaPlayer.Prepare ();
mediaPlayer.Start ();
}
void MediaListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
var song = songList[e.Position];
var songUri = song.Uri
mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType (Stream.Music);
mediaPlayer.SetDataSource (this, songUri);
mediaPlayer.Prepare ();
mediaPlayer.Start ();
}