Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用android.net uri作为Xamarin android中MediaPlayer类的源?_Android_Xamarin_Objectdatasource - Fatal编程技术网

如何使用android.net uri作为Xamarin android中MediaPlayer类的源?

如何使用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

我已经尝试使用GetItemAtId方法。但是,当我设置应该播放的音乐的数据源时,它返回一个错误

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 ();
}