首页 > 代码库 > android项目 之 记事本(13) ----- 查看图片及播放录音

android项目 之 记事本(13) ----- 查看图片及播放录音

今天就来实现下查看图片及录音的功能,在编辑或者浏览记事时,点击图片,打开一个自定义Activity(当然了,也可以调用系统的图库来查看)来查看所添加的图片的原始图片,而不是缩放后的图片,同理,用自定义Activity来查看录音文件,实现播放录音的功能。上图:

        从图中也可以看出,我们首先要创建两个Activity,当然了,布局文件也是少不了的,如下:

activity_show_picture.xml

 

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"   
  6.     >  
  7.       
  8.     <ImageView   
  9.         android:id="@+id/iv_showPic"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent"  
  12.         android:scaleType="fitCenter"  
  13.         />  
  14.   
  15. </LinearLayout>  

ShowPicture.java

 

[java] view plaincopy
  1. public class ShowPicture extends Activity {  
  2.     private ImageView img;  
  3.       
  4.     @Override  
  5.     protected void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  
  8.         setContentView(R.layout.activity_show_picture);  
  9.         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add);  
  10.         //设置标题  
  11.         TextView tv_title = (TextView)findViewById(R.id.tv_title);  
  12.         tv_title.setText("查看图片");  
  13.         Button bt_back = (Button)findViewById(R.id.bt_back);  
  14.         bt_back.setOnClickListener(new OnClickListener() {  
  15.               
  16.             @Override  
  17.             public void onClick(View arg0) {  
  18.                 ShowPicture.this.finish();  
  19.             }  
  20.         });  
  21.         Button bt_del = (Button)findViewById(R.id.bt_save);  
  22.         bt_del.setBackgroundResource(R.drawable.paint_icon_delete);  
  23.           
  24.         img = (ImageView)findViewById(R.id.iv_showPic);  
  25.           
  26.         Intent intent = this.getIntent();  
  27.         String imgPath = intent.getStringExtra("imgPath");  
  28.         Bitmap bm = BitmapFactory.decodeFile(imgPath);  
  29.         img.setImageBitmap(bm);  
  30.     }  
  31. }  

      主要思想就是用ImageView来显示指定路径的图片,该路径是从前一个Activity中传入进来的。这里的监听事件,只实现了返回的功能,至于,放大缩小图片,旋转图片,下节再实现吧。activity_show_record.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"   
  5.     android:background="@drawable/bg"  
  6.     >  
  7.      <LinearLayout   
  8.             android:layout_width="match_parent"  
  9.             android:layout_height="match_parent"  
  10.             android:orientation="vertical"  
  11.             android:gravity="center"  
  12.             android:layout_centerInParent="true"  
  13.             >  
  14.           
  15.         <LinearLayout   
  16.             android:layout_width="match_parent"  
  17.             android:layout_height="wrap_content"  
  18.             android:orientation="horizontal"  
  19.             android:gravity="center"  
  20.             android:layout_margin="5dp"  
  21.             >  
  22.         <ImageView  
  23.         android:id="@+id/iv_record_wave_left"  
  24.         android:layout_width="wrap_content"  
  25.         android:layout_height="wrap_content"  
  26.         android:layout_gravity="center"  
  27.           
  28.         android:layout_margin="5dp"  
  29.         android:background="@anim/record_wave_left"  
  30.         />  
  31.         <ImageView   
  32.         android:id="@+id/iv_microphone"  
  33.         android:layout_width="wrap_content"  
  34.         android:layout_height="wrap_content"  
  35.         android:layout_gravity="center"  
  36.         android:src=http://www.mamicode.com/"@drawable/record_microphone_icon"  
  37.         android:layout_margin="5dp"  
  38.         />  
  39.          <ImageView   
  40.         android:id="@+id/iv_record_wave_right"  
  41.         android:layout_width="wrap_content"  
  42.         android:layout_height="wrap_content"  
  43.         android:layout_gravity="center"  
  44.           
  45.         android:layout_margin="5dp"  
  46.         android:background="@anim/record_wave_right"  
  47.         />    
  48.      
  49.         </LinearLayout>    
  50.            <TextView   
  51.         android:id="@+id/tv_recordTime"  
  52.         android:layout_width="match_parent"  
  53.         android:layout_height="wrap_content"  
  54.         android:textColor="#499df7"  
  55.         android:textSize="20sp"  
  56.         android:text="00:00:00"  
  57.         android:gravity="center"  
  58.         android:layout_margin="5dp"  
  59.         />   
  60.    </LinearLayout>  
  61.      
  62. </RelativeLayout>  

ShowRecord.java

 

[java] view plaincopy
  1. public class ShowRecord extends Activity {  
  2.       
  3.     private String audioPath;  
  4.     private int isPlaying = 0;  
  5.     private AnimationDrawable ad_left,ad_right;  
  6.     private Timer mTimer;  
  7.     //语音操作对象  
  8.     private MediaPlayer mPlayer = null;  
  9.     private ImageView iv_record_wave_left,iv_record_wave_right,iv_microphone;  
  10.     private TextView tv_recordTime;  
  11.     @Override  
  12.     protected void onCreate(Bundle savedInstanceState) {  
  13.         // TODO Auto-generated method stub  
  14.         super.onCreate(savedInstanceState);  
  15.         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  
  16.         setContentView(R.layout.activity_show_record);  
  17.         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add);  
  18.         //设置标题  
  19.         TextView tv_title = (TextView)findViewById(R.id.tv_title);  
  20.         tv_title.setText("查看录音");  
  21.         Button bt_back = (Button)findViewById(R.id.bt_back);  
  22.         bt_back.setOnClickListener(new OnClickListener() {  
  23.               
  24.             @Override  
  25.             public void onClick(View arg0) {  
  26.                 if(isPlaying == 1){  
  27.                     mPlayer.stop();  
  28.                     mPlayer.release();  
  29.                 }  
  30.                 ShowRecord.this.finish();  
  31.             }  
  32.         });  
  33.         Button bt_del = (Button)findViewById(R.id.bt_save);  
  34.         bt_del.setBackgroundResource(R.drawable.paint_icon_delete);  
  35.           
  36.         Intent intent = this.getIntent();  
  37.         audioPath = intent.getStringExtra("audioPath");  
  38.           
  39.         iv_microphone = (ImageView)findViewById(R.id.iv_microphone);  
  40.         iv_microphone.setOnClickListener(new ClickEvent());  
  41.           
  42.         iv_record_wave_left = (ImageView)findViewById(R.id.iv_record_wave_left);  
  43.         iv_record_wave_right = (ImageView)findViewById(R.id.iv_record_wave_right);  
  44.           
  45.         ad_left = (AnimationDrawable)iv_record_wave_left.getBackground();  
  46.         //ad_left = (AnimationDrawable)iv_record_wave_left.getDrawable();  
  47.         ad_right = (AnimationDrawable)iv_record_wave_right.getBackground();  
  48.         //ad_right = (AnimationDrawable)iv_record_wave_right.getDrawable();  
  49.         tv_recordTime = (TextView)findViewById(R.id.tv_recordTime);  
  50.     }  
  51.       
  52.     final Handler handler = new Handler(){  
  53.         public void handleMessage(Message msg) {  
  54.             switch(msg.what){  
  55.                 case 1 :  
  56.                     String time[] = tv_recordTime.getText().toString().split(":");  
  57.                     int hour = Integer.parseInt(time[0]);  
  58.                     int minute = Integer.parseInt(time[1]);  
  59.                     int second = Integer.parseInt(time[2]);  
  60.                       
  61.                     if(second < 59){  
  62.                         second++;  
  63.                           
  64.                     }  
  65.                     else if(second == 59 && minute < 59){  
  66.                         minute++;  
  67.                         second = 0;  
  68.                           
  69.                     }  
  70.                     if(second == 59 && minute == 59 && hour < 98){  
  71.                         hour++;  
  72.                         minute = 0;  
  73.                         second = 0;  
  74.                     }  
  75.                       
  76.                     time[0] = hour + "";  
  77.                     time[1] = minute + "";  
  78.                     time[2] = second + "";  
  79.                     //调整格式显示到屏幕上  
  80.                     if(second < 10)  
  81.                         time[2] = "0" + second;  
  82.                     if(minute < 10)  
  83.                         time[1] = "0" + minute;  
  84.                     if(hour < 10)  
  85.                         time[0] = "0" + hour;  
  86.                       
  87.                     //显示在TextView中  
  88.                     tv_recordTime.setText(time[0]+":"+time[1]+":"+time[2]);  
  89.                       
  90.                     break;  
  91.               
  92.             }  
  93.               
  94.         }  
  95.     };  
  96.       
  97.     class ClickEvent implements OnClickListener{  
  98.   
  99.         @Override  
  100.         public void onClick(View arg0) {  
  101.             // TODO Auto-generated method stub  
  102.                 //试听  
  103.                 if(isPlaying == 0){  
  104.                     isPlaying = 1;  
  105.                     mPlayer = new MediaPlayer();  
  106.                     tv_recordTime.setText("00:00:00");  
  107.                     mTimer = new Timer();  
  108.                     mPlayer.setOnCompletionListener(new MediaCompletion());  
  109.                     try {  
  110.                         mPlayer.setDataSource(audioPath);  
  111.                         mPlayer.prepare();  
  112.                         mPlayer.start();  
  113.                     } catch (IllegalArgumentException e) {  
  114.                         // TODO Auto-generated catch block  
  115.                         e.printStackTrace();  
  116.                     } catch (SecurityException e) {  
  117.                         // TODO Auto-generated catch block  
  118.                         e.printStackTrace();  
  119.                     } catch (IllegalStateException e) {  
  120.                         // TODO Auto-generated catch block  
  121.                         e.printStackTrace();  
  122.                     } catch (IOException e) {  
  123.                         // TODO Auto-generated catch block  
  124.                         e.printStackTrace();  
  125.                     }  
  126.                     mTimer.schedule(new TimerTask() {  
  127.                           
  128.                         @Override  
  129.                         public void run() {  
  130.                             Message message = new Message();  
  131.                             message.what = 1;  
  132.                             handler.sendMessage(message);  
  133.                         }  
  134.                     }, 1000,1000);  
  135.                     //播放动画  
  136.                     ad_left.start();  
  137.                     ad_right.start();  
  138.                 }  
  139.                 //结束试听  
  140.                 else{  
  141.                     isPlaying = 0;  
  142.                     mPlayer.stop();  
  143.                     mPlayer.release();  
  144.                     mPlayer = null;  
  145.                     mTimer.cancel();  
  146.                     mTimer = null;  
  147.                     //停止动画  
  148.                     ad_left.stop();  
  149.                     ad_right.stop();  
  150.                 }  
  151.         }  
  152.     }  
  153.   
  154.     class MediaCompletion implements OnCompletionListener{  
  155.   
  156.         @Override  
  157.         public void onCompletion(MediaPlayer mp) {  
  158.             mTimer.cancel();  
  159.             mTimer = null;  
  160.             isPlaying = 0;  
  161.             //停止动画  
  162.             ad_left.stop();  
  163.             ad_right.stop();  
  164.             Toast.makeText(ShowRecord.this, "播放完毕", Toast.LENGTH_SHORT).show();  
  165.             tv_recordTime.setText("00:00:00");  
  166.         }  
  167.     }  
  168. }  

      在查看录音时,用到了对播放时间的显示处理,以及动画的播放与停止,稍有点复杂,这些在之前“添加录音”一节就就讲述了。

    

      有了这两个Activity后,那么剩下的工作就是在单击图片或者录音的事件中启动这两个Activity即可。但这就有一个问题,如何在图文混排的EditText中的判断单击的是图片,录音,还是文字呢??这就需要从EditText中的识别那些是图片,那些是文字,再进一步对图片分析到底单击的是那一个图片,从而实现查看具体图片及录音的功能,具体如下:

1. 记录EditText中每个图片的位置及所在源路径

          为了实现在编辑和浏览时可以随时查看原图片及录音文件,所以在每次添加图片或录音后,用一个List记住新增加的每个图片或录音的位置及所在路径,当然了,如果是浏览已经存在于数据库中的记事时,在加载数据的同时,同样用ListView来记住所有的图片及录音的位置和路径。主要代码如下:

 

[java] view plaincopy
  1.         //记录editText中的图片,用于单击时判断单击的是那一个图片  
  2.     private List<Map<String,String>> imgList = new ArrayList<Map<String,String>>();  

         每次单击记事列表项,进入查看记事,在加载数据的同时将所有图片及录音的位置及路径记录下来,具体为在loadDate()方法中添加以下代码:

[java] view plaincopy
  1.         //用List记录该录音的位置及所在路径,用于单击事件  
  2.  Map<String,String> map = new HashMap<String,String>();  
  3.  map.put("location", m.start()+"-"+m.end());  
  4.  map.put("path", path);  
  5.  imgList.add(map);  

        同理,也要在每次添加图片录音后也要加入相应的代码,在InsertBitmap()函数中添加如下代码:

 

[java] view plaincopy
  1.         //用List记录该录音的位置及所在路径,用于单击事件  
  2.         Map<String,String> map = new HashMap<String,String>();  
  3.         map.put("location", selectionIndex+"-"+(selectionIndex+spannableString.length()));  
  4.         map.put("path", imgPath);  
  5.         imgList.add(map);  

2. 给EditText添加单击事件

 

[java] view plaincopy
  1. private LineEditText et_Notes;  
  2.   
  3. ... ...  
  4.   
  5. et_Notes.setOnClickListener(new TextClickEvent());  

3. 判断单击的是图片还是普通文字

          为了判断单击的是图片还是普通文字,用到了Spanned,ImageSpan,主要思想,就是判断当前单击的位置是否在图片的位置范围内,主要代码如下:

 

[html] view plaincopy
  1.                         Spanned s = et_Notes.getText();  
  2.             ImageSpan[] imageSpans;  
  3.             imageSpans = s.getSpans(0, s.length(), ImageSpan.class);  
  4.               
  5.             int selectionStart = et_Notes.getSelectionStart();  
  6.             for(ImageSpan span : imageSpans){  
  7.                   
  8.                 int start = s.getSpanStart(span);  
  9.                 int end = s.getSpanEnd(span);  
  10.                 //找到图片  
  11.                 if(selectionStart >= start && selectionStart end){  
  12.                                      ... ...   
  13.                                 }  
  14.                   
  15.             }  

           打到了图片,接下来就要判断单击的到底是那一图片呢?

4. 决断单击的具体是那一张图片

这就用到了第一步记录的图片的位置和路径了,显然,就是用位置来判断到底是单击的那一个图片,主要代码如下:

 

[java] view plaincopy
  1.         //查找当前单击的图片是哪一个图片  
  2.     //System.out.println(start+"-----------"+end);  
  3.     String path = null;  
  4.     for(int i = 0;i < imgList.size();i++){  
  5.         Map map = imgList.get(i);  
  6.         //找到了  
  7.         if(map.get("location").equals(start+"-"+end)){  
  8.             path = imgList.get(i).get("path");  
  9.             break;  
  10.         }  
  11.     }  

  5. 判断是录音还是图片,启动对应的Activity,并传递路径

            查看图片,有两种方法,一种是调用系统的图库打开图片,另一种就是自定义,这里,我都实现了,打开录音用的是自定义的Activity,如下:

 

[java] view plaincopy
  1.         //接着判断当前图片是否是录音,如果为录音,则跳转到试听录音的Activity,如果不是,则跳转到查看图片的界面  
  2.     //录音,则跳转到试听录音的Activity  
  3.     if(path.substring(path.length()-3, path.length()).equals("amr")){  
  4.         Intent intent = new Intent(AddActivity.this,ShowRecord.class);  
  5.         intent.putExtra("audioPath", path);  
  6.         startActivity(intent);  
  7.     }  
  8.     //图片,则跳转到查看图片的界面  
  9.     else{  
  10.         //有两种方法,查看图片,第一种就是直接调用系统的图库查看图片,第二种是自定义Activity  
  11.         //调用系统图库查看图片  
  12.         /*Intent intent = new Intent(Intent.ACTION_VIEW); 
  13.         File file = new File(path); 
  14.         Uri uri = Uri.fromFile(file); 
  15.         intent.setDataAndType(uri, "image/*");*/  
  16.         //使用自定义Activity  
  17.         Intent intent = new Intent(AddActivity.this,ShowPicture.class);  
  18.         intent.putExtra("imgPath", path);  
  19.         startActivity(intent);  
  20.     }  

           以上,3,4,5步其实都是在单击的监听器中实现的,完整代码如下:

 

[java] view plaincopy
  1.         //为EidtText设置监听器  
  2.     class TextClickEvent implements OnClickListener{  
  3.   
  4.         @Override  
  5.         public void onClick(View v) {  
  6.             Spanned s = et_Notes.getText();  
  7.             ImageSpan[] imageSpans;  
  8.             imageSpans = s.getSpans(0, s.length(), ImageSpan.class);  
  9.               
  10.             int selectionStart = et_Notes.getSelectionStart();  
  11.             for(ImageSpan span : imageSpans){  
  12.                   
  13.                 int start = s.getSpanStart(span);  
  14.                 int end = s.getSpanEnd(span);  
  15.                 //找到图片  
  16.                 if(selectionStart >= start && selectionStart < end){  
  17.                     //Bitmap bitmap = ((BitmapDrawable)span.getDrawable()).getBitmap();  
  18.                     //查找当前单击的图片是哪一个图片  
  19.                     //System.out.println(start+"-----------"+end);  
  20.                     String path = null;  
  21.                     for(int i = 0;i < imgList.size();i++){  
  22.                         Map map = imgList.get(i);  
  23.                         //找到了  
  24.                         if(map.get("location").equals(start+"-"+end)){  
  25.                             path = imgList.get(i).get("path");  
  26.                             break;  
  27.                         }  
  28.                     }  
  29.                     //接着判断当前图片是否是录音,如果为录音,则跳转到试听录音的Activity,如果不是,则跳转到查看图片的界面  
  30.                     //录音,则跳转到试听录音的Activity  
  31.                     if(path.substring(path.length()-3, path.length()).equals("amr")){  
  32.                         Intent intent = new Intent(AddActivity.this,ShowRecord.class);  
  33.                         intent.putExtra("audioPath", path);  
  34.                         startActivity(intent);  
  35.                     }  
  36.                     //图片,则跳转到查看图片的界面  
  37.                     else{  
  38.                         //有两种方法,查看图片,第一种就是直接调用系统的图库查看图片,第二种是自定义Activity  
  39.                         //调用系统图库查看图片  
  40.                         /*Intent intent = new Intent(Intent.ACTION_VIEW); 
  41.                         File file = new File(path); 
  42.                         Uri uri = Uri.fromFile(file); 
  43.                         intent.setDataAndType(uri, "image/*");*/  
  44.                         //使用自定义Activity  
  45.                         Intent intent = new Intent(AddActivity.this,ShowPicture.class);  
  46.                         intent.putExtra("imgPath", path);  
  47.                         startActivity(intent);  
  48.                     }  
  49.                 }  
  50.                 else  
  51.                     //如果单击的是空白出或文字,则获得焦点,即打开软键盘   
  52.                     imm.showSoftInput(et_Notes, 0);  
  53.             }  
  54.         }  
  55.     }  

        

          至此,就实现了查看图片以及播放录音的功能。

 

android项目 之 记事本(13) ----- 查看图片及播放录音