0910Android音乐播放器
来源:互联网 发布:怎么编程游戏我的世界 编辑:程序博客网 时间:2024/05/21 10:35
原理
实现功能
- 点击音乐列表中的音乐播放
- 暂停播放开始播放(包括暂停以后拖动进度条到其他位置再播放)
- 拖动音乐进度条,音乐从拖动结束位置播放
- 上一首下一首音乐
流程图
原理
利用了mediaplayer,广播,服务,listView完成了整体任务。
在主函数中获得音乐地址,通过listView中的item点击事件打开服务,将音乐路径和名称传到服务中。然后在服务中打开音乐,将音乐的播放时间和音乐名称通过广播传到主线程中,开启服务中的线程将音乐的实时时间(耗时操作)传到主线程中。
在主线程中注册广播,新建广播接收器的实例。广播接收器通过发送广播时type类型来区别音乐的播放时间和音乐的实时时间,并依此设置textview和seekbar。
跳转功能通过在服务中MediaPlayer的seekTo来实现。
暂停播放设置点击事件,通过一个flag,使暂停和播放通过点击交替执行。设置点击具体功能也是在服务中进行,点一下MediaPlayer暂停pause(),再点一下start()。
音乐的上一首下一首,在主线程中控制,在服务中执行打开音乐的代码块。主线程中通过定义一个全局变量将listView中的position获取。在设置上下首音乐的点击事件中打开播放音乐的服务,并且通过position来设置播放音乐。
功能具体实现
主线程中注册广播,建立广播接收器实例。获得音乐,打开音乐适配器。
获得音乐
// 获得所有的歌曲 final File music = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); musics = music.listFiles();
打开音乐适配器
// 添加到listView中 final LayoutInflater inflater = getLayoutInflater(); MusicAdapter musicAdapter = new MusicAdapter(inflater, musics); mListView.setAdapter(musicAdapter);
音乐适配器中获取歌曲的名字,作者,图片
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh=null; if(convertView==null){ vh=new ViewHolder(); convertView=mInflater.inflate(R.layout.listview_item,null); vh.musicName = (TextView) convertView.findViewById(R.id.textview_music_name); vh.musicAuther = (TextView) convertView.findViewById(R.id.tv_music_auther); vh.img= (ImageView) convertView.findViewById(R.id.img); convertView.setTag(vh); } vh= (ViewHolder) convertView.getTag();// 设置音乐名称 vh.musicName.setText(musics[position].getName());// 获取作家 MediaMetadataRetriever mmr=new MediaMetadataRetriever(); mmr.setDataSource(musics[position].getAbsolutePath()); String auther=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);// 判断作者是否为空 if(auther!=null){ vh.musicAuther.setText(auther); }else { vh.musicAuther.setText("<未知>"); }// 获得图片 byte[] image=mmr.getEmbeddedPicture(); if(image!=null){ Bitmap bitmap= BitmapFactory.decodeByteArray(image,0,image.length); vh.img.setImageBitmap(bitmap); }else{ vh.img.setImageResource(R.mipmap.ic_launcher); } return convertView; } class ViewHolder{ TextView musicName; TextView musicAuther; ImageView img; }
动态注册广播
// 注册广播 myBroad = new MyBroadCastService(); IntentFilter filter = new IntentFilter(); filter.addAction(MUSIC_TIME); registerReceiver(myBroad, filter);
注销广播
// 动态注册注销广播 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(myBroad); }
新建广播实例
// 在活动中接受广播以便设置UI参数 class MyBroadCastService extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int type = intent.getIntExtra("type", 0); switch (type) { case 0: int time = intent.getIntExtra("time", 0); mSeekBar.setMax(time); Date date1=new Date(time); SimpleDateFormat format1=new SimpleDateFormat("mm:ss"); String s1=format1.format(date1); mTextViewAllTime.setText(s1); break; case 1: int time1 = intent.getIntExtra("time", 0); mSeekBar.setProgress(time1); Date date=new Date(time1); SimpleDateFormat format=new SimpleDateFormat("mm:ss"); String s=format.format(date); mTextViewCurrentTime.setText(s); break; } } }
打开音乐
主线程中设置点击事件
// 打开服务,在服务中打开音乐 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getApplicationContext(), MyService.class);// 将点击位置的音乐路径传到服务中 intent.putExtra("musicPath", musics[position].getAbsolutePath()); intent.putExtra("musicName", musics[position].getName()); intent.putExtra("type",Config.MUSIC_CLICK_START); startService(intent);// 用于设置下一首上一首音乐 mPosition =position; } });
服务中实现打开音乐
private void startMusic(Intent intent) { String musicPath = intent.getStringExtra("musicPath"); musicName= intent.getStringExtra("musicName");// 防止多个歌曲重复 if (mediaPlayer == null) { mediaPlayer = new MediaPlayer(); } mediaPlayer.reset(); try { mediaPlayer.setDataSource(musicPath); mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); int allTime = mediaPlayer.getDuration();// 发送广播将时间参数送过去 Intent intent1 = new Intent(MainActivity.MUSIC_TIME); intent1.putExtra("type", 0); intent1.putExtra("time", allTime); intent1.putExtra("name",musicName); sendBroadcast(intent1);// 服务中不能进行耗时操作,启动一个线程来传递音乐进度条(耗时操作) MySeekBar seekBar = new MySeekBar(); seekBar.start(); } }); } catch (IOException e) { e.printStackTrace(); } }
服务其中打开的线程
class MySeekBar extends Thread { @Override public void run() {// super.run(); while (mediaPlayer.isPlaying()) { int now = mediaPlayer.getCurrentPosition(); Intent intent1 = new Intent(MainActivity.MUSIC_TIME); intent1.putExtra("type", 1); intent1.putExtra("time", now); sendBroadcast(intent1); try {// 休眠一秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
实现音乐随进度条播放
主线程中设置点击事件
// 设置音乐随着seekbar的跳转 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { Intent intent=new Intent(getApplicationContext(),MyService.class); intent.putExtra("type", Config.MUSIC_SEEK); intent.putExtra("progress",seekBar.getProgress()); startService(intent); } });
服务中实现音乐随进度条播放
private void seekToProgress(Intent intent) { int progress = intent.getIntExtra("progress", 0);// 歌曲跳转到progress的位置后保持原来状态 mediaPlayer.seekTo(progress); }
实现音乐暂停
主线程中设置点击事件
mBtnPauseMusic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Intent intent=new Intent(getApplicationContext(),MyService.class); intent.putExtra("flag", flag); intent.putExtra("type", Config.MUSIC_BUTTON_PAUSE); startService(intent); flag=!flag; } });
服务中实现音乐暂停
private void pauseMusic(Intent intent) { boolean flag = intent.getBooleanExtra("flag", true); if (!flag) {// 此时线程关闭了 mediaPlayer.pause(); } else {// 跳转到暂停后滑动到的位置 int keepOn = mediaPlayer.getCurrentPosition(); mediaPlayer.seekTo(keepOn); mediaPlayer.start();// 再次打开线程 MySeekBar seekBar = new MySeekBar(); seekBar.start(); } }
实现下一首音乐
主线程中设置点击事件
// 设置下一首音乐 mBtnNextMusic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// 不是最后一首音乐时mPosition才+1 if(mPosition!=musics.length-1){ mPosition++; } Intent intent = new Intent(getApplicationContext(), MyService.class);// 将点击位置的音乐路径传到服务中 intent.putExtra("musicPath", musics[mPosition].getAbsolutePath()); intent.putExtra("musicName", musics[mPosition].getName()); intent.putExtra("type", Config.MUSIC_NEXT); startService(intent); } });
服务中实现下一首音乐
在服务中调用打开音乐方法startMusic(intent)
实现上一首音乐
主线程中设置点击事件
// 设置上一首音乐 mBtnBeforeMusic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// 不是第一首音乐时mPosition才-1 if(mPosition!=0){ mPosition--; } Intent intent = new Intent(getApplicationContext(), MyService.class);// 将点击位置的音乐路径传到服务中 intent.putExtra("musicPath", musics[mPosition].getAbsolutePath()); intent.putExtra("musicName", musics[mPosition].getName()); intent.putExtra("type", Config.MUSIC_PREVIOUS); startService(intent); } });
服务中实现上一首音乐
在服务中调用打开音乐方法startMusic(intent)
全部代码
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="0dp" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:cacheColorHint="#00000000" android:background="#ffffff" android:divider="@null" android:layout_weight="1"></ListView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/background" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> <TextView android:id="@+id/textview_current_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="00:00" /> <TextView android:id="@+id/textview_all_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_margin="5dp" android:text="00:00" /> </RelativeLayout> <SeekBar android:id="@+id/seekbar" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:gravity="center"> <CheckBox android:id="@+id/btn_brfore_music" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/previous_music" android:button="@null" /> <CheckBox android:id="@+id/btn_pause_music" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="30dp" android:layout_marginRight="30dp" android:background="@drawable/start_pause_press" android:button="@null" /> <CheckBox android:id="@+id/btn_next_music" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/next_music" android:button="@null" /> </LinearLayout> </LinearLayout></LinearLayout>
ListViewitem布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent"android:gravity="center_vertical" android:layout_height="match_parent"> <ImageView android:id="@+id/img" android:layout_width="70dp" android:layout_height="70dp" android:layout_margin="10dp" android:src="@mipmap/ic_launcher"/><TextView android:id="@+id/textview_music_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="音乐名称"/> <TextView android:id="@+id/tv_music_auther" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="作家" android:layout_margin="10dp" /></LinearLayout>
主线程
package com.example.laowang.mymediaplayer;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Environment;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.Window;import android.widget.AdapterView;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.ListView;import android.widget.SeekBar;import android.widget.TextView;import com.example.laowang.mymediaplayer.adapter.Config;import com.example.laowang.mymediaplayer.adapter.MusicAdapter;import java.io.File;import java.text.SimpleDateFormat;import java.util.Date;public class MainActivity extends Activity{ private CheckBox mBtnBeforeMusic; private CheckBox mBtnPauseMusic; private CheckBox mBtnNextMusic; private SeekBar mSeekBar; private ListView mListView; private TextView mTextViewAllTime; private TextView mTextViewCurrentTime; private TextView mTextViewMusicName; private MyBroadCastService myBroad; private int mPosition; private File[] musics; private boolean flag; public static final String MUSIC_TIME = "com.laowang.music"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); mBtnBeforeMusic = (CheckBox) findViewById(R.id.btn_brfore_music); mBtnNextMusic = (CheckBox) findViewById(R.id.btn_next_music); mBtnPauseMusic = (CheckBox) findViewById(R.id.btn_pause_music); mSeekBar = (SeekBar) findViewById(R.id.seekbar); mListView = (ListView) findViewById(R.id.listview); mTextViewAllTime = (TextView) findViewById(R.id.textview_all_time); mTextViewCurrentTime = (TextView) findViewById(R.id.textview_current_time); mTextViewMusicName = (TextView) findViewById(R.id.textview_music_name);// 获得所有的歌曲 final File music = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); musics = music.listFiles(); for (File item:musics){ Log.d("歌曲的位置", "→"+item); }// 添加到listView中 final LayoutInflater inflater = getLayoutInflater(); MusicAdapter musicAdapter = new MusicAdapter(inflater, musics); mListView.setAdapter(musicAdapter);// 注册广播 myBroad = new MyBroadCastService(); IntentFilter filter = new IntentFilter(); filter.addAction(MUSIC_TIME); registerReceiver(myBroad, filter);// 设置下一首音乐 mBtnNextMusic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// 不是最后一首音乐时mPosition才+1 if(mPosition!=musics.length-1){ mPosition++; } Intent intent = new Intent(getApplicationContext(), MyService.class);// 将点击位置的音乐路径传到服务中 intent.putExtra("musicPath", musics[mPosition].getAbsolutePath()); intent.putExtra("musicName", musics[mPosition].getName()); intent.putExtra("type", Config.MUSIC_NEXT); startService(intent); } });// 设置上一首音乐 mBtnBeforeMusic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// 不是第一首音乐时mPosition才-1 if(mPosition!=0){ mPosition--; } Intent intent = new Intent(getApplicationContext(), MyService.class);// 将点击位置的音乐路径传到服务中 intent.putExtra("musicPath", musics[mPosition].getAbsolutePath()); intent.putExtra("musicName", musics[mPosition].getName()); intent.putExtra("type", Config.MUSIC_PREVIOUS); startService(intent); } });// 设置音乐暂停开始 mBtnPauseMusic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Intent intent=new Intent(getApplicationContext(),MyService.class); intent.putExtra("flag", flag); intent.putExtra("type", Config.MUSIC_BUTTON_PAUSE); startService(intent); flag=!flag; } });// 打开服务,在服务中打开音乐 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(getApplicationContext(), MyService.class);// 将点击位置的音乐路径传到服务中 intent.putExtra("musicPath", musics[position].getAbsolutePath()); intent.putExtra("musicName", musics[position].getName()); intent.putExtra("type",Config.MUSIC_CLICK_START); startService(intent);// 用于设置下一首上一首音乐 mPosition =position; } });// 设置音乐随着seekbar的跳转 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { Intent intent=new Intent(getApplicationContext(),MyService.class); intent.putExtra("type", Config.MUSIC_SEEK); intent.putExtra("progress",seekBar.getProgress()); startService(intent); } }); }// 动态注册注销广播 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(myBroad); } // 在活动中接受广播以便设置UI参数 class MyBroadCastService extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int type = intent.getIntExtra("type", 0); switch (type) { case 0: int time = intent.getIntExtra("time", 0); mSeekBar.setMax(time); Date date1=new Date(time); SimpleDateFormat format1=new SimpleDateFormat("mm:ss"); String s1=format1.format(date1); mTextViewAllTime.setText(s1); String name=intent.getStringExtra("name"); mTextViewMusicName.setText(name); break; case 1: int time1 = intent.getIntExtra("time", 0); mSeekBar.setProgress(time1); Date date=new Date(time1); SimpleDateFormat format=new SimpleDateFormat("mm:ss"); String s=format.format(date); mTextViewCurrentTime.setText(s); break; } } }}
适配器
package com.example.laowang.mymediaplayer.adapter;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.media.MediaMetadataRetriever;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import com.example.laowang.mymediaplayer.R;import java.io.File;/** * Created by Administrator on 2015/9/10. */public class MusicAdapter extends BaseAdapter { private LayoutInflater mInflater; private File[] musics; public MusicAdapter(LayoutInflater mInflater, File[] musics) { this.mInflater = mInflater; this.musics = musics; } @Override public int getCount() { return musics.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh=null; if(convertView==null){ vh=new ViewHolder(); convertView=mInflater.inflate(R.layout.listview_item,null); vh.musicName = (TextView) convertView.findViewById(R.id.textview_music_name); vh.musicAuther = (TextView) convertView.findViewById(R.id.tv_music_auther); vh.img= (ImageView) convertView.findViewById(R.id.img); convertView.setTag(vh); } vh= (ViewHolder) convertView.getTag();// 设置音乐名称 vh.musicName.setText(musics[position].getName());// 获取作家 MediaMetadataRetriever mmr=new MediaMetadataRetriever(); mmr.setDataSource(musics[position].getAbsolutePath()); String auther=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);// 判断作者是否为空 if(auther!=null){ vh.musicAuther.setText(auther); }else { vh.musicAuther.setText("<未知>"); }// 获得图片 byte[] image=mmr.getEmbeddedPicture(); if(image!=null){ Bitmap bitmap= BitmapFactory.decodeByteArray(image,0,image.length); vh.img.setImageBitmap(bitmap); }else{ vh.img.setImageResource(R.mipmap.ic_launcher); } return convertView; } class ViewHolder{ TextView musicName; TextView musicAuther; ImageView img; }}
服务
package com.example.laowang.mymediaplayer;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.os.IBinder;import android.support.annotation.Nullable;import com.example.laowang.mymediaplayer.adapter.Config;import java.io.IOException;/** * Created by Administrator on 2015/9/10. */public class MyService extends Service { private MediaPlayer mediaPlayer; private boolean flag; private String musicName; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(final Intent intent, int flags, int startId) { int type = intent.getIntExtra("type", Config.MUSIC_CLICK_START); switch (type) { case Config.MUSIC_CLICK_START: startMusic(intent); break; case Config.MUSIC_SEEK: seekToProgress(intent); break; case Config.MUSIC_BUTTON_PAUSE: pauseMusic(intent); break; case Config.MUSIC_NEXT: startMusic(intent); break; case Config.MUSIC_PREVIOUS: startMusic(intent); break; default: break; } return super.onStartCommand(intent, flags, startId); } private void seekToProgress(Intent intent) { int progress = intent.getIntExtra("progress", 0);// 歌曲跳转到progress的位置后保持原来状态 mediaPlayer.seekTo(progress); } private void pauseMusic(Intent intent) { boolean flag = intent.getBooleanExtra("flag", true); if (!flag) {// 此时线程关闭了 mediaPlayer.pause(); } else {// 跳转到暂停后滑动到的位置 int keepOn = mediaPlayer.getCurrentPosition(); mediaPlayer.seekTo(keepOn); mediaPlayer.start();// 再次打开线程 MySeekBar seekBar = new MySeekBar(); seekBar.start(); } } private void startMusic(Intent intent) { String musicPath = intent.getStringExtra("musicPath"); musicName= intent.getStringExtra("musicName");// 防止多个歌曲重复 if (mediaPlayer == null) { mediaPlayer = new MediaPlayer(); } mediaPlayer.reset(); try { mediaPlayer.setDataSource(musicPath); mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); int allTime = mediaPlayer.getDuration();// 发送广播将时间参数送过去 Intent intent1 = new Intent(MainActivity.MUSIC_TIME); intent1.putExtra("type", 0); intent1.putExtra("time", allTime); intent1.putExtra("name",musicName); sendBroadcast(intent1);// 服务中不能进行耗时操作,启动一个线程来传递音乐进度条(耗时操作) MySeekBar seekBar = new MySeekBar(); seekBar.start(); } }); } catch (IOException e) { e.printStackTrace(); } } class MySeekBar extends Thread { @Override public void run() {// super.run(); while (mediaPlayer.isPlaying()) { int now = mediaPlayer.getCurrentPosition(); Intent intent1 = new Intent(MainActivity.MUSIC_TIME); intent1.putExtra("type", 1); intent1.putExtra("time", now); sendBroadcast(intent1); try {// 休眠一秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
存放静态常量的类
package com.example.laowang.mymediaplayer.adapter;/** * Created by Administrator on 2015/9/10. */public class Config { public static final int MUSIC_CLICK_START =1; public static final int MUSIC_SEEK=0; public static final int MUSIC_BUTTON_PAUSE =2; public static final int MUSIC_BUTTON_START=3; public static final int MUSIC_NEXT=5; public static final int MUSIC_PREVIOUS =4;}
AndroidMainFest
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.laowang.mymediaplayer" ><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService"/> </application></manifest>
2 0
- 0910Android音乐播放器
- android音乐播放器播放音乐卡
- Android 音乐播放 类似音乐播放器
- android 音乐播放器
- Android 音乐播放器
- android 音乐播放器
- Android音乐播放器
- Android--音乐播放器
- Android音乐播放器
- android 音乐播放器
- Android音乐播放器
- Android 音乐播放器
- Android音乐播放器
- Android音乐播放器
- Android:音乐播放器
- Android 音乐播放器。
- android 音乐播放器
- Android--音乐播放器
- 面积最大的全1子矩阵(腾讯2012年暑期实习生招聘面试二面试题)
- OpenGL ES 20 用2D纹理伪造3D效果 Demo
- COCI CONTEST #3 29.11.2014 考后总结
- lcx.exe 转发
- 软件架构师推荐书籍
- 0910Android音乐播放器
- 【C++面向对象学习笔记】-构造函数和析构函数
- MEMS惯性传感器
- System中的一些属性(Properties属性)如何获取系统属性和指定系统属性
- 简单的学生信息链表
- ngrok 内网穿透利器
- java设计模式第5弹--责任链模式
- C语言学习之结构体struct
- android开发步步为营之76:android导出anr日志