android_day10

1.计算机表示图形的几种方式
    bmp:以高质量保存  用于计算机
    jpg:以良好的质量保存  用于计算机或者网络
    png:以高质量保存
    图片大小的计算公式:图片的总像素*每个像素大小

    单色:每个像素最多可以表示2种颜色,要么是黑要么是白,那么只需要使用长度为1的二进制位来表示,那么一个像素占1/8个byte
    16色:每个像素最多可以表示16种颜色 0000-1111,那么只需要使用长度为4的二进制位来表示,那么一个像素占1/2个byte
    256色:每个像素最多可以表示256种颜色 0000 0000-1111 1111 ,那么只需要使用长度为8的二进制位来表示,那么一个像素占1个byte
    24位:每个像素最多可以表示1600万种颜色 那么一个像素占3byte
        r 1  byte
        g 1  byte
        b 1  byte
    
    android中采用的是png格式, android中采用ARGB android中一个像素占4byte

2.缩放加载大图片 
    异常:图片太大 OutOfMemeryError 
    1)获取图片的分辨率  2400*3200
    2)获取手机的分辨率 320*480
    3)计算缩放比
      宽 7  宽正好
      高 6倍
    4)按照大的进行缩放
    
    实现步骤:
    [1]activity.main.xml:
        <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:orientation="vertical"
            tools:context=".MainActivity" >

           <Button 
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:onClick="click"
               android:text="load"/>
           
           <ImageView 
               android:id="@+id/iv"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               />
            

        </LinearLayout>
    [2]MainActivity:
        private int height;
        private int width;
        private ImageView iv;

        @SuppressWarnings("deprecation")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //用来显示小狗的图片
            iv = (ImageView) findViewById(R.id.iv);
            //[1]获取手机的分辨率  WindowManager
            WindowManager wm=(WindowManager) getSystemService(WINDOW_SERVICE);
            height = wm.getDefaultDisplay().getHeight();
            width = wm.getDefaultDisplay().getWidth();
            System.out.println("width:"+width+"---"+height);
            
        }
        
        //点击按钮  加载一张大图片
        public void click(View v){
            //创建一个位图工厂的配置参数
            BitmapFactory.Options options=new Options();
            //解码器不去真正的解析位图  但是还能获取图片的宽和高信息
            options.inJustDecodeBounds=true;
            BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg", options);
            //[2]获取图片的宽和高信息
            int imgWidth=options.outWidth;
            int imgHeight=options.outHeight;
            System.out.println("图片的宽和高:"+imgWidth+"---"+imgHeight);
            //[3]计算缩放比
            int scale=1;
            int scaleX=imgWidth/width;
            int scaleY=imgHeight/height;
            if(scaleX>=scaleY&&scaleX>scale){
                scale=scaleX;
            }
            if(scaleY>scaleX&&scaleY>scale){
                scale=scaleY;
            }
            
            System.out.println("缩放比:"+scale);
            //[4]按照缩放比进行显示
            options.inSampleSize=scale;
            //[5]按照缩放比  进行解析位图
            options.inJustDecodeBounds=false;
            Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/dog.jpg",options);
            //[6]把bitmap显示到iv上
            iv.setImageBitmap(bitmap);
        }
    
    

3.创建原图的副本
    原图不能修改,副本可以
    [1]activity_main.xml:
        <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:orientation="vertical"
            tools:context=".MainActivity" >

           <ImageView 
               android:id="@+id/iv_src"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"/>
           
           <ImageView 
               android:id="@+id/iv_copy"
               android:layout_width="wrap_content"
               android:layout_marginTop="20dp"
               android:layout_height="wrap_content"
               />

        </LinearLayout>
    [2]MainActivity:
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //显示原图
            ImageView iv_src=(ImageView) findViewById(R.id.iv_src);
            
            //显示副本
            ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
            
            //[1]先把tomcat.png图片转换成bitmap  显示到iv_src
            Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
            
            //[1.1]操作图片
            //srcBitmap.setPixel(20, 30, Color.RED);
            iv_src.setImageBitmap(srcBitmap);
            
            //[2]创建原图的副本
            //[2.1]创建一个模板  相当于  创建一个大小和原图一样的  空白的白纸
            Bitmap copyBitmap=Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
            //[2.2]想作画需要一个画笔
            Paint paint=new Paint();
            //[2.3]创建一个画布  把白纸铺到画布上
            Canvas canvas=new Canvas(copyBitmap);
            //[2.4]开始作画
            canvas.drawBitmap(srcBitmap, new Matrix(), paint);
            
            //[2.5]操作画出来的小猫图片
            for (int i = 0; i < 20; i++) {
                copyBitmap.setPixel(20+i, 30, Color.RED);
            }
            
            //[3]把copybitmap显示到iv_copy上
            iv_copy.setImageBitmap(copyBitmap);

       }
    

4.图形处理的api
    旋转:matrix.setRotate(20, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);
    缩放:matrix.setScale(0.5f, 0.5f);
    平移:
        matrix.setTranslate(30, 0);
    镜面:就是使用缩放和平移的一个组合
        matrix.setScale(-1f, 1);
        //post是在上一次修改的基础上进行再次修改  set 每次操作都是最新的   会覆盖上次的操作
        matrix.postTranslate(srcBitmap.getWidth(), 0);
    倒影:
        matrix.setScale(1.0f, -1);
        //post是在上一次修改的基础上进行再次修改  set 每次操作都是最新的  会覆盖上次的操作
        matrix.postTranslate(0, srcBitmap.getHeight());
        
    
    [1]activity_main.xml:
        <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:orientation="vertical"
            tools:context=".MainActivity" >

          
            <ImageView 
                android:id="@+id/iv_src"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            
            <ImageView 
                android:id="@+id/iv_copy"
                android:layout_width="wrap_content"
                android:layout_marginTop="20dp"
                android:layout_height="wrap_content"/>
            
        </LinearLayout>
    [2]MainActivity:
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //显示原图
            ImageView iv_src=(ImageView) findViewById(R.id.iv_src);
            
            //显示副本
            ImageView iv_copy=(ImageView) findViewById(R.id.iv_copy);
            
            //[1]先把tomcat.png图片转换成bitmap  显示到iv_src
            Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
            
            //[1.1]操作图片
            //srcBitmap.setPixel(20, 30, Color.RED);
            iv_src.setImageBitmap(srcBitmap);
            
            //[2]创建原图的副本
            
            //[2.1]创建一个模板  相当于  创建了一个大小和原图一样的  空白的白纸
            Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
            //[2.2]想作画需要一个画笔
            Paint paint=new Paint();
            //[2.3]创建一个画布  把白纸铺到画布上
            Canvas canvas=new Canvas(copyBitmap);
            //[2.4]开始作画
            Matrix matrix=new Matrix();
            
            //[2.5]对图片进行旋转
            //matrix.setRotate(20, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);
            
            //[2.5]对图片进行缩放
            //matrix.setScale(0.5f, 0.5f);
            
            //[2.6]对图片进行平移
            //matrix.setTranslate(30, 0);
            
            //[2.7]镜像效果  如果2个方法一起用
            matrix.setScale(-1f, 1);
            //post是在上一次修改的基础上进行再次修改  set 每次操作都是最新的   会覆盖上次的操作
            matrix.postTranslate(srcBitmap.getWidth(), 0);
            
            
            //[2.8]倒影效果
            //matrix.setScale(1.0f, -1);
            //post是在上一次修改的基础上进行再次修改  set 每次操作都是最新的  会覆盖上次的操作
            //matrix.postTranslate(0, srcBitmap.getHeight());
            
            canvas.drawBitmap(srcBitmap, matrix, paint);
            
            //[3]把copybitmap显示到iv_copy上
            iv_copy.setImageBitmap(copyBitmap);

        }
    
5.画画板小案例
    [1]activity_main.xml:
        <RelativeLayout 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"
            tools:context=".MainActivity" >

            <ImageView 
                android:id="@+id/iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            
            <LinearLayout 
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/iv"
                android:orientation="horizontal">
                
                <Button android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="click1"
                    android:text="红色"/>
                
                <Button 
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="click2"
                    android:text="加粗"
                    />
                
                <Button 
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="click3"
                    android:text="保存"/>
                
            </LinearLayout>

        </RelativeLayout>
    [2]MainActivity:
        private ImageView iv;
        private Bitmap srcBitmap;
        private Bitmap copyBitmap;
        private Paint paint;
        private Canvas canvas;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //用来显示我们画的内容
            iv = (ImageView) findViewById(R.id.iv);
            
            //[1]获取原图 bg
            srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
            
            //[2]获取原图的副本  相当于是一个空白  的白纸
            copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
            
            //创建画笔
            paint = new Paint();
            
            //创建一个画布
            canvas = new Canvas(copyBitmap);
            
            //开始作画
            canvas.drawBitmap(srcBitmap, new Matrix(), paint);
            //convas.drawLine(20, 30, 50, 80, paint);
            iv.setImageBitmap(copyBitmap);
            
            //[3]给iv设置一个触摸事件
            iv.setOnTouchListener(new OnTouchListener() {
                int startX=0;
                int startY=0;
                
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    //获取当前事件类型
                    int action=event.getAction();
                    switch (action) {
                    case MotionEvent.ACTION_DOWN://按下
                        System.out.println("摸view");
                        //获取开始位置(划线)
                        
                        startX=(int) event.getX();
                        startY=(int) event.getY();
                        
                        break;
                    case MotionEvent.ACTION_MOVE://移动
                        System.out.println("移动");
                        //获取结束位置
                        int stopX=(int) event.getX();
                        int stopY=(int) event.getY();
                        //[不停的画线]
                        canvas.drawLine(startX, startY, stopX, stopY, paint);
                        //再次显示到iv上
                        iv.setImageBitmap(copyBitmap);
                        
                        //更新一下开始坐标和结束坐标
                        startX=stopX;
                        startY=stopY;
                        
                        break;
                    case MotionEvent.ACTION_UP://抬起
                        System.out.println("抬起");
                        break;

                    default:
                        break;
                    }
                    
                    // True if the listener has consumed the event, false otherwise
                    return true;//true 监听器处理完事件了
                }
            });
            
            

        }
        
        //点击按钮 改变画笔的颜色
        public void click1(View v){
            paint.setColor(Color.RED);
        }
        
        //点击按钮  对画笔加粗
        public void click2(View v){
            paint.setStrokeWidth(15);
        }
        
        //点击按钮 对图片进行保存
        public void click3(View v){
            try {
                /**
                 * SystemClock.uptimeMillis() 这个是当前手机的开机后的时间   开机了过了多久
                 */
                File file = new File(Environment.getExternalStorageDirectory().getPath(),SystemClock.uptimeMillis()+".png");
                FileOutputStream fos=new FileOutputStream(file);
                /**
                 * CompressFormat format 保存图片的格式
                 * int quality 保存图片的质量
                 */
                copyBitmap.compress(CompressFormat.PNG, 100, fos);
                
                //发送一条广播 欺骗系统图库的应用
                Intent intent=new Intent();
                //设置action
                intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
                intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
                //发送一条广播
                sendBroadcast(intent);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
        
        
6.撕衣服小案例
    原理:2张图片,一张是有衣服,一张没衣服,有衣服的触摸变透明即可(2.3不行,撕的透明是黑色,真机可以)
    [1]activity_main.xml:
        <RelativeLayout 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"
            tools:context=".MainActivity" >
               
            <ImageView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/after19"
                />
            <ImageView 
                android:id="@+id/iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />

        </RelativeLayout>
    [2]MainActivity:
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //用来显示 操作后的图片
            final ImageView iv = (ImageView) findViewById(R.id.iv);
            
            //[1]获取要操作图片 原图
            Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19);
            
            //[2]创建一个副本   相当于有一个和原图大小的白纸
            final Bitmap alterBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
            //创建画笔
            Paint paint = new Paint();
            //创建画布   把白纸铺到画布上
            Canvas canvas = new Canvas(alterBitmap);
            //开始作画 
            canvas.drawBitmap(srcBitmap, new Matrix(), paint);
            
            iv.setImageBitmap(alterBitmap);
            
            //[3]给vi设置一个触摸事件 
            iv.setOnTouchListener(new OnTouchListener() {
                
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    //[4]具体判断一下触摸事件 
                    switch (event.getAction()) {
                    
                    case MotionEvent.ACTION_MOVE://移动事件
                        
                        for (int i = -7; i < 7; i++) { //增加X轴坐标
                            
                            for (int j = -7; j < 7; j++) { //增加Y轴坐标
                                                      
                                
                                //为了良好的用户体验  撕一个圆 
                                if (Math.sqrt(i*i+j*j)<7) {
                                    
                                    try {
                                        alterBitmap.setPixel((int)event.getX()+i, (int)event.getY()+j, Color.TRANSPARENT);
                                    } catch (Exception e) {
                                    }
                                }
                                
                            }
                        }
                        
                        //更新一下iv
                        iv.setImageBitmap(alterBitmap);
                        break;

                    }
                    
                    return true;
                }
            });
        }
    


7.使用mediaplayer播放音频文件
    这个类用于播放音频或者视频
    [1]activity_main.xml:
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click"
            android:text="播放"
            />
    [2]MainActivity:
        //点击按钮  播放一个音频文件
        public void click(View v){
            //[1]初始化mediaplayer
            MediaPlayer mediaPlayer=new MediaPlayer();
            //[2]设置要播放的资源位置  path 可以是网络路径  也可是本地路径
            try {
                mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3");
                //[3]准备播放
                mediaPlayer.prepare();
                //[4]开始播放
                mediaPlayer.start();
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
    
    
8.百度音乐盒完成
    [1]清单文件application加:
        <service android:name="com.itheima.baidumusic.MusicService"></service>
    [2]activity_main.xml:
        <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:orientation="vertical"
            tools:context=".MainActivity" >

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click1"
                android:text="播放" />

            
             <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click2"
                android:text="暂停" />
             
              <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click3"
                android:text="继续播放" />

              <SeekBar
                  android:id="@+id/seekBar1"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content" />
            
        </LinearLayout>
    [3]Iservice:
        public interface Iservice {

            //把想暴露的方法都定义在接口中
            public void callPlayMusic();
            public void callPauseMusic();
            public void callRePlayMusic();
            public void callSeekTo(int position);
            
        }
    [4]MusicService:
        public class MusicService extends Service{

            private MediaPlayer mediaPlayer;
            
            //[2]把我们定义的中间人对象返回
            @Override
            public IBinder onBind(Intent intent) {
                return new MyBinder();
            }
            
            //服务一开启  就执行这个方法
            @Override
            public void onCreate() {
                //1.初始化mediaplayer
                mediaPlayer=new MediaPlayer();
                super.onCreate();
            }
            
            @Override
            public void onDestroy() {
                super.onDestroy();
            }
            
            //实现指定播放的位置
            public void seekTo(int position){
                mediaPlayer.seekTo(position);
            }
            
            //播放音乐的方法
            public void playMusic(){
                try {
                    //2.设置要播放的资源位置  path可以是网络路径  也可以是本地路径
                    mediaPlayer.reset();
                    mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3");
                    //3.准备播放
                    mediaPlayer.prepare();
                    //4.开始播放
                    mediaPlayer.start();
                    
                    //5.更新进度条
                    updateSeekBar();
                    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            
            //更新进度条的方法
            private void updateSeekBar(){
                //[1]获取到当前播放的总长度
                final int duration = mediaPlayer.getDuration();
                
                //[2]使用Timer定时器去定时获取当前进度
                final Timer timer=new Timer();
                final TimerTask task=new TimerTask() {
                    
                    @Override
                    public void run() {
                        //[3]一秒钟获取一次当前进度
                        int currentPosition = mediaPlayer.getCurrentPosition();
                        
                        //[4]拿着我们在MainActivity创建的handler发消息  消息就可以携带数据
                        Message msg=Message.obtain();
                        Bundle bundle=new Bundle();
                        bundle.putInt("duration", duration);
                        bundle.putInt("currentPosition", currentPosition);
                        msg.setData(bundle);
                        //发送一条消息  mainActivity里面的handlemessage方法就会执行
                        MainActivity.handler.sendMessage(msg);
                    }
                };
                
                //100毫秒后  每隔1秒执行一次run方法
                timer.schedule(task, 100,1000);
                
                //当歌曲执行完毕后 把timer和timertask取消
                //设置播放完成的监听
                mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                    
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        System.out.println("歌曲播放完成了");
                        
                        //把timer和timertask取消
                        timer.cancel();
                        task.cancel();
                    }
                });
                
            }
            
            //暂停音乐的方法
            public void pauseMusic(){
                //暂停音乐
                mediaPlayer.pause();
            }
            
            //继续播放音乐的方法
            public void rePlayMusic(){
                mediaPlayer.start();
            }
            
            //[1]在服务的内部定义一中间人对象(IBinder)
            private class MyBinder extends Binder implements Iservice{
                
                //调用播放音乐的方法
                @Override
                public void callPlayMusic() {
                    playMusic();
                }

                //调用暂停音乐的方法
                @Override
                public void callPauseMusic() {
                    pauseMusic();
                }
                
                //调用继续播放音乐的方法
                @Override
                public void callRePlayMusic() {
                    rePlayMusic();
                }

                //调用跳转到指定位置来放音乐的方法
                @Override
                public void callSeekTo(int position) {
                    seekTo(position);
                }
                
            }
            
        }
    [5]MainActivity:
        private Iservice iservice;//这个是我们定义的中间人对象
        private Myconn conn;
        
        public static Handler handler=new Handler(){
            public void handleMessage(android.os.Message msg) {
                //获取我们携带的数据
                Bundle data=msg.getData();
                //获取歌曲的总时长和当前进度
                int duration=data.getInt("duration");
                int currentPosition=data.getInt("currentPosition");
                
                //设置seekbar的进度
                sbar.setMax(duration);
                sbar.setProgress(currentPosition);
            };
        };
        
        private static SeekBar sbar;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            //混合方式开启服务
            //[1]先调用startService目的是可以保证服务在后台长期运行
            Intent intent=new Intent(this,MusicService.class);
            startService(intent);
            //[2]调用bindService目的是为了获取我们定义的中间人对象  就可以间接的调用服务里面的方法
            conn=new Myconn();
            bindService(intent, conn, BIND_AUTO_CREATE);
            
            //[3]找到seekbar  设置进度
            sbar = (SeekBar) findViewById(R.id.seekBar1);
            
            //[4]给seekbar设置监听事件
            sbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
                //当拖动停止的时候调用
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    iservice.callSeekTo(seekBar.getProgress());
                }
                //当开始拖动
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    
                }
                //当进度改变
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress,
                        boolean fromUser) {
                    
                }
            });
            
        }
        
        @Override
        protected void onDestroy() {
            //当Activity销毁的时候  解绑服务  目的是为了不报红色日志
            unbindService(conn);
            
            super.onDestroy();
        }
        
        //点击按钮  播放音乐
        public void click1(View v){
            //调用播放音乐的方法
            iservice.callPlayMusic();
        }
        //点击按钮  暂停音乐
        public void click2(View v){
            //调用暂停音乐的方法
            iservice.callPauseMusic();
        }
        //点击按钮  继续播放音乐
        public void click3(View v){
            //调用继续播放音乐的方法
            iservice.callRePlayMusic();
        }


        //监听服务的状态
        private class Myconn implements ServiceConnection{

            //当服务连接成功
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                //获取我们定义的中间人对象
                iservice=(Iservice) service;
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                
            }
            
        }

9.mediaplay的生命周期(播放网络音乐)
    同步和异步
    同步:一般播放本地音乐
    异步:播放网络音乐  不用开子线程  准备完成的监听mediaPlayer.setOnPreparedListener
    
    播放网络音乐:
    [1]清单文件加权限:<uses-permission android:name="android.permission.INTERNET"/>
    [2]activity_main.xml:
        <Button 
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:onClick="click"
           android:text="播放"
           />
    [3]MainActivity:
        //点击按钮  播放一个音频文件
        public void click(View v){
            //[1]初始化mediaplayer
            final MediaPlayer mediaPlayer=new MediaPlayer();
            //[2]设置要播放的资源位置  path可以是网络路径  也可以是本地路径
            try {
                mediaPlayer.setDataSource("http://192.168.1.102:8081/xpg.mp3");
                //[3]准备播放
                mediaPlayer.prepareAsync();
                
                //[3.1]设置一个准备完成的监听(准备完数据,即准备好)
                mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                    
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        // [4]开始播放
                        mediaPlayer.start();
                    }
                });
                
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            
        }
    
    
10.surfaceview介绍
    播放视频
    mediaplay 只能播放mp4格式或者3gp格式 (低版本模拟器不行,真机可以。真机的mediaplayer还可以播放avi)
    surfaceview他是一个重量级控件
    内部维护了2个线程
        A 加载数据  A负责显示
        B 负责显示  B取加载数据
    他可以直接在子线程更新ui
    
    播放网络视频:
    [1]清单文件加权限:<uses-permission android:name="android.permission.INTERNET"/>
    [2]activity_main.xml:
        <SurfaceView 
           android:id="@+id/sfv"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
    [3]MainActivity:
        private MediaPlayer mediaPlayer;
        private int currentPosition;//当前视频播放的位置

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //[0]找到控件用来显示播放视频的内容
            SurfaceView sfv=(SurfaceView) findViewById(R.id.sfv);
            
            //获取holder对象  用来维护视频播放的内容
            SurfaceHolder holder = sfv.getHolder();
            
            //[0.1]添加holder生命周期  方法
            holder.addCallback(new Callback() {
                //当surfaceview销毁
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                    System.out.println("surfaceDestroyed");
                    //停止播放视频
                    if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
                        //获取到当前播放视频的位置
                        currentPosition=mediaPlayer.getCurrentPosition();
                        mediaPlayer.stop();
                    }
                    
                }
                //这个方法执行了  说明surfaceview准备好了
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    //[1]初始化mediaplayer
                    System.out.println("surfaceCreated");
                    mediaPlayer=new MediaPlayer();
                    try {
                        //[2]设置要播放的资源位置  path可以是网络路径  也可以是本地路径  cc.MP4 aa.avi
                        mediaPlayer.setDataSource("http://192.168.1.102:8081/cc.MP4");
                        //[3]准备播放
                        mediaPlayer.prepareAsync();
                        
                        //[3.0]设置显示给sfv  surfaceholder 是用来维护视频播放的内容
                        mediaPlayer.setDisplay(holder);
                        
                        //[3.1]设置一个准备完成的监听
                        mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                            
                            @Override
                            public void onPrepared(MediaPlayer mp) {
                                //[4]开始播放
                                mediaPlayer.start();
                                
                                //[5]继续上次的位置继续播放
                                mediaPlayer.seekTo(currentPosition);
                            }
                        });
                        
                        
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width,
                        int height) {
                    
                }
            });
            

        }
    
    
    
11.VideoView控件介绍
    videoView是对surfaceView和mediaplayer的封装 (低版本模拟器不行,真机可以。真机的mediaplayer还可以播放avi)
    avi格式或者rmvb格式
    
    [1]清单文件加权限:<uses-permission android:name="android.permission.INTERNET"/>
    [2]activity_main.xml:
        <VideoView
            android:id="@+id/vv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
           />
    [3]MainActivity:
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

           //[1]找到控件
            VideoView vv=(VideoView) findViewById(R.id.vv);
            
            //[2]设置播放的路径cc.MP4
            vv.setVideoPath("http://192.168.1.102:8081/aa.avi");
            
            //[3]开始播放
            vv.start();        
        }
    
12.vitamio框架
    Vitamio只支持ARMv6+以上的CPU,如果报以上错误,说明不支持你的机器。(注意:模拟器要使用4.0以上)
    使用步骤看资料里面的总结
    解码原理:使用的是一个开源项目  ffmpeg  谷歌
    
    [1]先加vitamio框架的类库(在总结部分有)
    [2]清单文件加权限:<uses-permission android:name="android.permission.INTERNET"/>
    [3]清单文件application加:
         <!-- 一定要在清单文件初始化InitActivity  -->
         <activity android:name="io.vov.vitamio.activity.InitActivity"></activity>
    [4]activity_main.xml:
        <io.vov.vitamio.widget.VideoView
            android:id="@+id/vv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
           />
    [5]MainActivity:(import io.vov.vitamio.widget.VideoView;)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
           //插件vitamio框架检查是否可用
            if(!LibsChecker.checkVitamioLibs(this)){
                return;
            }
            
            final VideoView vv = (VideoView) findViewById(R.id.vv);
            vv.setVideoPath("http://192.168.1.102:8081/aa.avi");
            vv.setOnPreparedListener(new OnPreparedListener() {
                
                @Override
                public void onPrepared(MediaPlayer mp) {
                    vv.start();
                }
            });
            
            //设置video的控制器
            vv.setMediaController(new MediaController(this));
            
        }

13.照相机和录像
    照相
    录像
    
    [1]清单文件加权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    [2]activity_main.xml:
        <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            tools:context=".MainActivity" >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hello_world" />

            <Button
                android:onClick="click1"
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView1"
                android:layout_below="@+id/textView1"
                android:layout_marginLeft="15dp"
                android:layout_marginTop="72dp"
                android:text="照相" />

            <Button
                android:onClick="click2"
                android:id="@+id/button2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/button1"
                android:layout_below="@+id/button1"
                android:layout_marginTop="104dp"
                android:text="录像" />

        </RelativeLayout>
    [3]MainActivity:
        //点击按钮进行照相
        public void click1(View v){
            Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            File file=new File(Environment.getExternalStorageDirectory().getPath(),"haha.png");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
            // start the image capture Intent
            startActivityForResult(intent, 1);
        }

        //点击按钮进行录像
        public void click2(View v){
            Intent intent=new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
            File file=new File(Environment.getExternalStorageDirectory().getPath(),"hehe.MP4");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
             // start the image capture Intent
            startActivityForResult(intent, 2);
        }
        
        //当开启的Activity关闭的时候调用
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            System.out.println("哈哈哈哈");
            super.onActivityResult(requestCode, resultCode, data);
        }

今日总结
    [1]计算机表示图形的几种方式  
    [2]缩放加载大图片
    [3]创建原图的副本  因为原图不可以修改
    [4]画画板  设置触摸事件OnTouchListener
    [5]撕衣服小案例
    [6]多媒体api
    [7]百度音乐盒
    [8]surfaceview
    [9]videoView 对surfaceview和mediaplayer的封装
    [10]类库的概念
    [11]照相机和录像  调用系统的照相机
    
【android加类库】:工程B加类库A
    设置工程A,右键->Properties->Android,将Is library项选中,然后Apply。
    设置工程B,右键->Properties->Android,在Library中,点击Add按钮,将A工程加入,然后Apply。
    此时在B中就引入了A中的资源和代码,这些资源和代码都可以直接调用。
    需要注意的是,因为A已经不再是一个完整的Android应用,而是一个类库工程,所以有一些内容还需要在B中配置一下。
    比如A中有lib库引用,则B中也要加入该lib库,比如Alib库是appcompat_v7_10,B也要加;比如A中的AndroidManifest.xml文件的内容,在B的AndroidManifest.xml文件中也要相应加上。。。
    
    
【MediaPlayer视频异常】
    MediaPlayer   error (1, -2147483648)
    解决方法:(最后用高版本的真机,测试通过)
    其实代表MEDIA_ERROR_UNKNOWN.原因在于,MP4有多种编码格式,例如H.264,H.263等,而Android版本较低的机器只支持部分编码。
    一旦遭遇不被支持的编码格式,MediaPlayer可能就会抛出上面的错误信息。
    可以使用一些视频软件查看视频的编码格式,然后转换为普遍支持的格式。 

    

    

    
    


    
    
    
    
    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值